diff options
Diffstat (limited to 'Game/Code/Classes/UAudioPlayback_Bass.pas')
-rw-r--r-- | Game/Code/Classes/UAudioPlayback_Bass.pas | 450 |
1 files changed, 183 insertions, 267 deletions
diff --git a/Game/Code/Classes/UAudioPlayback_Bass.pas b/Game/Code/Classes/UAudioPlayback_Bass.pas index 87ff183d..266a5ec3 100644 --- a/Game/Code/Classes/UAudioPlayback_Bass.pas +++ b/Game/Code/Classes/UAudioPlayback_Bass.pas @@ -9,35 +9,31 @@ interface {$I switches.inc} -uses Classes, - {$IFDEF win32} - windows, - {$ENDIF} - SysUtils, - bass, - ULog, - UMusic; +uses + Classes, + SysUtils, + UMusic; implementation uses - {$IFDEF LAZARUS} - lclintf, - {$ENDIF} - URecord, - UIni, - UMain, - UCommon, - UThemes; + UIni, + UMain, + ULog, + UAudioCore_Bass, + bass; type - TBassOutputStream = class(TAudioPlaybackStream) + TBassPlaybackStream = class(TAudioPlaybackStream) private Handle: HSTREAM; + Loop: boolean; public constructor Create(); overload; constructor Create(stream: HSTREAM); overload; + procedure Reset(); + procedure Play(); override; procedure Pause(); override; procedure Stop(); override; @@ -46,41 +42,33 @@ type procedure SetLoop(Enabled: boolean); override; function GetLength(): real; override; function GetStatus(): TStreamStatus; override; + function GetVolume(): integer; override; + procedure SetVolume(volume: integer); override; + + function GetPosition: real; + procedure SetPosition(Time: real); + + function IsLoaded(): boolean; end; type TAudioPlayback_Bass = class( TInterfacedObject, IAudioPlayback) private - MusicStream: HSTREAM; - - StartSoundStream: HSTREAM; - BackSoundStream: HSTREAM; - SwooshSoundStream: HSTREAM; - ChangeSoundStream: HSTREAM; - OptionSoundStream: HSTREAM; - ClickSoundStream: HSTREAM; - DrumSoundStream: HSTREAM; - HihatSoundStream: HSTREAM; - ClapSoundStream: HSTREAM; - ShuffleSoundStream: HSTREAM; - - //Custom Sounds - CustomSounds: array of TCustomSoundEntry; - Loaded: boolean; - Loop: boolean; + MusicStream: TBassPlaybackStream; + function Load(Filename: string): TBassPlaybackStream; public function GetName: String; {IAudioOutput interface} - procedure InitializePlayback; + function InitializePlayback(): boolean; procedure SetVolume(Volume: integer); procedure SetMusicVolume(Volume: integer); procedure SetLoop(Enabled: boolean); - function Open(Name: string): boolean; // true if succeed - + function Open(Filename: string): boolean; // true if succeed + procedure Rewind; procedure Play; procedure Pause; //Pause Mod @@ -91,79 +79,106 @@ type function GetPosition: real; procedure SetPosition(Time: real); - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - - function LoadSoundFromFile(var stream: HSTREAM; Name: string): boolean; - //Equalizer - function GetFFTData: TFFTData; + procedure GetFFTData(var data: TFFTData); // Interface for Visualizer function GetPCMData(var data: TPCMData): Cardinal; - //Custom Sounds - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal ); + // Sounds + function OpenSound(const Filename: String): TAudioPlaybackStream; + procedure PlaySound(stream: TAudioPlaybackStream);
+ procedure StopSound(stream: TAudioPlaybackStream); end; var singleton_AudioPlaybackBass : IAudioPlayback; -constructor TBassOutputStream.Create(); +constructor TBassPlaybackStream.Create(); begin inherited; + Reset(); end; -constructor TBassOutputStream.Create(stream: HSTREAM); +constructor TBassPlaybackStream.Create(stream: HSTREAM); begin Create(); Handle := stream; end; -procedure TBassOutputStream.Play(); +procedure TBassPlaybackStream.Reset(); +begin + Loop := false; + if (Handle <> 0) then + Bass_StreamFree(Handle); + Handle := 0; +end; + +procedure TBassPlaybackStream.Play(); begin - BASS_ChannelPlay(Handle, True); + BASS_ChannelPlay(Handle, Loop); end; -procedure TBassOutputStream.Pause(); +procedure TBassPlaybackStream.Pause(); begin - //if (Loaded) then BASS_ChannelPause(Handle); end; -procedure TBassOutputStream.Stop(); +procedure TBassPlaybackStream.Stop(); begin BASS_ChannelStop(Handle); end; -procedure TBassOutputStream.Close(); +procedure TBassPlaybackStream.Close(); begin - Bass_StreamFree(Handle); + Reset(); end; -function TBassOutputStream.GetLoop(): boolean; +function TBassPlaybackStream.GetVolume(): integer; begin - // TODO - result := false; + Result := 0; + BASS_ChannelSetAttributes(Handle, PInteger(nil)^, Result, PInteger(nil)^); +end; + +procedure TBassPlaybackStream.SetVolume(volume: integer); +begin + // clamp volume + if volume < 0 then + volume := 0; + if volume > 100 then + volume := 100; + // set volume + BASS_ChannelSetAttributes(Handle, -1, volume, -101); end; -procedure TBassOutputStream.SetLoop(Enabled: boolean); +function TBassPlaybackStream.GetPosition: real; +var + bytes: integer; +begin + bytes := BASS_ChannelGetPosition(Handle); + Result := BASS_ChannelBytes2Seconds(Handle, bytes); +end; + +procedure TBassPlaybackStream.SetPosition(Time: real); +var + bytes: integer; begin - // TODO + bytes := BASS_ChannelSeconds2Bytes(Handle, Time); + BASS_ChannelSetPosition(Handle, bytes); end; -function TBassOutputStream.GetLength(): real; +function TBassPlaybackStream.GetLoop(): boolean; +begin + result := Loop; +end; + +procedure TBassPlaybackStream.SetLoop(Enabled: boolean); +begin + Loop := Enabled; +end; + +function TBassPlaybackStream.GetLength(): real; var bytes: integer; begin @@ -171,37 +186,45 @@ begin Result := BASS_ChannelBytes2Seconds(Handle, bytes); end; -function TBassOutputStream.GetStatus(): TStreamStatus; +function TBassPlaybackStream.GetStatus(): TStreamStatus; var state: DWORD; begin state := BASS_ChannelIsActive(Handle); case state of BASS_ACTIVE_PLAYING: - result := sPlaying; + result := ssPlaying; BASS_ACTIVE_PAUSED: - result := sPaused; + result := ssPaused; + BASS_ACTIVE_STALLED: + result := ssBlocked; + BASS_ACTIVE_STOPPED: + result := ssStopped; else - result := sStopped; + result := ssUnknown; end; end; +function TBassPlaybackStream.IsLoaded(): boolean; +begin + Result := (Handle <> 0); +end; + function TAudioPlayback_Bass.GetName: String; begin result := 'BASS_Playback'; end; -procedure TAudioPlayback_Bass.InitializePlayback; +function TAudioPlayback_Bass.InitializePlayback(): boolean; var Pet: integer; S: integer; begin -// Log.BenchmarkStart(4); -// Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); + result := false; - Loaded := false; - Loop := false; + //Log.BenchmarkStart(4); + //Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); if not BASS_Init(1, 44100, 0, 0, nil) then begin @@ -209,30 +232,32 @@ begin Exit; end; -// Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); + //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'); + //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); + //BASS_SetConfig(BASS_CONFIG_BUFFER, 100); -// Log.BenchmarkStart(4); - LoadSoundFromFile(StartSoundStream, SoundPath + 'Common Start.mp3'); - LoadSoundFromFile(BackSoundStream, SoundPath + 'Common Back.mp3'); - LoadSoundFromFile(SwooshSoundStream, SoundPath + 'menu swoosh.mp3'); - LoadSoundFromFile(ChangeSoundStream, SoundPath + 'select music change music 50.mp3'); - LoadSoundFromFile(OptionSoundStream, SoundPath + 'option change col.mp3'); - LoadSoundFromFile(ClickSoundStream, SoundPath + 'rimshot022b.mp3'); + result := true; +end; -// LoadSoundFromFile(DrumSoundStream, SoundPath + 'bassdrumhard076b.mp3'); -// LoadSoundFromFile(HihatSoundStream, SoundPath + 'hihatclosed068b.mp3'); -// LoadSoundFromFile(ClapSoundStream, SoundPath + 'claps050b.mp3'); +function TAudioPlayback_Bass.Load(Filename: string): TBassPlaybackStream; +var + L: Integer; + stream: HSTREAM; +begin + Result := nil; -// LoadSoundFromFile(ShuffleSoundStream, SoundPath + 'Shuffle.mp3'); + //Log.LogStatus('Loading Sound: "' + Filename + '"', 'LoadSoundFromFile'); + stream := BASS_StreamCreateFile(False, pchar(Filename), 0, 0, 0); + if (stream = 0) then + begin + Log.LogError('Failed to open "' + Filename + '", ' + + TAudioCore_Bass.ErrorGetString(BASS_ErrorGetCode()), 'TAudioPlayback_Bass.Load'); + Exit; + end; -// Log.BenchmarkEnd(4); -// Log.LogBenchmark('--> Loading Sounds', 4); + Result := TBassPlaybackStream.Create(stream); end; procedure TAudioPlayback_Bass.SetVolume(Volume: integer); @@ -240,7 +265,6 @@ begin //Old Sets Wave Volume //BASS_SetVolume(Volume); //New: Sets Volume only for this Application - BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); @@ -248,193 +272,102 @@ end; procedure TAudioPlayback_Bass.SetMusicVolume(Volume: Integer); begin - //Max Volume Prevention - if Volume > 100 then - Volume := 100; - - if Volume < 0 then - Volume := 0; - - //Set Volume - BASS_ChannelSetAttributes (MusicStream, -1, Volume, -101); + if assigned(MusicStream) then + MusicStream.SetVolume(Volume); end; procedure TAudioPlayback_Bass.SetLoop(Enabled: boolean); begin - Loop := Enabled; + if assigned(MusicStream) then + MusicStream.Loop := Enabled; end; -function TAudioPlayback_Bass.Open(Name: string): boolean; +function TAudioPlayback_Bass.Open(Filename: string): boolean; +var + stream: HSTREAM; begin - Loaded := false; - if FileExists(Name) then - begin - MusicStream := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); + Result := false; - Loaded := true; - //Set Max Volume - SetMusicVolume (100); - end; + // free old MusicStream + if assigned(MusicStream) then + MusicStream.Free; - Result := Loaded; -end; + MusicStream := Load(Filename); + if not assigned(MusicStream) then + Exit; -procedure TAudioPlayback_Bass.Rewind; -begin - if Loaded then begin - end; + //Set Max Volume + SetMusicVolume(100); + + Result := true; end; -procedure TAudioPlayback_Bass.SetPosition(Time: real); -var - bytes: integer; +procedure TAudioPlayback_Bass.Rewind; begin - bytes := BASS_ChannelSeconds2Bytes(MusicStream, Time); - BASS_ChannelSetPosition(MusicStream, bytes); + SetPosition(0); end; procedure TAudioPlayback_Bass.Play; begin - if Loaded then - begin - if Loop then - BASS_ChannelPlay(MusicStream, True); // start from beginning... actually bass itself does not loop, nor does this TAudio_bass Class - - BASS_ChannelPlay(MusicStream, False); // for setting position before playing - end; + if assigned(MusicStream) then + MusicStream.Play(); end; -procedure TAudioPlayback_Bass.Pause; //Pause Mod +procedure TAudioPlayback_Bass.Pause; begin - if Loaded then begin - BASS_ChannelPause(MusicStream); // Pauses Song - end; + if assigned(MusicStream) then + MusicStream.Pause(); end; procedure TAudioPlayback_Bass.Stop; begin - Bass_ChannelStop(MusicStream); + if assigned(MusicStream) then + MusicStream.Stop(); end; procedure TAudioPlayback_Bass.Close; begin - Bass_StreamFree(MusicStream); + if assigned(MusicStream) then + MusicStream.Close(); end; function TAudioPlayback_Bass.Length: real; var bytes: integer; begin - bytes := BASS_ChannelGetLength(MusicStream); - Result := BASS_ChannelBytes2Seconds(MusicStream, bytes); -end; - -function TAudioPlayback_Bass.getPosition: real; -var - bytes: integer; -begin - bytes := BASS_ChannelGetPosition(MusicStream); - Result := BASS_ChannelBytes2Seconds(MusicStream, bytes); -end; - -function TAudioPlayback_Bass.Finished: boolean; -begin - Result := false; - - if BASS_ChannelIsActive(MusicStream) = BASS_ACTIVE_STOPPED then - begin - Result := true; - end; -end; - -procedure TAudioPlayback_Bass.PlayStart; -begin - BASS_ChannelPlay(StartSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayBack; -begin - BASS_ChannelPlay(BackSoundStream, True);// then -end; - -procedure TAudioPlayback_Bass.PlaySwoosh; -begin - BASS_ChannelPlay(SwooshSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayChange; -begin - BASS_ChannelPlay(ChangeSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayOption; -begin - BASS_ChannelPlay(OptionSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayClick; -begin - BASS_ChannelPlay(ClickSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayDrum; -begin - BASS_ChannelPlay(DrumSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayHihat; -begin - BASS_ChannelPlay(HihatSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayClap; -begin - BASS_ChannelPlay(ClapSoundStream, True); + if assigned(MusicStream) then + Result := MusicStream.GetLength() + else + Result := -1; end; -procedure TAudioPlayback_Bass.PlayShuffle; +function TAudioPlayback_Bass.GetPosition: real; begin - BASS_ChannelPlay(ShuffleSoundStream, True); + if assigned(MusicStream) then + Result := MusicStream.GetPosition() + else + Result := -1; end; -procedure TAudioPlayback_Bass.StopShuffle; +procedure TAudioPlayback_Bass.SetPosition(Time: real); begin - BASS_ChannelStop(ShuffleSoundStream); + if assigned(MusicStream) then + MusicStream.SetPosition(Time); end; -function TAudioPlayback_Bass.LoadSoundFromFile(var stream: HSTREAM; Name: string): boolean; -var - L: Integer; +function TAudioPlayback_Bass.Finished: boolean; begin - if FileExists(Name) then - begin - Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); - try - stream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); - - //Add CustomSound - L := High(CustomSounds) + 1; - SetLength (CustomSounds, L + 1); - CustomSounds[L].Filename := Name; - CustomSounds[L].Stream := TBassOutputStream.Create(stream); - except - Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); - end; - end + if assigned(MusicStream) then + Result := (MusicStream.GetStatus() = ssStopped) else - begin - Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); - exit; - end; + Result := true; end; //Equalizer -function TAudioPlayback_Bass.GetFFTData: TFFTData; -var - Data: TFFTData; +procedure TAudioPlayback_Bass.GetFFTData(var data: TFFTData); begin //Get Channel Data Mono and 256 Values - BASS_ChannelGetData(MusicStream, @Result, BASS_DATA_FFT512); + BASS_ChannelGetData(MusicStream.Handle, @data, BASS_DATA_FFT512); end; {* @@ -447,23 +380,21 @@ var nBytes: DWORD; begin //Get Channel Data Mono and 256 Values - BASS_ChannelGetInfo(MusicStream, info); - ZeroMemory(@data, sizeof(TPCMData)); + BASS_ChannelGetInfo(MusicStream.Handle, info); + FillChar(data, sizeof(TPCMData), 0); if (info.chans = 1) then begin // mono file -> add stereo channel - { - nBytes := BASS_ChannelGetData(Bass, @data[0], samples*sizeof(Smallint)); + nBytes := 0;//BASS_ChannelGetData(Bass, @data[0], samples*sizeof(Smallint)); // interleave data //CopyMemory(@data[1], @data[0], samples*sizeof(Smallint)); - } result := 0; end else begin // stereo file - nBytes := BASS_ChannelGetData(MusicStream, @data, sizeof(TPCMData)); + nBytes := BASS_ChannelGetData(MusicStream.Handle, @data, sizeof(TPCMData)); end; if(nBytes <= 0) then result := 0 @@ -471,36 +402,21 @@ begin result := nBytes div sizeof(TPCMStereoSample); end; -function TAudioPlayback_Bass.LoadCustomSound(const Filename: String): Cardinal; -var - S: hStream; - I: Integer; - F: String; +function TAudioPlayback_Bass.OpenSound(const Filename: string): TAudioPlaybackStream; 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; + result := Load(Filename); +end; - if LoadSoundFromFile(S, SoundPath + Filename) then - Result := High(CustomSounds) - else - Result := 0; +procedure TAudioPlayback_Bass.PlaySound(stream: TAudioPlaybackStream); +begin + if assigned(stream) then + stream.Play(); end; -procedure TAudioPlayback_Bass.PlayCustomSound(const Index: Cardinal ); +procedure TAudioPlayback_Bass.StopSound(stream: TAudioPlaybackStream); begin - if Index <= High(CustomSounds) then - with CustomSounds[Index].Stream as TBassOutputStream do - begin - BASS_ChannelPlay(Handle, True); - end; + if assigned(stream) then + stream.Stop(); end; |