program CreamPlay; {$APPTYPE CONSOLE} uses Windows, MMSystem, CreamTrackerEngine in '..\CreamTrackerEngine.pas', TRILinker in '..\Aulan\TRILinker.pas'; const SampleRate=44100; SynthBufferSize=2048; type PSynthEndBuffer=^TSynthEndBuffer; TSynthEndBuffer=array[0..SynthBufferSize-1,0..1] of single; var Buffers:array[0..3] of TSynthEndBuffer; var WaveOutHandle:longword; BufferCounter:longword; {$define sound16bit} {$ifdef sound16bit} const WaveFormat:TWaveFormatEx=(wFormatTag:1;nChannels:2;nSamplesPerSec:SampleRate; nAvgBytesPerSec:SampleRate*2*sizeof(smallint); nBlockAlign:sizeof(smallint)*2; wBitsPerSample:sizeof(smallint)*8;cbSize:0); WaveHandler:array[0..3] of TWAVEHDR=((lpData:@Buffers[0]; dwBufferLength:sizeof(TSynthEndBuffer) div 2; dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[1]; dwBufferLength:sizeof(TSynthEndBuffer) div 2; dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[2]; dwBufferLength:sizeof(TSynthEndBuffer) div 2; dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[3]; dwBufferLength:sizeof(TSynthEndBuffer) div 2; dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0)); function SoftTRUNC(FloatValue:single):integer; type plongword=^longword; const MaskMantissa=(1 shl 23)-1; var Exponent,Mantissa,Sig,SigExtra,Signed,IsDenormalized:longword; value,Shift:integer; begin Exponent:=(plongword(@FloatValue)^ and $7ffffffF) shr 23; Mantissa:=plongword(@FloatValue)^ and MaskMantissa; Shift:=Exponent-$96; Sig:=Mantissa or $00800000; SigExtra:=Sig shl (Shift and 31); IsDenormalized:=0-ord(0<=Shift); Value:=(((-ord(Exponent>=$7E)) and (Sig shr (32-Shift))) and not IsDenormalized) or (SigExtra and IsDenormalized); Signed:=0-ord((plongword(@FloatValue)^ and $80000000)<>0); result:=(((0-Value) and Signed) or (Value and not Signed)) and (0-ord($9E>Exponent)); end; {$else} const WaveFormat:TWaveFormatEx=(wFormatTag:3;nChannels:2;nSamplesPerSec:SampleRate; nAvgBytesPerSec:SampleRate*2*sizeof(single); nBlockAlign:sizeof(single)*2; wBitsPerSample:sizeof(single)*8;cbSize:0); WaveHandler:array[0..3] of TWAVEHDR=((lpData:@Buffers[0]; dwBufferLength:sizeof(TSynthEndBuffer); dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[1]; dwBufferLength:sizeof(TSynthEndBuffer); dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[2]; dwBufferLength:sizeof(TSynthEndBuffer); dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0), (lpData:@Buffers[3]; dwBufferLength:sizeof(TSynthEndBuffer); dwBytesRecorded:0; dwUser:0; dwFlags:WHDR_DONE; dwLoops:0)); {$endif} var Instance:TCreamTrackerInstance; FileHandle:THandle; Data:pointer; DataSize,DataRead:longword; sis:^smallint; sfs:^single; i:longint; begin Data:=nil; DataSize:=0; //FileHandle:=CreateFileA('test12.s3m',GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if ParamCount>0 then begin FileHandle:=CreateFileA(PAnsiChar(ParamStr(1)),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if FileHandle<>0 then begin DataSize:=SetFilePointer(FileHandle,0,nil,FILE_END); if SetFilePointer(FileHandle,0,nil,FILE_BEGIN)=0 then begin GetMem(Data,DataSize); if not ReadFile(FileHandle,Data^,DataSize,DataRead,nil) then begin FreeMem(Data); Data:=nil; end; end; CloseHandle(FileHandle); end; if assigned(Data) then begin CreamTrackerCreate(Instance,SampleRate); if CreamTrackerLoad(Instance,Data,DataSize) then begin CreamTrackerReset(Instance); Instance.Playing:=true; Instance.RepeatCounter:=0; waveOutOpen(@WaveOutHandle,WAVE_MAPPER,@WaveFormat,0,0,0); BufferCounter:=0; while not Instance.TrackEnd do begin if (WaveHandler[BufferCounter].dwFlags and WHDR_DONE)<>0 then begin if waveOutUnprepareHeader(WaveOutHandle,@WaveHandler[BufferCounter],sizeof(TWAVEHDR))<>WAVERR_STILLPLAYING then begin WaveHandler[BufferCounter].dwFlags:=WaveHandler[BufferCounter].dwFlags and not WHDR_DONE; CreamTrackerFillBuffer(Instance,psingle(WaveHandler[BufferCounter].lpData),SynthBufferSize); {$ifdef sound16bit} sis:=pointer(WaveHandler[BufferCounter].lpData); sfs:=pointer(WaveHandler[BufferCounter].lpData); for i:=0 to (SynthBufferSize*2)-1 do begin if sfs^<-1.0 then begin sfs^:=-1.0; end else if sfs^>1.0 then begin sfs^:=1.0; end; sis^:=round(sfs^*32767); inc(sis); inc(sfs); end; {$endif} waveOutPrepareHeader(WaveOutHandle,@WaveHandler[BufferCounter],sizeof(TWAVEHDR)); waveOutWrite(WaveOutHandle,@WaveHandler[BufferCounter],sizeof(TWAVEHDR)); BufferCounter:=(BufferCounter+1) and 3; end; end else begin Sleep(1); end; end; waveOutReset(WaveOutHandle); waveOutClose(WaveOutHandle); end; {$ifndef CreamTrackerMinimalPlayer} CreamTrackerDestroy(Instance); FreeMem(Data); {$endif} end; end; end.