#	Makefile.MSVC: MSVC Makefile for LAME 
#
#	2000-11-21 Robert Hegemann
#	dedicated to the LAME project http://www.mp3dev.org
###############################################################################



#__ readme ____________________________________________________________________
#	nmake -f Makefile.MSVC
#		-> build lame and dll, but not mp3x
#		-> use Robert's code modifications
#		-> assume INTEL compiler available  
#		-> assume NASM available
#		-> assemble MMX code with NASM
#		-> optimize for PIII
#		-> single file optimizations
#		-> no compiler warnings
#
#	passing arguments, one can modify the default behaviour:
#	COMP=<not INTEL or BCC>    ->  use MS compiler
#	WARN=<anything but OFF>    ->  give verbose compiler warnings
#	ASM=<anything but YES>     ->  no NASM nor MMX
#	MMX=<anything but YES>     ->  do not assemble MMX code
#	CFG=<anything but RH>      ->  disable Robert's modifications
#	CPU=P1                     ->  optimize for Pentium instead of P II/III
#	CPU=P2                     ->  optimize for Pentium II/III, you need a PII or better
#	CPU=P3                     ->  optimize for Pentium III, you need a PIII or better
#	GTK=YES                    ->  have GTK, adds mp3x to default targets
#	PREC=SLOPPY                ->  use single float instead of double
#
#	Example:
#	nmake -f Makefile.MSVC CPU=P1 GTK=YES
#____________________________________________________________________ readme __



#	targets <-> DOS filenames

T_LAME = lame.exe
T_LDLL = lame_enc.dll
T_MP3X = mp3x.exe

#	default targets

PGM = $(T_LDLL) $(T_LAME)

#	some default settings

!	IF "$(MSVCVER)" != ""
COMP = MS
!	IF "$(MSVCVER)" == "Win64"
!	IF "$(ASM)" == ""
ASM = NO # or it could be ML64 if we want to use it...
GTK = NO
!	ENDIF
!	ENDIF
!	ELSE
!	IF "$(COMP)" == ""
COMP = INTEL
!	ENDIF
!	ENDIF

!	IF "$(ASM)" == ""
ASM = YES
!	ENDIF

!	IF "$(MMX)" == ""
MMX = YES
!	ENDIF

!	IF "$(CFG)" == "NO-ALTERNATE-CODE-AVAILABLE"
CFG = RH
!	ENDIF

!	IF "$(CPU)" == ""
CPU = P2auto
!	ENDIF

!	IF "$(WARN)" == ""
WARN = OFF
!	ENDIF

!	IF "$(PREC)" == ""
PREC = DOUBLE
!	ENDIF


OFF = win32

