From 27ca028ea19879bb3b109c58bae86b61e60b3370 Mon Sep 17 00:00:00 2001 From: tobigun Date: Thu, 6 Dec 2007 10:40:15 +0000 Subject: Visualizer changes (audio connection, some opengl fixes) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@679 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UAudio_bass.pas | 37 +++++++++++++++ Game/Code/Classes/UMedia_dummy.pas | 6 +++ Game/Code/Classes/UMusic.pas | 8 +++- Game/Code/Classes/UVisualizer.pas | 96 ++++++++++++++++++++++---------------- 4 files changed, 106 insertions(+), 41 deletions(-) (limited to 'Game/Code/Classes') diff --git a/Game/Code/Classes/UAudio_bass.pas b/Game/Code/Classes/UAudio_bass.pas index bcf01f92..69278cca 100644 --- a/Game/Code/Classes/UAudio_bass.pas +++ b/Game/Code/Classes/UAudio_bass.pas @@ -100,6 +100,9 @@ type //Equalizer function GetFFTData: TFFTData; + // Interface for Visualizer + function GetPCMData(var data: TPCMData): Cardinal; + //Custom Sounds function LoadCustomSound(const Filename: String): Cardinal; procedure PlayCustomSound(const Index: Cardinal ); @@ -384,6 +387,40 @@ begin BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); end; +{* + * Copies interleaved PCM 16bit uint (maybe fake) stereo samples into data. + * Returns the number of frames (= stereo/mono sample) + *} +function TAudio_bass.GetPCMData(var data: TPCMData): Cardinal; +var + info: BASS_CHANNELINFO; + nBytes: DWORD; +begin + //Get Channel Data Mono and 256 Values + BASS_ChannelGetInfo(Bass, info); + ZeroMemory(@data, sizeof(TPCMData)); + + if (info.chans = 1) then + begin + // mono file -> add stereo channel + { + nBytes := 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(Bass, @data, sizeof(TPCMData)); + end; + if(nBytes <= 0) then + result := 0 + else + result := nBytes div sizeof(TPCMStereoSample); +end; + function TAudio_bass.LoadCustomSound(const Filename: String): Cardinal; var S: hStream; diff --git a/Game/Code/Classes/UMedia_dummy.pas b/Game/Code/Classes/UMedia_dummy.pas index 630b497e..c5fb799c 100644 --- a/Game/Code/Classes/UMedia_dummy.pas +++ b/Game/Code/Classes/UMedia_dummy.pas @@ -57,6 +57,7 @@ type procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); procedure StopCard(Card: byte); function GetFFTData: TFFTData; + function GetPCMData(var data: TPCMData): Cardinal; // IAudioPlayback procedure InitializePlayback; @@ -167,6 +168,11 @@ function Tmedia_dummy.GetFFTData: TFFTData; begin end; +function Tmedia_dummy.GetPCMData(var data: TPCMData): Cardinal; +begin + result := 0; +end; + // IAudioPlayback procedure Tmedia_dummy.InitializePlayback; begin diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index 18ec2944..4acbb55a 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -83,7 +83,10 @@ type Source: array of string; end; - TFFTData = array [0..256] of Single; + TFFTData = array[0..256] of Single; + + TPCMStereoSample = array[0..1] of Smallint; + TPCMData = array[0..511] of TPCMStereoSample; hStream = Cardinal; @@ -165,6 +168,9 @@ type //Equalizer function GetFFTData: TFFTData; + + // Interface for Visualizer + function GetPCMData(var data: TPCMData): Cardinal; end; IAudioInput = Interface diff --git a/Game/Code/Classes/UVisualizer.pas b/Game/Code/Classes/UVisualizer.pas index 1905358f..0f2334ba 100644 --- a/Game/Code/Classes/UVisualizer.pas +++ b/Game/Code/Classes/UVisualizer.pas @@ -30,16 +30,19 @@ uses SDL, implementation +uses + UGraphic; + var singleton_VideoProjectM : IVideoPlayback; const - VisualWidth = 800; // 640 - VisualHeight = 600; // 480 gx = 32; gy = 24; fps = 30; texsize = 512; + visuals_Dir = 'Visuals'; // TODO: move this to a place common for all visualizers + projectM_Dir = visuals_Dir+'/projectM'; type TVideoPlayback_ProjectM = class( TInterfacedObject, IVideoPlayback ) @@ -50,7 +53,7 @@ type VisualizerPaused : Boolean; VisualTex : glUint; - pcm_data : TPCM16; + PCMData : TPCMData; hRC : Integer; hDC : Integer; @@ -140,7 +143,6 @@ end; procedure TVideoPlayback_ProjectM.VisualizerStart; begin -//exit; VisualizerStarted := True; New(pm); @@ -153,8 +155,8 @@ begin pm^.fps := fps; pm^.renderTarget^.usePbuffers := 0; - pm^.fontURL := PChar('Visuals\fonts'); - pm^.presetURL := PChar('Visuals\presets'); + pm^.fontURL := PChar(projectM_Dir+'/fonts'); + pm^.presetURL := PChar(projectM_Dir+'/presets'); glPushAttrib(GL_ALL_ATTRIB_BITS); projectM_init(pm); @@ -164,7 +166,9 @@ begin glPushMatrix(); glMatrixMode(GL_TEXTURE); glPushMatrix(); - projectM_resetGL(pm, VisualWidth, VisualHeight); + + projectM_resetGL(pm, ScreenW, ScreenH); + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -191,21 +195,16 @@ end; procedure TVideoPlayback_ProjectM.GetFrame(Time: Extended); var i: integer; + nSamples: cardinal; begin -// exit; - if not VisualizerStarted then Exit; if VisualizerPaused then Exit; - Randomize(); - - for i := 0 to 511 do - begin - pcm_data[0][i] := RandomRange(High(Smallint), Low(Smallint)); - pcm_data[1][i] := pcm_data[0][i]; - end; - addPCM16(pcm_data); + // get audio data + nSamples := AudioPlayback.GetPCMData(PcmData); + addPCM16Data(PSmallInt(@PcmData), nSamples); + // store OpenGL state (might be messed up otherwise) glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -213,12 +212,17 @@ begin glPushMatrix(); glMatrixMode(GL_TEXTURE); glPushMatrix(); + + // let projectM render a frame renderFrame(pm); glFlush(); - { + + {$IFDEF UseTexture} glBindTexture(GL_TEXTURE_2D, VisualTex); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, VisualWidth, VisualHeight, 0); - } + {$ENDIF} + + // restore USDX OpenGL state glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -227,41 +231,45 @@ begin glPopMatrix(); glPopAttrib(); + // discard projectM's depth buffer information (avoid overlay) glClear(GL_DEPTH_BUFFER_BIT); - - { - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - - glEnable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glBindTexture(GL_TEXTURE_2D, VisualTex); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(-1, -1); - glTexCoord2f(1, 0); glVertex2f( 1, -1); - glTexCoord2f(1, 1); glVertex2f( 1, 1); - glTexCoord2f(0, 1); glVertex2f(-1, 1); - glEnd(); - glDisable(GL_TEXTURE_2D); - } end; procedure TVideoPlayback_ProjectM.DrawGL(Screen: integer); begin - - exit; - + {$IFDEF UseTexture} // have a nice black background to draw on (even if there were errors opening the vid) if Screen=1 then begin - glClearColor(0,0,0,0); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); end; // exit if there's nothing to draw if not VisualizerStarted then Exit; - glEnable(GL_TEXTURE_2D); + // setup display + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 1, 0, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glEnable(GL_BLEND); - glColor4f(1, 1, 1, 1); + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, VisualTex); + glColor4f(1, 1, 1, 1); + + // draw projectM frame + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(0, 0); + glTexCoord2f(1, 0); glVertex2f(1, 0); + glTexCoord2f(1, 1); glVertex2f(1, 1); + glTexCoord2f(0, 1); glVertex2f(0, 1); + glEnd(); + + { glbegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(400-VisualWidth/2, 300-VisualHeight/2); @@ -272,9 +280,17 @@ begin glTexCoord2f(1, 0); glVertex2f(400+VisualWidth/2, 300-VisualHeight/2); glEnd; + } + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); + // restore state + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + {$ENDIF} end; -- cgit v1.2.3