diff options
Diffstat (limited to '')
-rw-r--r-- | Game/Code/Classes/UAudio_FFMpeg.pas | 634 | ||||
-rw-r--r-- | Game/Code/Classes/UAudio_bass.pas (renamed from Game/Code/Classes/UMusic_BASS.pas) | 226 | ||||
-rw-r--r-- | Game/Code/Classes/UMusic.pas | 87 | ||||
-rw-r--r-- | Game/Code/UltraStar.dpr | 11 |
4 files changed, 788 insertions, 170 deletions
diff --git a/Game/Code/Classes/UAudio_FFMpeg.pas b/Game/Code/Classes/UAudio_FFMpeg.pas new file mode 100644 index 00000000..2a3c5cb5 --- /dev/null +++ b/Game/Code/Classes/UAudio_FFMpeg.pas @@ -0,0 +1,634 @@ +unit UAudio_FFMpeg; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + + +uses Classes, + {$IFDEF win32} + windows, + {$ENDIF} + Messages, + SysUtils, + {$IFNDEF FPC} + Forms, + {$ENDIF} + + bass, + ULog, + UMusic; + +implementation + +uses + {$IFDEF FPC} + lclintf, + {$ENDIF} + URecord, + UIni, + UMain, + UThemes; + +const + RecordSystem = 1; + +type + TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, + mpPaused, mpOpen); + +const + ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); + +type + TAudio_ffMpeg = class( TInterfacedObject, IAudioPlayback ) + private + BassStart: hStream; // Wait, I've replaced this with BASS + BassBack: hStream; // It has almost all features we need + BassSwoosh: hStream; + BassChange: hStream; // Almost? It aleady has them all :) + BassOption: hStream; + BassClick: hStream; + BassDrum: hStream; + BassHihat: hStream; + BassClap: hStream; + BassShuffle: hStream; + + //Custom Sounds + CustomSounds: array of TCustomSoundEntry; + Loaded: boolean; + Loop: boolean; + fHWND: THandle; + + public + Bass: hStream; + function GetName: String; + procedure InitializePlayback; + procedure InitializeRecord; + procedure SetVolume(Volume: integer); + procedure SetMusicVolume(Volume: integer); + procedure SetLoop(Enabled: boolean); + function Open(Name: string): boolean; // true if succeed + procedure Rewind; + procedure MoveTo(Time: real); + procedure Play; + procedure Pause; //Pause Mod + procedure Stop; + procedure Close; + function Finished: boolean; + function Length: real; + function Position: real; + procedure PlayStart; + procedure PlayBack; + procedure PlaySwoosh; + procedure PlayChange; + procedure PlayOption; + procedure PlayClick; + procedure PlayDrum; + procedure PlayHihat; + procedure PlayClap; + procedure PlayShuffle; + procedure StopShuffle; + procedure CaptureStart; + procedure CaptureStop; + procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); + procedure StopCard(Card: byte); + function LoadSoundFromFile(var hStream: hStream; Name: string): boolean; + + //Equalizer + function GetFFTData: TFFTData; + + //Custom Sounds + function LoadCustomSound(const Filename: String): Cardinal; + procedure PlayCustomSound(const Index: Cardinal ); +end; + +var + singleton_MusicFFMpeg : IAudioPlayback; + +function TAudio_ffMpeg.GetName: String; +begin + result := 'FFMpeg';
+end; + +procedure TAudio_ffMpeg.InitializePlayback; +var + Pet: integer; + S: integer; +begin + Log.BenchmarkStart(4); + Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); + + Loaded := false; + Loop := false; + + {$ifdef win32} + // TODO : JB_Linux ... is this needed ? :) + fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function + {$ENDIF} + + // TODO : jb_linux replace with something other than bass + if not BASS_Init(1, 44100, 0, fHWND, nil) then + begin + {$IFNDEF FPC} + // TODO : JB_linux find a way to do this nice.. + Application.MessageBox ('Could not initialize BASS', 'Error'); + {$ENDIF} + Exit; + end; + + Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); + + // config playing buffer +// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); +// BASS_SetConfig(BASS_CONFIG_BUFFER, 100); + + Log.LogStatus('Loading Sounds', 'Music Initialize'); + + Log.BenchmarkStart(4); + LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3'); + LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3'); + LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3'); + LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3'); + LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3'); + LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3'); + +// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3'); +// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3'); +// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3'); + +// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3'); + + Log.BenchmarkEnd(4); + Log.LogBenchmark('--> Loading Sounds', 4); +end; + +procedure TAudio_ffMpeg.InitializeRecord; +var + S: integer; + device: integer; + descr: string; + input: integer; + input2: integer; + flags: integer; + mic: array[0..15] of integer; + SC: integer; // soundcard + SCI: integer; // soundcard input +begin + if RecordSystem = 1 then begin + SetLength(Sound, 6 {max players});//Ini.Players+1); + for S := 0 to High(Sound) do begin //Ini.Players do begin + Sound[S] := TSound.Create; + Sound[S].Num := S; + Sound[S].BufferNew := TMemoryStream.Create; + SetLength(Sound[S].BufferLong, 1); + Sound[S].BufferLong[0] := TMemoryStream.Create; + Sound[S].n := 4*1024; + end; + + + // check for recording devices; + {device := 0; + descr := BASS_RecordGetDeviceDescription(device); + + SetLength(SoundCard, 0); + while (descr <> '') do begin + SC := High(SoundCard) + 1; + SetLength(SoundCard, SC+1); + + Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr); + SoundCard[SC].Description := Descr; + + // check for recording inputs + mic[device] := -1; // default to no change + input := 0; + BASS_RecordInit(device); + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + flags := BASS_RecordGetInput(input); + + SetLength(SoundCard[SC].Input, 0); + while (flags <> -1) do begin + SCI := High(SoundCard[SC].Input) + 1; + SetLength(SoundCard[SC].Input, SCI+1); + + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input); + + if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin + mic[device] := input; // auto set microphone + end; + Inc(Input); + flags := BASS_RecordGetInput(input); + end; + + if mic[device] <> -1 then begin + Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device])) + end else begin + Log.LogAnalyze('Mic not found'); + mic[device] := 0; // setting to the first one (for kxproject) + end; + SoundCard[SC].InputSeleceted := Mic[Device]; + + + BASS_RecordFree; + + inc(Device); + descr := BASS_RecordGetDeviceDescription(Device); + end; // while} + end; // if +end; + +procedure TAudio_ffMpeg.SetVolume(Volume: integer); +begin + //Old Sets Wave Volume + //BASS_SetVolume(Volume); + //New: Sets Volume only for this Application + + + // TODO : jb_linux replace with something other than bass + BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); +end; + +procedure TAudio_ffMpeg.SetMusicVolume(Volume: Integer); +begin + //Max Volume Prevention + if Volume > 100 then + Volume := 100; + + if Volume < 0 then + Volume := 0; + + + //Set Volume + // TODO : jb_linux replace with something other than bass + BASS_ChannelSetAttributes (Bass, -1, Volume, -101); +end; + +procedure TAudio_ffMpeg.SetLoop(Enabled: boolean); +begin + Loop := Enabled; +end; + +function TAudio_ffMpeg.Open(Name: string): boolean; +begin + Loaded := false; + if FileExists(Name) then + begin + // TODO : jb_linux replace with something other than bass + Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); + + Loaded := true; + //Set Max Volume + SetMusicVolume (100); + end; + + Result := Loaded; +end; + +procedure TAudio_ffMpeg.Rewind; +begin + if Loaded then begin + end; +end; + +procedure TAudio_ffMpeg.MoveTo(Time: real); +var + bytes: integer; +begin + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelSeconds2Bytes(Bass, Time); + BASS_ChannelSetPosition(Bass, bytes); +end; + +procedure TAudio_ffMpeg.Play; +begin + // TODO : jb_linux replace with something other than bass + if Loaded then + begin + if Loop then + BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TAudio_ffMpeg Class + + BASS_ChannelPlay(Bass, False); // for setting position before playing + end; +end; + +procedure TAudio_ffMpeg.Pause; //Pause Mod +begin + // TODO : jb_linux replace with something other than bass + if Loaded then begin + BASS_ChannelPause(Bass); // Pauses Song + end; +end; + +procedure TAudio_ffMpeg.Stop; +begin + // TODO : jb_linux replace with something other than bass + Bass_ChannelStop(Bass); +end; + +procedure TAudio_ffMpeg.Close; +begin + // TODO : jb_linux replace with something other than bass + Bass_StreamFree(Bass); +end; + +function TAudio_ffMpeg.Length: real; +var + bytes: integer; +begin + Result := 60; + + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetLength(Bass); + Result := BASS_ChannelBytes2Seconds(Bass, bytes); +end; + +function TAudio_ffMpeg.Position: real; +var + bytes: integer; +begin + Result := 0; + + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetPosition(BASS); + Result := BASS_ChannelBytes2Seconds(BASS, bytes); +end; + +function TAudio_ffMpeg.Finished: boolean; +begin + Result := false; + + // TODO : jb_linux replace with something other than bass + if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then + begin + Result := true; + end; +end; + +procedure TAudio_ffMpeg.PlayStart; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassStart, True); +end; + +procedure TAudio_ffMpeg.PlayBack; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassBack, True);// then +end; + +procedure TAudio_ffMpeg.PlaySwoosh; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassSwoosh, True); +end; + +procedure TAudio_ffMpeg.PlayChange; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassChange, True); +end; + +procedure TAudio_ffMpeg.PlayOption; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassOption, True); +end; + +procedure TAudio_ffMpeg.PlayClick; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClick, True); +end; + +procedure TAudio_ffMpeg.PlayDrum; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassDrum, True); +end; + +procedure TAudio_ffMpeg.PlayHihat; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassHihat, True); +end; + +procedure TAudio_ffMpeg.PlayClap; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClap, True); +end; + +procedure TAudio_ffMpeg.PlayShuffle; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassShuffle, True); +end; + +procedure TAudio_ffMpeg.StopShuffle; +begin + // TODO : jb_linux replace with something other than bass + BASS_ChannelStop(BassShuffle); +end; + +procedure TAudio_ffMpeg.CaptureStart; +var + S: integer; + SC: integer; + P1: integer; + P2: integer; +begin + for S := 0 to High(Sound) do + Sound[S].BufferLong[0].Clear; + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then + CaptureCard(SC, P1, P2); + end; +end; + +procedure TAudio_ffMpeg.CaptureStop; +var + SC: integer; + P1: integer; + P2: integer; +begin + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then StopCard(SC); + end; + +end; + +//procedure TAudio_ffMpeg.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); +procedure TAudio_ffMpeg.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); +var + Error: integer; + ErrorMsg: string; +begin + if not BASS_RecordInit(RecordI) then + begin + Error := BASS_ErrorGetCode; + + ErrorMsg := IntToStr(Error); + if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5'; + if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized'; + if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid'; + if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver'; + + {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg);} + Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg); + Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg); + + + end + else + begin + Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256); + end; +end; + +procedure TAudio_ffMpeg.StopCard(Card: byte); +begin + // TODO : jb_linux replace with something other than bass + BASS_RecordSetDevice(Card); + BASS_RecordFree; +end; + +function TAudio_ffMpeg.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; +var + L: Integer; +begin + if FileExists(Name) then + begin + Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); + try + // TODO : jb_linux replace with something other than bass + hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); + + //Add CustomSound + L := High(CustomSounds) + 1; + SetLength (CustomSounds, L + 1); + CustomSounds[L].Filename := Name; + CustomSounds[L].Handle := hStream; + except + Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); + end; + end + else + begin + Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); + exit; + end; +end; + +//Equalizer +function TAudio_ffMpeg.GetFFTData: TFFTData; +var + Data: TFFTData; +begin + //Get Channel Data Mono and 256 Values + BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); +end; + +function TAudio_ffMpeg.LoadCustomSound(const Filename: String): Cardinal; +var + S: hStream; + I: Integer; + F: String; +begin + //Search for Sound in already loaded Sounds + F := UpperCase(SoundPath + FileName); + For I := 0 to High(CustomSounds) do + begin + if (UpperCase(CustomSounds[I].Filename) = F) then + begin + Result := I; + Exit; + end; + end; + + if LoadSoundFromFile(S, SoundPath + Filename) then + Result := High(CustomSounds) + else + Result := 0; +end; + +procedure TAudio_ffMpeg.PlayCustomSound(const Index: Cardinal ); +begin + if Index <= High(CustomSounds) then + BASS_ChannelPlay(CustomSounds[Index].Handle, True); +end; + + +{* + +Sorry guys... this is my mess :( +Im going to try and get ffmpeg to handle audio playback ( at least for linux ) +and Im going to implement it nicly along side BASS, in TAudio_ffMpeg ( where I can ) + +http://www.dranger.com/ffmpeg/ffmpeg.html +http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html + +http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html + +*} +{* +function TAudio_ffMpeg.FFMPeg_StreamCreateFile(abool : boolean; aFileName : pchar ): THandle; +var + lFormatCtx : PAVFormatContext; +begin + +(* + if(SDL_OpenAudio(&wanted_spec, &spec) < 0) + begin + fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError()); + writeln( 'SDL_OpenAudio' ); + exit; + end; +*) + +(* + if ( av_open_input_file( lFormatCtx, aFileName, NULL, 0, NULL ) <> 0 ) + begin + writeln( 'Unable to open file '+ aFileName ); + exit; + end; + + // Retrieve stream information + if ( av_find_stream_info(pFormatCtx) < 0 ) + begin + writeln( 'Unable to Retrieve stream information' ); + exit; + end; +*) + +end; *} + +initialization + singleton_MusicFFMpeg := TAudio_ffMpeg.create(); + + writeln( 'UAudio_Bass - Register Playback' ); + AudioManager.add( IAudioPlayback( singleton_MusicFFMpeg ) ); + +finalization
+ AudioManager.Remove( IAudioPlayback( singleton_MusicFFMpeg ) );
+
+ +end. diff --git a/Game/Code/Classes/UMusic_BASS.pas b/Game/Code/Classes/UAudio_bass.pas index 7de2d781..cbeadc47 100644 --- a/Game/Code/Classes/UMusic_BASS.pas +++ b/Game/Code/Classes/UAudio_bass.pas @@ -1,21 +1,16 @@ -unit UMusic_BASS; +unit UAudio_bass; interface -{$I switches.inc} - {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses Classes, - {$IFDEF win32} windows, {$ENDIF} - -// UCommon, Messages, SysUtils, {$IFNDEF FPC} @@ -25,14 +20,30 @@ uses Classes, bass, ULog, UMusic; -// USongs; -// Classes; +implementation + +uses + {$IFDEF FPC} + lclintf, + {$ENDIF} + URecord, + UIni, + UMain, + UThemes; +const + RecordSystem = 1; type + TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, + mpPaused, mpOpen); - TMusic_bass = class( TInterfacedObject, IAudioPlayback, IAudioInput ) +const + ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); + +type + TAudio_bass = class( TInterfacedObject, IAudioPlayback, IAudioInput ) private BassStart: hStream; // Wait, I've replaced this with BASS BassBack: hStream; // It has almost all features we need @@ -53,6 +64,7 @@ type public Bass: hStream; + function GetName: String; procedure InitializePlayback; procedure InitializeRecord; procedure SetVolume(Volume: integer); @@ -93,37 +105,15 @@ type procedure PlayCustomSound(const Index: Cardinal ); end; -const - RecordSystem = 1; - -type - TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, - mpPaused, mpOpen); - -const - ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); - -implementation - -uses - {$IFDEF FPC} - lclintf, - {$ENDIF} - -// avcodec, -// avformat, -// avutil, - -// UGraphic, - URecord, -// UFiles, - UIni, - UMain, - UThemes; - +var + singleton_MusicBass : IAudioPlayback; +function TAudio_bass.GetName: String; +begin + result := 'BASS';
+end; -procedure TMusic_bass.InitializePlayback; +procedure TAudio_bass.InitializePlayback; var Pet: integer; S: integer; @@ -139,7 +129,6 @@ begin fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function {$ENDIF} - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass if not BASS_Init(1, 44100, 0, fHWND, nil) then begin @@ -149,7 +138,6 @@ begin {$ENDIF} Exit; end; - {$ENDIF} Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); @@ -177,7 +165,7 @@ begin Log.LogBenchmark('--> Loading Sounds', 4); end; -procedure TMusic_bass.InitializeRecord; +procedure TAudio_bass.InitializeRecord; var S: integer; device: integer; @@ -252,21 +240,20 @@ begin end; // if end; -procedure TMusic_bass.SetVolume(Volume: integer); +procedure TAudio_bass.SetVolume(Volume: integer); begin //Old Sets Wave Volume //BASS_SetVolume(Volume); //New: Sets Volume only for this Application - {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); - {$ENDIF} end; -procedure TMusic_bass.SetMusicVolume(Volume: Integer); +procedure TAudio_bass.SetMusicVolume(Volume: Integer); begin //Max Volume Prevention if Volume > 100 then @@ -277,26 +264,22 @@ begin //Set Volume - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelSetAttributes (Bass, -1, Volume, -101); - {$ENDIF} end; -procedure TMusic_bass.SetLoop(Enabled: boolean); +procedure TAudio_bass.SetLoop(Enabled: boolean); begin Loop := Enabled; end; -function TMusic_bass.Open(Name: string): boolean; +function TAudio_bass.Open(Name: string): boolean; begin Loaded := false; if FileExists(Name) then begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); - {$ENDIF} Loaded := true; //Set Max Volume @@ -306,191 +289,153 @@ begin Result := Loaded; end; -procedure TMusic_bass.Rewind; +procedure TAudio_bass.Rewind; begin if Loaded then begin end; end; -procedure TMusic_bass.MoveTo(Time: real); +procedure TAudio_bass.MoveTo(Time: real); var bytes: integer; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass bytes := BASS_ChannelSeconds2Bytes(Bass, Time); BASS_ChannelSetPosition(Bass, bytes); - {$ENDIF} end; -procedure TMusic_bass.Play; +procedure TAudio_bass.Play; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass if Loaded then begin if Loop then - BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic_bass Class + BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TAudio_bass Class BASS_ChannelPlay(Bass, False); // for setting position before playing end; - {$ENDIF} end; -procedure TMusic_bass.Pause; //Pause Mod +procedure TAudio_bass.Pause; //Pause Mod begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass if Loaded then begin BASS_ChannelPause(Bass); // Pauses Song end; - {$ENDIF} end; -procedure TMusic_bass.Stop; +procedure TAudio_bass.Stop; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass Bass_ChannelStop(Bass); - {$ENDIF} end; -procedure TMusic_bass.Close; +procedure TAudio_bass.Close; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass Bass_StreamFree(Bass); - {$ENDIF} end; -function TMusic_bass.Length: real; +function TAudio_bass.Length: real; var bytes: integer; begin Result := 60; - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass bytes := BASS_ChannelGetLength(Bass); Result := BASS_ChannelBytes2Seconds(Bass, bytes); - {$ENDIF} end; -function TMusic_bass.Position: real; +function TAudio_bass.Position: real; var bytes: integer; begin Result := 0; - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass bytes := BASS_ChannelGetPosition(BASS); Result := BASS_ChannelBytes2Seconds(BASS, bytes); - {$ENDIF} end; -function TMusic_bass.Finished: boolean; +function TAudio_bass.Finished: boolean; begin Result := false; - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then begin Result := true; end; - {$ENDIF} end; -procedure TMusic_bass.PlayStart; +procedure TAudio_bass.PlayStart; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassStart, True); - {$ENDIF} end; -procedure TMusic_bass.PlayBack; +procedure TAudio_bass.PlayBack; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassBack, True);// then - {$ENDIF} end; -procedure TMusic_bass.PlaySwoosh; +procedure TAudio_bass.PlaySwoosh; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassSwoosh, True); - {$ENDIF} end; -procedure TMusic_bass.PlayChange; +procedure TAudio_bass.PlayChange; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassChange, True); - {$ENDIF} end; -procedure TMusic_bass.PlayOption; +procedure TAudio_bass.PlayOption; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassOption, True); - {$ENDIF} end; -procedure TMusic_bass.PlayClick; +procedure TAudio_bass.PlayClick; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassClick, True); - {$ENDIF} end; -procedure TMusic_bass.PlayDrum; +procedure TAudio_bass.PlayDrum; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassDrum, True); - {$ENDIF} end; -procedure TMusic_bass.PlayHihat; +procedure TAudio_bass.PlayHihat; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassHihat, True); - {$ENDIF} end; -procedure TMusic_bass.PlayClap; +procedure TAudio_bass.PlayClap; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassClap, True); - {$ENDIF} end; -procedure TMusic_bass.PlayShuffle; +procedure TAudio_bass.PlayShuffle; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelPlay(BassShuffle, True); - {$ENDIF} end; -procedure TMusic_bass.StopShuffle; +procedure TAudio_bass.StopShuffle; begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_ChannelStop(BassShuffle); - {$ENDIF} end; -procedure TMusic_bass.CaptureStart; +procedure TAudio_bass.CaptureStart; var S: integer; SC: integer; @@ -510,7 +455,7 @@ begin end; end; -procedure TMusic_bass.CaptureStop; +procedure TAudio_bass.CaptureStop; var SC: integer; P1: integer; @@ -527,15 +472,12 @@ begin end; -//procedure TMusic_bass.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); -procedure TMusic_bass.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); +//procedure TAudio_bass.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); +procedure TAudio_bass.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); var Error: integer; ErrorMsg: string; begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if not BASS_RecordInit(RecordI) then begin Error := BASS_ErrorGetCode; @@ -560,20 +502,16 @@ begin begin Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256); end; - - {$ENDIF} end; -procedure TMusic_bass.StopCard(Card: byte); +procedure TAudio_bass.StopCard(Card: byte); begin - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass BASS_RecordSetDevice(Card); BASS_RecordFree; - {$ENDIF} end; -function TMusic_bass.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; +function TAudio_bass.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; var L: Integer; begin @@ -581,15 +519,9 @@ begin begin Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); try - {$IFDEF useBASS} // TODO : jb_linux replace with something other than bass hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); - {$ELSE} - hStream := FFMPeg_StreamCreateFile(False, pchar(Name) ); - {$ENDIF} - - //Add CustomSound L := High(CustomSounds) + 1; SetLength (CustomSounds, L + 1); @@ -607,21 +539,15 @@ begin end; //Equalizer -function TMusic_bass.GetFFTData: TFFTData; +function TAudio_bass.GetFFTData: TFFTData; var -Data: TFFTData; + Data: TFFTData; begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - //Get Channel Data Mono and 256 Values BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); - //Result := Data; - - {$ENDIF} end; -function TMusic_bass.LoadCustomSound(const Filename: String): Cardinal; +function TAudio_bass.LoadCustomSound(const Filename: String): Cardinal; var S: hStream; I: Integer; @@ -644,15 +570,10 @@ begin Result := 0; end; -procedure TMusic_bass.PlayCustomSound(const Index: Cardinal ); +procedure TAudio_bass.PlayCustomSound(const Index: Cardinal ); begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if Index <= High(CustomSounds) then BASS_ChannelPlay(CustomSounds[Index].Handle, True); - - {$ENDIF} end; @@ -660,7 +581,7 @@ end; Sorry guys... this is my mess :( Im going to try and get ffmpeg to handle audio playback ( at least for linux ) -and Im going to implement it nicly along side BASS, in TMusic_bass ( where I can ) +and Im going to implement it nicly along side BASS, in TAudio_bass ( where I can ) http://www.dranger.com/ffmpeg/ffmpeg.html http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html @@ -669,7 +590,7 @@ http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html *} {* -function TMusic_bass.FFMPeg_StreamCreateFile(abool : boolean; aFileName : pchar ): THandle; +function TAudio_bass.FFMPeg_StreamCreateFile(abool : boolean; aFileName : pchar ): THandle; var lFormatCtx : PAVFormatContext; begin @@ -700,4 +621,17 @@ begin end; *} +initialization + singleton_MusicBass := TAudio_bass.create(); + + writeln( 'UAudio_Bass - Register Playback' ); + AudioManager.add( IAudioPlayback( singleton_MusicBass ) ); + + writeln( 'UAudio_Bass - Register Input' ); + AudioManager.add( IAudioInput( singleton_MusicBass ) ); + +finalization
+ AudioManager.Remove( IAudioPlayback( singleton_MusicBass ) );
+ AudioManager.Remove( IAudioInput( singleton_MusicBass ) );
+ end. diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index a2620607..8aa59d41 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -95,6 +95,8 @@ type type IAudioPlayback = Interface + ['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}'] + function GetName: String; procedure InitializePlayback; procedure SetVolume(Volume: integer); procedure SetMusicVolume(Volume: integer); @@ -129,6 +131,8 @@ type end; IAudioInput = Interface + ['{A5C8DA92-2A0C-4AB2-849B-2F7448C6003A}'] + function GetName: String; procedure InitializeRecord; procedure CaptureStart; @@ -158,46 +162,89 @@ procedure InitializeSound; function AudioPlayback(): IAudioPlayback; function AudioInput(): IAudioInput; +function AudioManager: TInterfaceList; + implementation uses - uLog, - UMusic_BASS; + sysutils, + uLog; var singleton_AudioPlayback : IAudioPlayback; singleton_AudioInput : IAudioInput; + singleton_AudioManager : TInterfaceList; + +
+function AudioManager: TInterfaceList;
+begin
+ Result := singleton_AudioManager;
+end; //CompressionPluginManager + function AudioPlayback(): IAudioPlayback; begin - if singleton_AudioPlayback = nil then
- begin
- writeln( 'Created AudioPlayback' );
- singleton_AudioPlayback := TMusic_bass.create(); // Yes we could do this with one instance of TMusic_Bass... but I cant be bothered at this point:P - end; - - result := singleton_AudioPlayback;
+ result := singleton_AudioPlayback; end; function AudioInput(): IAudioInput; begin - if singleton_AudioInput = nil then
- begin
- writeln( 'Created AudioInput' );
- singleton_AudioInput := TMusic_bass.create(); // Yes we could do this with one instance of TMusic_Bass... but I cant be bothered at this point:P - end; - result := singleton_AudioInput;
end; procedure InitializeSound; +var + lTmpPlayBack : IAudioPlayback; + lTmpInput : IAudioInput; + iCount : Integer; begin - Log.LogStatus('Initializing Playback', 'InitializeSound'); - AudioPlayback.InitializePlayback; - - Log.LogStatus('Initializing Record', 'InitializeSound'); - AudioInput.InitializeRecord; + lTmpPlayBack := nil; + lTmpInput := nil; + + writeln( 'InitializeSound , Enumerate Registered Audio Interfaces' ); + for iCount := 0 to singleton_AudioManager.Count - 1 do + begin + if assigned( AudioManager[iCount] ) then + begin + // if this interface is a Playback, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IAudioPlayback, lTmpPlayBack ) = 0 ) AND
+ ( not assigned( singleton_AudioPlayback ) ) then + begin + singleton_AudioPlayback := lTmpPlayBack;
+ end;
+
+ // if this interface is a Input, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IAudioInput, lTmpInput ) = 0 ) AND
+ ( not assigned( singleton_AudioInput ) ) then
+ begin + singleton_AudioInput := lTmpInput;
+ end;
+ end;
+ end;
+ + + writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName ); + writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName ); + + // Initialize Playback + Log.LogStatus('Initializing Playback ('+AudioPlayback.GetName+')', 'InitializeSound'); + AudioPlayback.InitializePlayback; + + // Initialize Input + Log.LogStatus('Initializing Record ('+AudioPlayback.GetName+')', 'InitializeSound'); + AudioInput.InitializeRecord; end; +initialization +begin
+ writeln('Init AudioManager');
+ singleton_AudioManager := TInterfaceList.Create();
+end;
+
+finalization
+ writeln('Finalize AudioManager');
+ singleton_AudioManager.clear;
+ FreeAndNil( singleton_AudioManager ); + end. diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index 239984b5..de34aa52 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -43,8 +43,12 @@ uses UCommon in 'Classes\UCommon.pas',
UGraphic in 'Classes\UGraphic.pas',
UTexture in 'Classes\UTexture.pas',
- UMusic in 'Classes\UMusic.pas',
- UMusic_BASS in 'Classes\UMusic_BASS.pas',
+
+ UMusic in 'Classes\UMusic.pas',
+ UAudio_FFMpeg in 'Classes\UAudio_FFMpeg.pas',
+ UAudio_Bass in 'Classes\UAudio_Bass.pas',
+
+
ULanguage in 'Classes\ULanguage.pas',
UMain in 'Classes\UMain.pas',
UDraw in 'Classes\UDraw.pas',
@@ -291,8 +295,7 @@ begin // Sound
Log.BenchmarkStart(1);
- Log.LogStatus('Initialize Sound', 'Initialization');
- Log.LogStatus('Creating Music', 'InitializeSound'); InitializeSound();
+ Log.LogStatus('Initialize Sound', 'Initialization'); InitializeSound();
Log.BenchmarkEnd(1);
Log.LogBenchmark('Initializing Sound', 1);
|