!	MESSAGE ----------------------------------------------------------------------
!	IF "$(CFG)" == ""
!	 MESSAGE building LAME
!	ELSE
!	 MESSAGE building LAME featuring $(CFG)
!	ENDIF
!	IF "$(ASM)" == "YES"
!	 MESSAGE + ASM
!	 IF "$(MMX)" == "YES"
!	  MESSAGE + MMX
!	 ENDIF 
!	ENDIF 
!	IF "$(GTK)" == "YES"
!	 MESSAGE + GTK
!	ENDIF 
!	IF "$(COMP)" == "INTEL"
!	 MESSAGE using INTEL COMPILER
!	 IF "$(CPU)" == "P1"
!	  MESSAGE + optimizing for Pentium (MMX)
!	 ELSE
!	  IF "$(CPU)" == "P2"
!	   MESSAGE + you need a Pentium II or better
!	  ELSE
!	   IF "$(CPU)" == "P3"
!	    MESSAGE + you need a Pentium III or better
!	   ELSE
!	    MESSAGE + optimizing for Pentium II/III
!	   ENDIF
!	  ENDIF
!	 ENDIF
!	ELSE
!	 IF "$(MSVCVER)" == "6.0"
!	  MESSAGE + using MSVC 6.0 32-Bit Compiler
!	  IF "$(CPU)" == "P1"
!	   MESSAGE + optimizing for Pentium (MMX) (may slow down PIII a few percent)
!	  ELSE
!	   MESSAGE + optimizing for Pentium II/III
!	  ENDIF
!	 ELSEIF "$(MSVCVER)" == "8.0"
!	  MESSAGE + using MSVC 8.0 32-Bit Compiler
!	  IF "$(CPU)" == "P1"
!	   MESSAGE + optimizing for Pentium (MMX) (may slow down PIII a few percent)
!	  ELSE
!	   MESSAGE + optimizing for Pentium II/III
!	  ENDIF
!	 ELSE
!	  IF "$(MSVCVER)" == "Win64"
!	   MESSAGE + using MS 64-Bit Compiler
!	  ELSE
!	   MESSAGE using MS COMPILER
!	   IF "$(CPU)" == "P1"
!	    MESSAGE + optimizing for Pentium (MMX) (may slow down PIII a few percent)
!	   ELSE
!	    MESSAGE + optimizing for Pentium II/III
!	   ENDIF
!	  ENDIF
!	 ENDIF
!	ENDIF
!	IF "$(PREC)" == "SINGLE"
!	 MESSAGE + using Single precision
!	ENDIF
!	MESSAGE ----------------------------------------------------------------------

!	IF "$(COMP)" != "INTEL"
!	IF "$(COMP)" != "BCC"

#__ Microsoft C options _______________________________________________________
#
#	/O2     maximize speed
#	/Ob<n>  inline expansion
#	/Og     enable global optimizations
#	/Oi     enable intrinsic functions
#	/Ot     favor code speed
#	/Oy     enable frame pointer omission
#	/G5     Pentium optimization
#	/G6     Pentium II/III optimization
#	/GA     optimize for Windows Application
#	/GF     enable read-only string pooling
#	/Gf     enable string spooling
#	/Gs     disable stack checking calls
#	/Gy     separate functions for linker
#	/QIfdiv generate code for Pentium FDIV fix
#	/QI0f   generate code for Pentium 0x0f erratum fix
#
#	remarks: 
#	 - aliasing options seem to break code
#	 - try to get the Intel compiler demonstration code!
#	   ICL produces faster code.

# debugging options
# CC_OPTS = /nologo /Zi /Ge /GZ
# LN_OPTS = /nologo /debug:full /debugtype:cv /fixed:no

# profiling options
# CC_OPTS = /nologo /Zi /O2b2gity /G6As /DNDEBUG 
# LN_OPTS = /nologo /debug:full /debugtype:cv /fixed:no /profile

# release options
!	IF "$(MSVCVER)" == "Win64"
CC_OPTS = /nologo /DWin64 /O2b2ity /GAy /Gs1024 /Zp8 /GL /GS- /Zi
!	ELSEIF "$(MSVCVER)" == "8.0"
CC_OPTS = /nologo /DNDEBUG /O2 /Ob2 /GAy /Gs1024 /Zp8 /GL /Zi
!	ELSE
CC_OPTS = /nologo /DNDEBUG /O2 /Ob2 /GAy /Gs1024 /QIfdiv /QI0f /YX
!	ENDIF

!	IF "$(NODEBUG)" == "1"
CC_OPTS = $(CC_OPTS) /DNDEBUG
!	ENDIF

!	IF "$(MSVCVER)" == "6.0"
!	IF "$(CPU)" == "P1"
CC_OPTS = $(CC_OPTS) /G5
!	ELSE
CC_OPTS = $(CC_OPTS) /G6
!	ENDIF
!	ENDIF

!	IF "$(WARN)" == "OFF"
CC_OPTS = $(CC_OPTS) /w
!	ELSE
CC_OPTS = $(CC_OPTS) /W$(WARN)
!	ENDIF

!	IF "$(PREC)" == "SINGLE"
CC_OPTS = $(CC_OPTS) /DFLOAT8=float /DREAL_IS_FLOAT=1
!	ENDIF

