aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code
diff options
context:
space:
mode:
authorjaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-10-11 13:32:43 +0000
committerjaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-10-11 13:32:43 +0000
commitdf37a6a52ea5b1856e9e0e4d924a859f3fa472e1 (patch)
tree3b5808921a947a5952224f605f23d4932f31535b /Game/Code
parent6292440f6da3c11e85bb9fc3a741a26540e429be (diff)
downloadusdx-df37a6a52ea5b1856e9e0e4d924a859f3fa472e1.tar.gz
usdx-df37a6a52ea5b1856e9e0e4d924a859f3fa472e1.tar.xz
usdx-df37a6a52ea5b1856e9e0e4d924a859f3fa472e1.zip
added UAudio_FFMpeg.pas as placeholder... ( Still has bass code in it.. needs to be replaced with ffmpeg code )
UMusic ( And UAudio* ) files, now have proper IAudioPlayback and IAudioInput Interface enumeration. simply having the unit in the uses clause will make it available. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@506 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code')
-rw-r--r--Game/Code/Classes/UAudio_FFMpeg.pas634
-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.pas87
-rw-r--r--Game/Code/UltraStar.dpr11
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);