diff options
Diffstat (limited to '')
-rw-r--r-- | Game/Code/Classes/UAudio_bass.pas | 37 | ||||
-rw-r--r-- | Game/Code/Classes/UMedia_dummy.pas | 6 | ||||
-rw-r--r-- | Game/Code/Classes/UMusic.pas | 8 | ||||
-rw-r--r-- | Game/Code/Classes/UVisualizer.pas | 96 |
4 files changed, 106 insertions, 41 deletions
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;
|