CC_OUT = /Fo

!	IF "$(MSVCVER)" == "Win64"
!	IF "$(NODEBUG)" == "1"
LN_OPTS = /nologo /map:lame.map
LN_DLL = /DLL
LN_OUT = /OUT:
!	ELSE
LN_OPTS = /nologo /DEBUG /pdb:lame.pdb /map:lame.map 
LN_DLL = /DLL /DEBUG
LN_OUT = /OUT:
!	ENDIF
!	ELSEIF "$(MSVCVER)" == "8.0"
!	IF "$(NODEBUG)" == "1"
LN_OPTS = /nologo /map:lame.map 
LN_DLL = /DLL
LN_OUT = /OUT:
!	ELSE
LN_OPTS = /nologo /DEBUG /pdb:lame.pdb /map:lame.map 
LN_DLL = /DLL /DEBUG
LN_OUT = /OUT:
!	ENDIF
!	ELSE
!	IF "$(NODEBUG)" == "1"
LN_OPTS = /nologo /map:lame.map
LN_DLL = /DLL
LN_OUT = /OUT:
!	ELSE
LN_OPTS = /nologo
LN_DLL = /DLL /DEBUG /pdb:lame.pdb /map:lame.map 
LN_OUT = /OUT:
!	ENDIF
!	ENDIF

!	IF "$(MSVCVER)" == "Win64"
CC = cl
LN = link
!	ELSE
CC = cl
LN = link
!	ENDIF
#_______________________________________________________ Microsoft C options __


!	ELSE

#__ Borland BCC options _______________________________________________________
#
#	first draft, DLL not working, generates very slow code!
BCCINST = C:/Borland/BCC55

CC_OPTS = -pc -q -ff -fp -jb -j1 -tWC -tWM -O2 -OS -I$(BCCINST)/include -DNDEBUG -DWIN32
# dll >> -tWD
LN_OPTS = -lGn -lGi -lap -lx -L$(BCCINST)/lib
# dll >> -Tpd
!	IF "$(CPU)" == "P1"
CC_OPTS = $(CC_OPTS) -5
!	ELSE
CC_OPTS = $(CC_OPTS) -6
!	ENDIF

!	IF "$(WARN)" == "OFF"
CC_OPTS = $(CC_OPTS) -w-
!	ELSE
CC_OPTS = $(CC_OPTS) 
!	ENDIF

LN_DLL = 
#$(CCINST)/lib/cw32R.lib
LN_OUT = -e
CC_OUT = -o

CC = bcc32
LN = bcc32

OFF = obj
PGM = $(T_LAME)

!	ENDIF
#_______________________________________________________ Borland BCC options __


!	ELSE

#__ Intel 4.5 options _________________________________________________________
#
#	/YX         enable automatic precompiled header file creation/usage
#	/Ox         maximum optimization same as /O2 without /Gfy
#	/O2         same as /Gfsy /Ob1gyti
#	/Gd      1) make cdecl the default calling convention
#	/G5      2) optimized for Pentium
#	/G6      3) optimized for Pentium II/III
#	/GA         assume single threaded
#	/Gs[n]      disable stack checks for functions with <n bytes of locals
#	/GF         read-only string pooling optimization
#	/Gy         separate functions for the linker 
#	/Qunroll    unroll loops with default heuristic
#	/QIfist     enable fast float to int conversion
#	/QIfdiv     enable patch for Pentium with FDIV erratum
#	/QI0f       enable patch for Pentium with 0f erratum
#	/Qip     2) enable single-file IP optimizations (within files)
#	/Qipo       enable multi-file IP optimizations (between files)
#	/Qipo_wp 4) enable entire program multi-file IP optimizations
#	/QaxiMK     automatic use of specialized code for PII/III, MMX, SIMD
#
#	remarks: 
#	1) slows speed down, not using
#	2) faster compared to 3) or 4) on Pentium MMX at 200 MHz

