From 30e17a410222b363fd49af7bf500987a18b621cc Mon Sep 17 00:00:00 2001
From: tobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>
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