aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Game/Code/Classes/UAudio_bass.pas37
-rw-r--r--Game/Code/Classes/UMedia_dummy.pas6
-rw-r--r--Game/Code/Classes/UMusic.pas8
-rw-r--r--Game/Code/Classes/UVisualizer.pas96
-rw-r--r--Game/Code/UltraStar.dpr16
-rw-r--r--Game/Code/lib/projectM/projectM.pas2
6 files changed, 118 insertions, 47 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;
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index 6a1d0013..49ba145d 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -49,9 +49,14 @@ uses
avio in 'lib\ffmpeg\avio.pas',
//swscale in 'lib\ffmpeg\swscale.pas',
+ {$ifdef UseProjectM}
+ projectM in 'lib\projectM\projectM.pas',
+ {$endif}
+
SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
SQLite3 in 'lib\SQLite\SQLite3.pas',
+
//------------------------------
//Includes - Menu System
//------------------------------
@@ -68,7 +73,7 @@ uses
//------------------------------
//Includes - Classes
- //------------------------------
+ //------------------------------
UCommon in 'Classes\UCommon.pas',
UGraphic in 'Classes\UGraphic.pas',
UTexture in 'Classes\UTexture.pas',
@@ -109,9 +114,9 @@ uses
uPluginLoader in 'Classes\uPluginLoader.pas', //New Plugin Loader Module
UParty in 'Classes\UParty.pas', // to - do : rewrite Party Manager as Module, reomplent ability to offer party Mody by Plugin
- UPlatform in 'Classes\UPlatform.pas',
+ UPlatform in 'Classes\UPlatform.pas',
{$IFDEF WIN32}
- UPlatformWindows in 'Classes\UPlatformWindows.pas',
+ UPlatformWindows in 'Classes\UPlatformWindows.pas',
{$ENDIF}
{$IFDEF LINUX}
UPlatformLinux in 'Classes\UPlatformLinux.pas',
@@ -139,8 +144,9 @@ uses
UAudio_FFMpeg in 'Classes\UAudio_FFMpeg.pas',
{$endif}
- projectM in 'lib\projectM\projectM.pas',
- UVisualizer in 'Classes\UVisualizer.pas',
+{$IFDEF UseProjectM}
+ UVisualizer in 'Classes\UVisualizer.pas',
+{$ENDIF}
//------------------------------
//Includes - Screens
diff --git a/Game/Code/lib/projectM/projectM.pas b/Game/Code/lib/projectM/projectM.pas
index 72fb0b92..be6f77b1 100644
--- a/Game/Code/lib/projectM/projectM.pas
+++ b/Game/Code/lib/projectM/projectM.pas
@@ -344,8 +344,8 @@ type
procedure addPCMfloat(PCMdata: PFLOAT, samples: INT);
}
procedure addPCM16(pcm_data: TPCM16); cdecl; external 'libprojectM.dll';
+ procedure addPCM16Data(pcm_data: PSmallint; samples: Smallint); cdecl; external 'libprojectM.dll';
{
- procedure addPCM16Data(const short* pcm_data, short samples);
procedure addPCM8( unsigned char [2][512]);
}