!	IF "$(CPU)" == "P1"
CC_OPTS = /G5 /QaxiMK /QIfdiv /QI0f
!	ELSE
!	IF "$(CPU)" == "P2"
CC_OPTS = /G6 /Qxi /QaxMK
!	ELSE
!	IF "$(CPU)" == "P3"
CC_OPTS = /G6 /QxiMK
!	ELSE
CC_OPTS = /G6 /QaxiMK /QIfdiv /QI0f
!	ENDIF
!	ENDIF
!	ENDIF

!	IF "$(WARN)" == "OFF"
CC_OPTS = $(CC_OPTS) /w
!	ELSE
CC_OPTS = $(CC_OPTS) /W2 /Wport
!	ENDIF

!	IF "$(PREC)" == "SINGLE"
CC_OPTS = $(CC_OPTS) /DFLOAT8=float /DREAL_IS_FLOAT=1
!	ENDIF

CC_OPTS = /nologo /DNDEBUG /YX /GA /Ox /Ob2 \
          /Qunroll /Qsox- /Qip $(CC_OPTS)


LN_OPTS = $(CC_OPTS)
LN_DLL = /LD
LN_OUT = /Fe
CC_OUT = /Fo

CC = icl
LN = icl
#_________________________________________________________ Intel 4.5 options __

!	ENDIF



#-- MISC --
SNDLIB = /DLAMESNDFILE
LIBSNDFILE =

BRHIST_SWITCH = /DBRHIST
TIMER_SWITCH =

CPP_OPTS = /DHAVE_CONFIG_H -I.



#__ FRAME ANALYZER SUPPORT ____________________________________________________
#
#	Assuming you have "glib-dev" and "gtk+-dev" installed and the system
#	DLLs "glib-1.3.dll", "gdk-1.3.dll" and "gtk-1.3.dll" copied into the
#	"Win\System" folder
#
#	To compile in the frame analyzer support, you need the above mentioned
#	libraries. You can pass the appropriate path to them in GTK_DIRS.
#
!	IF "$(GTK)" == "YES"
!	IF "$(GTK_DIRS)" == ""
GTK_DIRS = ../src
!	ENDIF
GTK_OPTS = -I$(GTK_DIRS)/glib     \
           -I$(GTK_DIRS)/gtk+     \
           -I$(GTK_DIRS)/gtk+/gtk \
           -I$(GTK_DIRS)/gtk+/gdk
GTK_LIBS = $(GTK_DIRS)/gtk+/gtk/gtk-1.3.lib \
           $(GTK_DIRS)/gtk+/gdk/gdk-1.3.lib \
           $(GTK_DIRS)/glib/glib-1.3.lib

PGM = $(T_MP3X) $(PGM)
!	ELSE
!	IF "$(GTK)" == ""
!	MESSAGE Pass GTK=YES to build the frame analyzer. (requires installed GTK)
!	ENDIF
!	ENDIF
#____________________________________________________ FRAME ANALYZER SUPPORT __



#__ MPG123 DECODING ___________________________________________________________
#
#	uncomment the following if you want decoding support
#	It's always a good idea to compile it in!
#
CPP_OPTS = $(CPP_OPTS) /DHAVE_MPGLIB /DUSE_LAYER_1 /DUSE_LAYER_2
#___________________________________________________________ MPG123 DECODING __



#__ Takehiro's IEEE hack ______________________________________________________
#
#	uncomment the following to enable Takehiro's IEEE hack
#	You'll want it on a x86 machine with i387 FPU
#
CPP_OPTS = $(CPP_OPTS) /DTAKEHIRO_IEEE754_HACK
#______________________________________________________ Takehiro's IEEE hack __



#__ Robert's alternate code ___________________________________________________
!	IF "$(CFG)" == "RH"
CPP_OPTS = $(CPP_OPTS) 
!MESSAGE there is currently no alternate code by RH
!	ENDIF
#___________________________________________________ Robert's alternate code __



