diff options
Diffstat (limited to '')
-rw-r--r-- | Game/Code/Classes/UMusic.pas | 951 |
1 files changed, 951 insertions, 0 deletions
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas new file mode 100644 index 00000000..c4f80235 --- /dev/null +++ b/Game/Code/Classes/UMusic.pas @@ -0,0 +1,951 @@ +unit UMusic;
+
+interface
+
+uses Classes, MPlayer, Windows, Messages, SysUtils, Forms, ULog, USongs, Bass;//, DXSounds;
+
+procedure InitializeSound;
+
+type
+ TPos = record
+ line: integer;
+ note: integer;
+ end;
+
+ TSongMode = (smNormal, smParty, smChallenge, smMedley);
+
+ TSoundCard = record
+ Name: string;
+ Source: array of string;
+ end;
+
+ TFFTData = array [0..256] of Single;
+
+ TCustomSoundEntry = record
+ Filename: String;
+ Handle: hStream;
+ end;
+
+ TMusic = class
+ private
+// MediaPlayer: TMediaPlayer; // It will be replaced by another component;
+{ MediaPlayerStart: TMediaPlayer; // or maybe not if done this way ;)
+ MediaPlayerBack: TMediaPlayer;
+ MediaPlayerSwoosh: TMediaPlayer;
+ MediaPlayerChange: TMediaPlayer;
+ MediaPlayerOption: TMediaPlayer;
+ MediaPlayerClick: TMediaPlayer;
+ MediaPlayerDrum: TMediaPlayer;
+ MediaPlayerHihat: TMediaPlayer;
+ MediaPlayerClap: TMediaPlayer;
+ MediaPlayerShuffle: TMediaPlayer;}
+ 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;
+ BassApplause: hStream;
+
+ //Custom Sounds
+ CustomSounds: array of TCustomSoundEntry;
+
+
+ Loaded: boolean;
+ Loop: boolean;
+// DXSound: TDXSound;
+// Player: TcmxMp3;
+ DSP_VocalRemover: HDSP;
+ public
+ Bass: hStream;
+
+// SoundCard: array of TSoundCard;
+ procedure InitializePlayback;
+ procedure InitializeRecord;
+ procedure SetVolume(Volume: integer);
+ procedure SetMusicVolume(Volume: integer);
+ procedure Fade(InitVolume, TargetVolume: Integer; FadeTime: real);
+ procedure FadeStop(FadeTime: real);
+ 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 PlayApplause;
+ procedure CaptureStart;
+ procedure CaptureStop;
+ procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
+ procedure StopCard(Card: byte);
+ function LoadPlayerFromFile(var MediaPlayer: TMediaPlayer; Name: string): boolean;
+ 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);
+
+ procedure EnableVocalRemover;
+ procedure DisableVocalRemover;
+ function VocalRemoverActivated(): boolean;
+
+end;
+
+const
+ RecordSystem = 1;
+
+function FindNote(beat: integer): TPos;
+
+type
+ TMuzyka = record
+ Path: string;
+ Start: integer; // start of song in ms
+// BPM: array of TBPM;
+// Gap: real;
+ IlNut: integer;
+ DlugoscNut: integer;
+// WartoscNut: integer;
+ end;
+
+ TCzesci = record //Lines
+ Akt: integer; // aktualna czesc utworu do rysowania
+ High: integer;
+ Ilosc: integer;
+ Resolution: integer;
+ NotesGAP: integer;
+ Wartosc: integer;
+ Czesc: array of record //Line
+ Start: integer;
+ StartNote: integer;
+ Lyric: string;
+ LyricWidth: real;
+ Koniec: integer; //Ende?
+ BaseNote: integer;
+ HighNut: integer;
+ IlNut: integer;
+ TotalNotes: integer;
+ Nuta: array of record //Note
+ Color: integer;
+ Start: integer;
+ Dlugosc: integer;
+ Ton: integer;
+ TonGamy: integer;
+ Tekst: string; //Silbe?
+ FreeStyle: boolean;
+ Wartosc: integer; // zwykla nuta x1, zlota nuta x2
+ IsMedley: boolean; //just for editor
+ IsStartPreview: boolean; //just for editor
+
+
+
+
+ end;
+ end;
+ end;
+
+ TCzas = record // wszystko, co dotyczy aktualnej klatki
+// BajtowTotal: integer;
+// BajtowTeraz: integer;
+// BajtowNaSek: integer;
+ OldBeat: integer; // poprzednio wykryty beat w utworze
+ AktBeat: integer; // aktualny beat w utworze
+ MidBeat: real; // dokladny AktBeat
+
+ // should not be used
+// OldHalf: integer; // poprzednio wykryta polowka
+// AktHalf: integer; // aktualna polowka w utworze
+// MidHalf: real; // dokladny AktHalf
+
+ // now we use this for super synchronization!
+ // only used when analyzing voice
+ OldBeatD: integer; // poprzednio wykryty beat w utworze
+ AktBeatD: integer; // aktualny beat w utworze
+ MidBeatD: real; // dokladny AktBeatD
+ FracBeatD: real; // fractional part of MidBeatD
+
+ // we use this for audiable clicks
+ OldBeatC: integer; // poprzednio wykryty beat w utworze
+ AktBeatC: integer; // aktualny beat w utworze
+ MidBeatC: real; // dokladny AktBeatC
+ FracBeatC: real; // fractional part of MidBeatC
+
+
+ OldCzesc: integer; // poprzednio wyswietlana czesc
+ // akt jest w czesci.akt
+
+ Teraz: real; // aktualny czas w utworze
+ Razem: real; // caly czas utworu
+// TerazSek: integer;
+ end;
+
+var
+ Form: TForm;
+ Music: TMusic;
+
+ // muzyka
+ Muzyka: TMuzyka;
+
+ // czesci z nutami;
+ Czesci: array of TCzesci;
+
+ // czas
+ Czas: TCzas;
+
+ fHWND: Thandle;
+
+const
+ ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
+
+implementation
+uses UGraphic, URecord, UFiles, UIni, UMain, UThemes, UTime;
+
+//from http://www.un4seen.com/forum/?topic=5943.0;hl=sbvocalcut16
+procedure SBVocalCut16(handle: DWORD; channel: DWORD; buffer: Pointer; length: DWORD; user: DWORD); stdcall;
+var
+ i, k: DWORD;
+ dmch: Smallint;
+ lch, rch: PSmallint;
+
+begin
+ i := 0;
+ lch := buffer;
+ rch := buffer;
+ Inc(rch);
+
+ while (i < length) do
+ begin
+ dmch := round((((0 - lch^) + (rch^)) div 2)*1.5);
+
+ lch^ := dmch;
+ rch^ := dmch;
+
+ Inc(lch, 2);
+ Inc(rch, 2);
+ Inc(i, SizeOf(SmallInt) * 2);
+ end;
+end;
+
+function FindNote(beat: integer): TPos;
+var
+ I, J: integer;
+ found: boolean;
+ min: integer;
+ diff: integer;
+begin
+ found := false;
+ for I := 0 to length(Czesci[0].Czesc) - 1 do
+ begin
+ for J := 0 to length(Czesci[0].Czesc[I].Nuta) - 1 do
+ begin
+ if (beat>=Czesci[0].Czesc[I].Nuta[J].Start) and
+ (beat<=Czesci[0].Czesc[I].Nuta[J].Start + Czesci[0].Czesc[I].Nuta[J].Dlugosc) then
+ begin
+ Result.line := I;
+ Result.note := J;
+ found:=true;
+ break;
+ end;
+ end;
+ end;
+
+ if found then //found exactly
+ exit;
+
+ min := high(integer);
+ //second try (approximating)
+ for I := 0 to length(Czesci[0].Czesc) - 1 do
+ begin
+ for J := 0 to length(Czesci[0].Czesc[I].Nuta) - 1 do
+ begin
+ diff := abs(Czesci[0].Czesc[I].Nuta[J].Start - beat);
+ if diff<min then
+ begin
+ Result.line := I;
+ Result.note := J;
+ min := diff;
+ end;
+ end;
+ end;
+end;
+
+procedure InitializeSound;
+begin
+ Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback;
+ Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord;
+end;
+
+procedure TMusic.InitializePlayback;
+var
+ Pet: integer;
+ S: integer;
+begin
+ Log.BenchmarkStart(4);
+ Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
+ Loaded := false;
+ Loop := false;
+ fHWND := AllocateHWND( nil);
+
+ if BASS_Init(1, 44100, 0, fHWND, nil) = false then + begin
+ Application.MessageBox ('Could not initialize BASS', 'Error');
+ Exit;
+ end;
+ DSP_VocalRemover := 0;
+ Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
+
+ // config playing buffer
+ //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 0);
+ //BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
+
+{ MediaPlayer := TMediaPlayer.Create( nil );
+ MediaPlayer.ParentWindow := fHWND;
+ MediaPlayer.Wait := true;}
+
+ Log.LogStatus('Loading Sounds', 'Music Initialize');
+
+{ LoadPlayerFromFile(MediaPlayerStart, SoundPath + 'Common Start.mp3');
+ LoadPlayerFromFile(MediaPlayerBack, SoundPath + 'Common Back.mp3');
+ LoadPlayerFromFile(MediaPlayerSwoosh, SoundPath + 'menu swoosh.mp3');
+ LoadPlayerFromFile(MediaPlayerChange, SoundPath + 'select music change music.mp3');
+ LoadPlayerFromFile(MediaPlayerOption, SoundPath + 'option change col.mp3');
+ LoadPlayerFromFile(MediaPlayerClick, SoundPath + 'rimshot022b.mp3');
+
+ LoadPlayerFromFile(MediaPlayerDrum, SoundPath + 'bassdrumhard076b.mp3');
+ LoadPlayerFromFile(MediaPlayerHihat, SoundPath + 'hihatclosed068b.mp3');
+ LoadPlayerFromFile(MediaPlayerClap, SoundPath + 'claps050b.mp3');
+
+ LoadPlayerFromFile(MediaPlayerShuffle, SoundPath + 'Shuffle.mp3');}
+
+ 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');
+ LoadSoundFromFile(BassApplause, SoundPath + 'Applause.mp3');
+ Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4);
+end;
+
+procedure TMusic.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 TMusic.SetVolume(Volume: integer);
+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);
+end;
+
+procedure TMusic.SetMusicVolume(Volume: Integer);
+begin
+ //Max Volume Prevention
+ if Volume > 100 then
+ Volume := 100;
+
+ //Set Volume
+ BASS_ChannelSetAttributes (Bass, -1, Volume, -101);
+end;
+
+procedure TMusic.Fade(InitVolume, TargetVolume: Integer; FadeTime: real);
+var
+ time: dword;
+begin
+ //Max Volume Prevention
+ if TargetVolume > 100 then
+ TargetVolume := 100
+ else if TargetVolume<0 then
+ TargetVolume := 0;
+
+ BASS_ChannelSetAttributes (Bass, -1, InitVolume, -101);
+ time := round(FadeTime*1000);
+ BASS_ChannelSlideAttributes (Bass, -1, TargetVolume, -101, time);
+end;
+
+procedure TMusic.FadeStop(FadeTime: real);
+var
+ time: dword;
+begin
+ time := round(FadeTime*1000);
+ BASS_ChannelSlideAttributes (Bass, -1, -2, -101, time); //fade out and stop
+end;
+
+procedure TMusic.SetLoop(Enabled: boolean);
+begin
+ Loop := Enabled;
+end;
+
+function TMusic.Open(Name: string): boolean;
+begin
+ Loaded := false;
+
+ if FileExists(Name) then begin
+{ MediaPlayer.FileName := Name;
+ MediaPlayer.Open;}
+
+ Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0);
+ Loaded := true;
+ DSP_VocalRemover:=0;
+ //Set Max Volume
+ SetMusicVolume (100);
+ end;
+
+ Result := Loaded;
+
+// Player := TcmxMp3.Create(Name);
+end;
+
+procedure TMusic.Rewind;
+begin
+ if Loaded then begin
+// MediaPlayer.Position := 0;
+
+ end;
+end;
+
+procedure TMusic.MoveTo(Time: real);
+var
+ bytes: integer;
+begin
+// if Loaded then begin
+// MediaPlayer.StartPos := Round(Time);
+ bytes := BASS_ChannelSeconds2Bytes(Bass, Time);
+ BASS_ChannelSetPosition(Bass, bytes);
+// end;
+end;
+
+procedure TMusic.Play;
+begin
+ if Loaded then begin
+// MediaPlayer.Play;
+ if Loop then BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class
+ BASS_ChannelPlay(Bass, False); // for setting position before playing
+ end;
+end;
+
+procedure TMusic.Pause; //Pause Mod
+begin
+ if Loaded then begin
+ BASS_ChannelPause(Bass); // Pauses Song
+ end;
+end;
+
+procedure TMusic.Stop;
+begin
+ Bass_ChannelStop(Bass);
+// Bass_StreamFree(Bass);
+// if ModeStr[MediaPlayer.Mode] = 'Playing' then begin
+// MediaPlayer.Stop;
+// end;
+end;
+
+procedure TMusic.Close;
+begin
+ Bass_StreamFree(Bass);
+ DSP_VocalRemover:=0;
+// Player.Free;
+// MediaPlayer.Close;
+end;
+
+function TMusic.Length: real;
+var
+ bytes: integer;
+begin
+ Result := 60;
+
+ bytes := BASS_ChannelGetLength( Bass );
+ Result := BASS_ChannelBytes2Seconds(Bass, bytes);
+
+{ if Assigned(MediaPlayer) then begin
+ if Loaded then Result := MediaPlayer.Length / 1000;
+ end;}
+// if Assigned(Player) then
+// Result := Player.LengthInSeconds;
+end;
+
+function TMusic.Position: real;
+var
+ bytes: integer;
+begin
+ Result := 0;//MediaPlayer.Position / 1000;
+ bytes := BASS_ChannelGetPosition(BASS);
+ Result := BASS_ChannelBytes2Seconds(BASS, bytes);
+end;
+
+function TMusic.Finished: boolean;
+begin
+ Result := false;
+// if ModeStr[MediaPlayer.Mode] = 'Stopped' then Result := true;
+ if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then begin
+// beep;
+ Result := true;
+ end;
+end;
+
+{function myeffect( chan : integer; stream : Pointer; len : integer; udata : Pointer ): Pointer; cdecl;
+var
+ dane: pwordarray;
+ pet: integer;
+ Prev: smallint;
+ PrevNew: smallint;
+begin
+ dane := stream;
+ Prev := 0;
+ for pet := 0 to len div 2 -1 do begin
+ PrevNew := Dane[Pet];
+
+// Dane[pet] := Round(PrevNew*1/8 + Prev*7/8);
+
+ Prev := Dane[Pet];
+ end;
+end;}
+
+procedure TMusic.PlayStart;
+{var
+ Music: PMix_Chunk;}
+begin
+{ Mix_OpenAudio(44100, 16, 1, 16*1024);
+ Music := Mix_LoadWAV('D:\Rozne\UltraStar\Old\Boys - Hej Sokoly 30s.wav');
+ Mix_RegisterEffect(0, myeffect, nil, 0);
+ Mix_PlayChannel(0, Music, 0);}
+
+// MediaPlayerStart.Rewind;
+// MediaPlayerStart.Play;
+ BASS_ChannelPlay(BassStart, True);
+end;
+
+procedure TMusic.PlayBack;
+begin
+// MediaPlayerBack.Rewind;
+// MediaPlayerBack.Play;
+// if not
+ BASS_ChannelPlay(BassBack, True);// then
+// Application.MessageBox ('Error playing stream!', 'Error');
+end;
+
+procedure TMusic.PlaySwoosh;
+begin
+// MediaPlayerSwoosh.Rewind;
+// MediaPlayerSwoosh.Play;
+ BASS_ChannelPlay(BassSwoosh, True);
+end;
+
+procedure TMusic.PlayChange;
+begin
+// MediaPlayerChange.Rewind;
+// MediaPlayerChange.Play;
+ BASS_ChannelPlay(BassChange, True);
+end;
+
+procedure TMusic.PlayOption;
+begin
+// MediaPlayerOption.Rewind;
+// MediaPlayerOption.Play;
+ BASS_ChannelPlay(BassOption, True);
+end;
+
+procedure TMusic.PlayClick;
+begin
+// MediaPlayerClick.Rewind;
+// MediaPlayerClick.Play;
+ BASS_ChannelPlay(BassClick, True);
+end;
+
+procedure TMusic.PlayDrum;
+begin
+// MediaPlayerDrum.Rewind;
+// MediaPlayerDrum.Play;
+ BASS_ChannelPlay(BassDrum, True);
+end;
+
+procedure TMusic.PlayHihat;
+begin
+// MediaPlayerHihat.Rewind;
+// MediaPlayerHihat.Play;
+ BASS_ChannelPlay(BassHihat, True);
+end;
+
+procedure TMusic.PlayClap;
+begin
+// MediaPlayerClap.Rewind;
+// MediaPlayerClap.Play;
+ BASS_ChannelPlay(BassClap, True);
+end;
+
+procedure TMusic.PlayShuffle;
+begin
+// MediaPlayerShuffle.Rewind;
+// MediaPlayerShuffle.Play;
+ BASS_ChannelPlay(BassShuffle, True);
+end;
+
+procedure TMusic.StopShuffle;
+begin
+ BASS_ChannelStop(BassShuffle);
+end;
+
+procedure TMusic.PlayApplause;
+begin
+// MediaPlayerShuffle.Rewind;
+// MediaPlayerShuffle.Play;
+ BASS_ChannelPlay(BassApplause, True);
+end;
+
+procedure TMusic.CaptureStart;
+var
+ S: integer;
+ SC: integer;
+ P1: integer;
+ P2: integer;
+begin
+ for S := 0 to High(Sound) do
+ Sound[S].BufferLong[0].Clear;
+
+{ case PlayersPlay of
+ 1: begin
+ CaptureCard(0, 0, 1, 0);
+ end;
+ 2: begin
+ if Ini.TwoPlayerMode = 0 then begin
+ CaptureCard(0, 0, 1, 2);
+ end else begin
+ CaptureCard(0, 0, 1, 0);
+ CaptureCard(1, 1, 2, 0);
+ end;
+ end;
+ 3: begin
+ CaptureCard(0, 0, 1, 2);
+ CaptureCard(1, 1, 3, 0);
+ end;
+ end; // case}
+
+// CaptureCard(0, 0, 0, 0);
+// end;
+
+ {for SC := 0 to High(SoundCard) do begin
+ P1 := Ini.SoundCard[SC, 1];
+ P2 := Ini.SoundCard[SC, 2];
+ if P1 > PlayersPlay then P1 := 0;
+ if P2 > PlayersPlay then P2 := 0;
+ CaptureCard(SC, P1, P2);
+ end; }
+ // 0.5.2: new
+ 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 TMusic.CaptureStop;
+var
+ SC: integer;
+ P1: integer;
+ P2: integer;
+begin
+{ if RecordSystem = 1 then begin
+ case PlayersPlay of
+ 1: begin
+ StopCard(0);
+ end;
+ 2: begin
+ if Ini.TwoPlayerMode = 0 then begin
+ StopCard(0);
+ end else begin
+ StopCard(0);
+ StopCard(1);
+ end;
+ end;
+ 3: begin
+ StopCard(0);
+ StopCard(1);
+ end;
+ end;
+ end;}
+
+ {for SC := 0 to High(SoundCard) do begin
+ StopCard(SC);
+ end; }
+
+ // 0.5.2
+ 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 TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte);
+procedure TMusic.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
+
+ //SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
+ Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
+
+ {if SoundCard[RecordI].BassRecordStream = 0 then begin
+ Error := BASS_ErrorGetCode;
+
+ ErrorMsg := IntToStr(Error);
+ if Error = BASS_ERROR_INIT then ErrorMsg := 'Not successfully called';
+ if Error = BASS_ERROR_ALREADY then ErrorMsg := 'Recording is already in progress';
+ if Error = BASS_ERROR_NOTAVAIL then ErrorMsg := 'The recording device is not available';
+ if Error = BASS_ERROR_FORMAT then ErrorMsg := 'The specified format is not supported';
+ if Error = BASS_ERROR_MEM then ErrorMsg := 'There is insufficent memory';
+ if Error = BASS_ERROR_UNKNOWN then ErrorMsg := 'Unknown';
+
+ Log.LogError('Error creating record stream [' + IntToStr(RecordI) + ', '
+ + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
+ + ErrorMsg);
+ end; }
+ end;
+end;
+
+procedure TMusic.StopCard(Card: byte);
+begin
+ BASS_RecordSetDevice(Card);
+ BASS_RecordFree;
+end;
+
+function TMusic.LoadPlayerFromFile(var MediaPlayer: TMediaPlayer; Name: string): boolean;
+begin
+ Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadPlayerFromFile');
+ if FileExists(Name) then begin
+ try
+ MediaPlayer := TMediaPlayer.Create( nil );
+ except
+ Log.LogError('Failed to create MediaPlayer', 'LoadPlayerFromFile');
+ end;
+ try
+ MediaPlayer.ParentWindow := fHWND;
+ MediaPlayer.Wait := true;
+ MediaPlayer.FileName := Name;
+ MediaPlayer.DeviceType := dtAutoSelect;
+ MediaPlayer.Display := nil;
+ except
+ Log.LogError('Failed setting MediaPlayer: ' + MediaPlayer.ErrorMessage, 'LoadPlayerFromFile');
+ end;
+ try
+ MediaPlayer.Open;
+ except
+ Log.LogError('Failed to open using MediaPlayer', 'LoadPlayerFromFile');
+ end;
+ end else begin
+ Log.LogError('Sound not found: "' + Name + '"', 'LoadPlayerFromFile');
+ exit;
+ end;
+end;
+
+function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+var
+ L: Integer;
+begin
+ if FileExists(Name) then begin
+ Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadPlayerFromFile');
+ try
+ 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', 'LoadPlayerFromFile');
+ end;
+ end else begin
+ Log.LogError('Sound not found: "' + Name + '"', 'LoadPlayerFromFile');
+ exit;
+ end;
+end;
+
+//Equalizer
+function TMusic.GetFFTData: TFFTData;
+var
+Data: TFFTData;
+begin
+ //Get Channel Data Mono and 256 Values
+ BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512);
+ //Result := Data;
+end;
+
+function TMusic.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 TMusic.PlayCustomSound(const Index: Cardinal);
+begin
+if Index <= High(CustomSounds) then
+ BASS_ChannelPlay(CustomSounds[Index].Handle, True);
+end;
+
+procedure TMusic.EnableVocalRemover;
+begin
+ if DSP_VocalRemover=0 then
+ DSP_VocalRemover := Bass_ChannelSetDSP(Bass, @SBVocalCut16, 0, 0);
+
+end;
+
+procedure TMusic.DisableVocalRemover;
+begin
+ if DSP_VocalRemover<>0 then
+ begin
+ BASS_ChannelRemoveDSP(Bass, DSP_VocalRemover);
+ DSP_VocalRemover := 0;
+ end;
+end;
+
+function TMusic.VocalRemoverActivated(): boolean;
+begin
+ Result := (DSP_VocalRemover <> 0);
+end;
+
+end.
|