From 30e17a410222b363fd49af7bf500987a18b621cc Mon Sep 17 00:00:00 2001 From: tobigun Date: Thu, 6 Mar 2008 17:12:35 +0000 Subject: bug-fix: there was a Floating-Point exception when calling WindowFunc(). This was caused by a multiplication with -NaN. The NaN value was in the in_-array because it was not zero'ed properly (sorry, my fault). The problem was fixed by replacing GetMem with AllocMem. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@924 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UAudioPlayback_SoftMixer.pas | 95 +++++++++++++++++--------- 1 file changed, 63 insertions(+), 32 deletions(-) (limited to 'Game') diff --git a/Game/Code/Classes/UAudioPlayback_SoftMixer.pas b/Game/Code/Classes/UAudioPlayback_SoftMixer.pas index 5beff682..29983778 100644 --- a/Game/Code/Classes/UAudioPlayback_SoftMixer.pas +++ b/Game/Code/Classes/UAudioPlayback_SoftMixer.pas @@ -67,6 +67,7 @@ type procedure SetPosition(Time: real); function ReadData(Buffer: PChar; BufSize: integer): integer; + function GetPCMData(var data: TPCMData): Cardinal; procedure GetFFTData(var data: TFFTData); end; @@ -115,7 +116,7 @@ type procedure SetVolume(Volume: integer); procedure SetMusicVolume(Volume: integer); procedure SetLoop(Enabled: boolean); - function Open(Filename: string): boolean; // true if succeed + function Open(const Filename: string): boolean; // true if succeed procedure Rewind; procedure SetPosition(Time: real); procedure Play; @@ -566,6 +567,55 @@ begin Result := BufSize - BytesNeeded; end; +(* TODO: libsamplerate support +function TSoftMixerPlaybackStream.ReadData(Buffer: PChar; BufSize: integer): integer; +var + convState: PSRC_STATE; + convData: SRC_DATA; + error: integer; +begin + // Note: needs mono->stereo conversion, multi-channel->stereo, etc. + // maybe we should use SDL for the channel-conversion stuff + // and use libsamplerate afterwards for the frequency-conversion + + //convState := src_new(SRC_SINC_MEDIUM_QUALITY, 2, @error); + //src_short_to_float_array(input, output, len); + convData. + if (src_process(convState, @convData) <> 0) then + begin + Log.LogError(src_strerror(src_error(convState)), 'TSoftMixerPlaybackStream.ReadData'); + Exit; + end; + src_float_to_short_array(); + //src_delete(convState); +end; +*) + +function TSoftMixerPlaybackStream.GetPCMData(var data: TPCMData): Cardinal; +var size: integer; +begin + Result := 0; +(* + // just SInt16 stereo support for now + if ((Engine.GetAudioFormatInfo().Format <> asfS16) or + (Engine.GetAudioFormatInfo().Channels <> 2)) then + begin + Exit; + end; + + // zero memory + FillChar(data, SizeOf(data), 0); + + Lock(); + Result := Min(SizeOf(data), SampleBufferCount); + if (Result > 0) then + begin + Move(SampleBuffer[0], data[0], Result); + end; + Unlock(); +*) +end; + procedure TSoftMixerPlaybackStream.GetFFTData(var data: TFFTData); var i: integer; @@ -576,12 +626,14 @@ begin // only works with SInt16 and Float values at the moment AudioFormat := Engine.GetAudioFormatInfo(); - GetMem(DataIn, FFTSize * SizeOf(Single)); + DataIn := AllocMem(FFTSize * SizeOf(Single)); + if (DataIn = nil) then + Exit; Lock(); - // FIXME: We just use the first Frames frames, the others are ignored. + // TODO: We just use the first Frames frames, the others are ignored. // This is OK for the equalizer display but not if we want to use - // this function for voice-analysis. + // this function for voice-analysis someday (I don't think we want). Frames := Min(FFTSize, SampleBufferCount div AudioFormat.FrameSize); // use only first channel and convert data to float-values case AudioFormat.Format of @@ -598,7 +650,7 @@ begin end; Unlock(); - WindowFunc(FFTSize, DataIn); + WindowFunc(fwfHanning, FFTSize, DataIn); PowerSpectrum(FFTSize, DataIn, @data); FreeMem(DataIn); @@ -610,30 +662,6 @@ begin end; end; -(* TODO: libsamplerate support -function TSoftMixerPlaybackStream.ReadData(Buffer: PChar; BufSize: integer): integer; -var - convState: PSRC_STATE; - convData: SRC_DATA; - error: integer; -begin - // Note: needs mono->stereo conversion, multi-channel->stereo, etc. - // maybe we should use SDL for the channel-conversion stuff - // and use libsamplerate afterwards for the frequency-conversion - - //convState := src_new(SRC_SINC_MEDIUM_QUALITY, 2, @error); - //src_short_to_float_array(input, output, len); - convData. - if (src_process(convState, @convData) <> 0) then - begin - Log.LogError(src_strerror(src_error(convState)), 'TSoftMixerPlaybackStream.ReadData'); - Exit; - end; - src_float_to_short_array(); - //src_delete(convState); -end; -*) - function TSoftMixerPlaybackStream.GetPosition: real; begin if assigned(DecodeStream) then @@ -749,7 +777,7 @@ begin MusicStream.SetLoop(Enabled); end; -function TAudioPlayback_SoftMixer.Open(Filename: string): boolean; +function TAudioPlayback_SoftMixer.Open(const Filename: string): boolean; var decodeStream: TAudioDecodeStream; begin @@ -839,12 +867,15 @@ end; // Interface for Visualizer function TAudioPlayback_SoftMixer.GetPCMData(var data: TPCMData): Cardinal; begin - result := 0; + if assigned(MusicStream) then + Result := MusicStream.GetPCMData(data) + else + Result := 0; end; function TAudioPlayback_SoftMixer.OpenSound(const Filename: String): TAudioPlaybackStream; begin - result := Load(Filename); + Result := Load(Filename); end; procedure TAudioPlayback_SoftMixer.PlaySound(stream: TAudioPlaybackStream); -- cgit v1.2.3