CC_SWITCHES = $(CC_OPTS) $(SNDLIB) $(BRHIST_SWITCH) \
              $(TIMER_SWITCH) $(GTK_OPTS) /DBS_FORMAT=BINARY

LN_SWITCHES = $(LN_OPTS)

lame_sources = \
	frontend/main.c

mpx_sources = \
	frontend/gpkplotting.c \
	frontend/gtkanal.c \
	frontend/mp3x.c

dll_sources = \
	dll/BladeMP3EncDll.c

common_sources = \
	frontend/portableio.c \
	frontend/get_audio.c \
	frontend/parse.c \
	frontend/timestatus.c \
	frontend/lametime.c \
	frontend/brhist.c

lamelib_sources = \
	libmp3lame/bitstream.c \
	libmp3lame/encoder.c \
	libmp3lame/fft.c \
	libmp3lame/gain_analysis.c \
	libmp3lame/id3tag.c \
	libmp3lame/lame.c \
	libmp3lame/newmdct.c \
	libmp3lame/psymodel.c \
	libmp3lame/quantize.c \
	libmp3lame/quantize_pvt.c \
	libmp3lame/set_get.c \
	libmp3lame/vbrquantize.c \
	libmp3lame/reservoir.c \
	libmp3lame/tables.c \
	libmp3lame/takehiro.c \
	libmp3lame/util.c \
	libmp3lame/mpglib_interface.c \
	libmp3lame/VbrTag.c \
	libmp3lame/presets.c \
	libmp3lame/version.c

mpglib_sources = \
	mpglib/common.c \
	mpglib/dct64_i386.c \
	mpglib/decode_i386.c \
	mpglib/layer1.c \
	mpglib/layer2.c \
	mpglib/layer3.c \
	mpglib/tabinit.c \
	mpglib/interface.c


!IF "$(MSVCVER)" == "Win64"
ADDL_OBJ = bufferoverflowU.lib
!ENDIF

LIB_OBJ = $(lamelib_sources:.c=.obj)
MPG_OBJ = $(mpglib_sources:.c=.obj)
CMMN_OBJ = $(common_sources:.c=.obj)
LAME_OBJ = $(lame_sources:.c=.obj)
MPX_OBJ = $(mpx_sources:.c=.obj)
DLL_OBJ = $(dll_sources:.c=.obj)


.c.obj: 
	@$(CC) $(CPP_OPTS) $(CC_SWITCHES) -Iinclude -Ilibmp3lame -Impglib \
	       $(CC_OUT)$@  -c $<


#__ MASM ______________________________________________________________________
#
#	MASM: Microsoft Assembler
#
!	IF "$(ASM)" == "ML64"
#
.SUFFIXES : .nas
.nas.obj:
	@echo $< 
	@ml64 -Ilibmp3lame\i386 -Sf -DWIN32 -DWIN64 $< -Fo$@
                                
CC_SWITCHES = $(CC_SWITCHES) -DHAVE_NASM
ASM_OBJ = $(ASM_OBJ) libmp3lame\i386\cpu_feat.obj

ASM_OBJ = $(ASM_OBJ) libmp3lame\i386\fft3dn.obj

#	not yet coded
#CC_SWITCHES = $(CC_SWITCHES) -DUSE_FFTSSE
#ASM_OBJ = $(ASM_OBJ) libmp3lame\i386\fftsse.obj

#CC_SWITCHES = $(CC_SWITCHES) -DUSE_FFTFPU
#ASM_OBJ = $(ASM_OBJ) libmp3lame\i386\fftfpu.obj
#______________________________________________________________________ MASM __


#__ NASM ______________________________________________________________________
#
#	NASM: Netwide Assembler
#
!	ELSEIF "$(ASM)" == "YES"
#
.SUFFIXES : .nas
.nas.obj:
	@echo $< 
	@nasmw -f $(OFF) -i libmp3lame/i386/ -DWIN32 $< -o $@
                                
CC_SWITCHES = $(CC_SWITCHES) /DHAVE_NASM
ASM_OBJ = $(ASM_OBJ) libmp3lame/i386/cpu_feat.obj


ASM_OBJ = $(ASM_OBJ) libmp3lame/i386/fft3dn.obj

#	not yet coded
#CC_SWITCHES = $(CC_SWITCHES) /DUSE_FFTSSE
#ASM_OBJ = $(ASM_OBJ) libmp3lame/i386/fftsse.obj

#CC_SWITCHES = $(CC_SWITCHES) /DUSE_FFTFPU
#ASM_OBJ = $(ASM_OBJ) libmp3lame/i386/fftfpu.obj
#______________________________________________________________________ NASM __

!	ELSE
!	MESSAGE Pass ASM=YES to build the assembler optimizations
!	ENDIF


#__ MMX _______________________________________________________________________
#
#	you need NASM but *not necessarily* a processor with MMX
#	The above CPU feature detection code allows to run the same
#	binary on a CPU without MMX too!
#
!	IF "$(ASM)" == "YES"
!	IF "$(MMX)" == "YES"
CC_SWITCHES = $(CC_SWITCHES) /DMMX_choose_table
ASM_OBJ = $(ASM_OBJ) libmp3lame/i386/choose_table.obj
!	ENDIF
!	ENDIF
#_______________________________________________________________________ MMX __

!	MESSAGE



all :	$(PGM)
	@echo.
	@echo --=*  $(PGM) uptodate  *=--
	@echo.

common:	$(CMMN_OBJ)
	@echo.
	@echo --- COMMON FRONTEND STUFF UPTODATE ---
	@echo.

libA:	$(LIB_OBJ)
	@echo.
	@echo --- LAME MP3 ENCODING LIBRARY UPTODATE ---
	@echo.

libB:	$(MPG_OBJ)
	@echo.
	@echo --- MPG123 DECODING LIBRARY UPTODATE ---
	@echo.

lib: $(ASM_OBJ) libA libB

$(T_LAME) : config.h lib common $(LAME_OBJ)
	@$(LN) $(LN_OUT)$@ $(LN_SWITCHES) $(LIBSNDFILE) \
	       $(ASM_OBJ) $(LIB_OBJ) $(MPG_OBJ) $(CMMN_OBJ) $(LAME_OBJ) $(ADDL_OBJ)
	@echo.
	@echo --=*  $@ ready  *=--
	@echo.

$(T_MP3X) : config.h lib common $(MPX_OBJ)
	@$(LN) $(LN_OUT)$@ $(LN_SWITCHES) $(GTK_LIBS) $(LIBSNDFILE) \
	       $(ASM_OBJ) $(LIB_OBJ) $(MPG_OBJ) $(CMMN_OBJ) $(MPX_OBJ) $(ADDL_OBJ)
	@echo.
	@echo --=*  $@ ready  *=--
	@echo.

$(T_LDLL) : config.h lib $(DLL_OBJ)
	@$(LN) $(LN_OUT)$@ $(LN_SWITCHES) $(LN_DLL) $(LIBSNDFILE) \
	       $(ASM_OBJ) $(LIB_OBJ) $(MPG_OBJ) $(DLL_OBJ) $(ADDL_OBJ)
	@echo.
	@echo --=*  $@ ready  *=--
	@echo.

config.h : configMS.h
	@-copy configMS.h config.h

clean:
	@-del lame.exe
	@-del lame.pdb
	@-del icl.pch
	@-del lame_enc.*
	@-del frontend\*.obj
	@-del dll\*.obj
	@-del mpglib\*.obj
	@-del libmp3lame\*.obj
	@-del libmp3lame\i386\*.obj


rebuild: clean all


lame	:	$(T_LAME)
dll 	:	$(T_LDLL)
mp3x	:	$(T_MP3X)

