aboutsummaryrefslogtreecommitdiffstats
path: root/src/media
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-21 18:27:36 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-21 18:27:36 +0000
commit868ce765441473e7d1fec9b3ad22a707f121a637 (patch)
tree8f67a0e6ff2c306603ef37ec0bc8cc0e042eb5d2 /src/media
parent62c665cb863914c2d5e07bf4b8bd07c1c45be7ac (diff)
downloadusdx-868ce765441473e7d1fec9b3ad22a707f121a637.tar.gz
usdx-868ce765441473e7d1fec9b3ad22a707f121a637.tar.xz
usdx-868ce765441473e7d1fec9b3ad22a707f121a637.zip
- add video loop option
- allow multiple instances of a video git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2260 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'src/media')
-rw-r--r--src/media/UMedia_dummy.pas200
-rw-r--r--src/media/UVideo.pas162
-rw-r--r--src/media/UVisualizer.pas230
3 files changed, 378 insertions, 214 deletions
diff --git a/src/media/UMedia_dummy.pas b/src/media/UMedia_dummy.pas
index 25e94724..35b8bd70 100644
--- a/src/media/UMedia_dummy.pas
+++ b/src/media/UMedia_dummy.pas
@@ -42,17 +42,17 @@ uses
UPath;
type
- TMedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput )
+ TAudio_Dummy = class( TInterfacedObject, IAudioPlayback, IAudioInput )
private
DummyOutputDeviceList: TAudioOutputDeviceList;
public
constructor Create();
- function GetName: string;
+ function GetName: string;
function Init(): boolean;
function Finalize(): boolean;
- function Open(const aFileName: IPath): boolean; // true if succeed
+ function Open(const aFileName: IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -64,9 +64,6 @@ type
procedure SetSyncSource(SyncSource: TSyncSource);
- procedure GetFrame(Time: Extended);
- procedure DrawGL(Screen: integer);
-
// IAudioInput
function InitializeRecord: boolean;
function FinalizeRecord: boolean;
@@ -83,9 +80,11 @@ type
procedure FadeIn(Time: real; TargetVolume: single);
procedure SetAppVolume(Volume: single);
procedure SetVolume(Volume: single);
- procedure SetLoop(Enabled: boolean);
procedure Rewind;
+ procedure SetLoop(Enabled: boolean);
+ function GetLoop(): boolean;
+
function Finished: boolean;
function Length: real;
@@ -98,98 +97,122 @@ type
procedure CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
end;
-function TMedia_dummy.GetName: string;
-begin
- Result := 'dummy';
-end;
+ TVideo_Dummy = class( TInterfacedObject, IVideo )
+ public
+ procedure Close;
-procedure TMedia_dummy.GetFrame(Time: Extended);
-begin
-end;
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetLoop(Enable: boolean);
+ function GetLoop(): boolean;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+
+ property Loop: boolean read GetLoop write SetLoop;
+ property Position: real read GetPosition write SetPosition;
+ end;
-procedure TMedia_dummy.DrawGL(Screen: integer);
+ TVideoPlayback_Dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization )
+ public
+ constructor Create();
+ function GetName: string;
+
+ function Init(): boolean;
+ function Finalize(): boolean;
+
+ function Open(const FileName: IPath): IVideo;
+ end;
+
+function TAudio_Dummy.GetName: string;
begin
+ Result := 'AudioDummy';
end;
-constructor TMedia_dummy.Create();
+constructor TAudio_Dummy.Create();
begin
inherited;
end;
-function TMedia_dummy.Init(): boolean;
+function TAudio_Dummy.Init(): boolean;
begin
Result := true;
end;
-function TMedia_dummy.Finalize(): boolean;
+function TAudio_Dummy.Finalize(): boolean;
begin
Result := true;
end;
-function TMedia_dummy.Open(const aFileName : IPath): boolean; // true if succeed
+function TAudio_Dummy.Open(const aFileName : IPath): boolean; // true if succeed
begin
Result := false;
end;
-procedure TMedia_dummy.Close;
+procedure TAudio_Dummy.Close;
begin
end;
-procedure TMedia_dummy.Play;
+procedure TAudio_Dummy.Play;
begin
end;
-procedure TMedia_dummy.Pause;
+procedure TAudio_Dummy.Pause;
begin
end;
-procedure TMedia_dummy.Stop;
+procedure TAudio_Dummy.Stop;
begin
end;
-procedure TMedia_dummy.SetPosition(Time: real);
+procedure TAudio_Dummy.SetPosition(Time: real);
begin
end;
-function TMedia_dummy.GetPosition: real;
+function TAudio_Dummy.GetPosition: real;
begin
Result := 0;
end;
-procedure TMedia_dummy.SetSyncSource(SyncSource: TSyncSource);
+procedure TAudio_Dummy.SetSyncSource(SyncSource: TSyncSource);
begin
end;
// IAudioInput
-function TMedia_dummy.InitializeRecord: boolean;
+function TAudio_Dummy.InitializeRecord: boolean;
begin
Result := true;
end;
-function TMedia_dummy.FinalizeRecord: boolean;
+function TAudio_Dummy.FinalizeRecord: boolean;
begin
Result := true;
end;
-procedure TMedia_dummy.CaptureStart;
+procedure TAudio_Dummy.CaptureStart;
begin
end;
-procedure TMedia_dummy.CaptureStop;
+procedure TAudio_Dummy.CaptureStop;
begin
end;
-procedure TMedia_dummy.GetFFTData(var data: TFFTData);
+procedure TAudio_Dummy.GetFFTData(var data: TFFTData);
begin
end;
-function TMedia_dummy.GetPCMData(var data: TPCMData): Cardinal;
+function TAudio_Dummy.GetPCMData(var data: TPCMData): Cardinal;
begin
Result := 0;
end;
// IAudioPlayback
-function TMedia_dummy.InitializePlayback: boolean;
+function TAudio_Dummy.InitializePlayback: boolean;
begin
SetLength(DummyOutputDeviceList, 1);
DummyOutputDeviceList[0] := TAudioOutputDevice.Create();
@@ -197,73 +220,152 @@ begin
Result := true;
end;
-function TMedia_dummy.FinalizePlayback: boolean;
+function TAudio_Dummy.FinalizePlayback: boolean;
begin
Result := true;
end;
-function TMedia_dummy.GetOutputDeviceList(): TAudioOutputDeviceList;
+function TAudio_Dummy.GetOutputDeviceList(): TAudioOutputDeviceList;
begin
Result := DummyOutputDeviceList;
end;
-procedure TMedia_dummy.SetAppVolume(Volume: single);
+procedure TAudio_Dummy.SetAppVolume(Volume: single);
+begin
+end;
+
+procedure TAudio_Dummy.SetVolume(Volume: single);
begin
end;
-procedure TMedia_dummy.SetVolume(Volume: single);
+procedure TAudio_Dummy.SetLoop(Enabled: boolean);
begin
end;
-procedure TMedia_dummy.SetLoop(Enabled: boolean);
+function TAudio_Dummy.GetLoop(): boolean;
begin
+ Result := false;
end;
-procedure TMedia_dummy.FadeIn(Time: real; TargetVolume: single);
+procedure TAudio_Dummy.FadeIn(Time: real; TargetVolume: single);
begin
end;
-procedure TMedia_dummy.Rewind;
+procedure TAudio_Dummy.Rewind;
begin
end;
-function TMedia_dummy.Finished: boolean;
+function TAudio_Dummy.Finished: boolean;
begin
Result := false;
end;
-function TMedia_dummy.Length: real;
+function TAudio_Dummy.Length: real;
begin
Result := 60;
end;
-function TMedia_dummy.OpenSound(const Filename: IPath): TAudioPlaybackStream;
+function TAudio_Dummy.OpenSound(const Filename: IPath): TAudioPlaybackStream;
begin
Result := nil;
end;
-procedure TMedia_dummy.CloseSound(var PlaybackStream: TAudioPlaybackStream);
+procedure TAudio_Dummy.CloseSound(var PlaybackStream: TAudioPlaybackStream);
begin
end;
-procedure TMedia_dummy.PlaySound(stream: TAudioPlaybackStream);
+procedure TAudio_Dummy.PlaySound(stream: TAudioPlaybackStream);
begin
end;
-procedure TMedia_dummy.StopSound(stream: TAudioPlaybackStream);
+procedure TAudio_Dummy.StopSound(stream: TAudioPlaybackStream);
begin
end;
-function TMedia_dummy.CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+function TAudio_Dummy.CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
begin
Result := nil;
end;
-procedure TMedia_dummy.CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
+procedure TAudio_Dummy.CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
+begin
+end;
+
+
+{ TVideoPlayback_Dummy }
+
+procedure TVideo_Dummy.Close;
begin
end;
+procedure TVideo_Dummy.Play;
+begin
+end;
+
+procedure TVideo_Dummy.Pause;
+begin
+end;
+
+procedure TVideo_Dummy.Stop;
+begin
+end;
+
+procedure TVideo_Dummy.SetLoop(Enable: boolean);
+begin
+end;
+
+function TVideo_Dummy.GetLoop(): boolean;
+begin
+ Result := false;
+end;
+
+procedure TVideo_Dummy.SetPosition(Time: real);
+begin
+end;
+
+function TVideo_Dummy.GetPosition: real;
+begin
+ Result := 0;
+end;
+
+procedure TVideo_Dummy.GetFrame(Time: Extended);
+begin
+end;
+
+procedure TVideo_Dummy.DrawGL(Screen: integer);
+begin
+end;
+
+
+{ TVideoPlayback_Dummy }
+
+constructor TVideoPlayback_Dummy.Create();
+begin
+end;
+
+function TVideoPlayback_Dummy.GetName: string;
+begin
+ Result := 'VideoDummy';
+end;
+
+function TVideoPlayback_Dummy.Init(): boolean;
+begin
+ Result := true;
+end;
+
+function TVideoPlayback_Dummy.Finalize(): boolean;
+begin
+ Result := true;
+end;
+
+function TVideoPlayback_Dummy.Open(const FileName: IPath): IVideo;
+begin
+ Result := TVideo_Dummy.Create;
+end;
+
+
initialization
- MediaManager.Add(TMedia_dummy.Create);
+ MediaManager.Add(TAudio_Dummy.Create);
+ MediaManager.Add(TVideoPlayback_Dummy.Create);
end.
diff --git a/src/media/UVideo.pas b/src/media/UVideo.pas
index 27f29f7e..fd3c7e2a 100644
--- a/src/media/UVideo.pas
+++ b/src/media/UVideo.pas
@@ -107,11 +107,15 @@ type
Upper, Lower: double;
end;
- TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback )
+ IVideo_FFmpeg = interface (IVideo)
+ ['{E640E130-C8C0-4399-AF02-67A3569313AB}']
+ function Open(const FileName: IPath): boolean;
+ end;
+
+ TVideo_FFmpeg = class( TInterfacedObject, IVideo_FFmpeg )
private
fOpened: boolean; //**< stream successfully opened
fPaused: boolean; //**< stream paused
- fInitialized: boolean;
fEOF: boolean; //**< end-of-file state
fLoop: boolean; //**< looping enabled
@@ -150,23 +154,37 @@ type
procedure ShowDebugInfo();
public
- function GetName: String;
+ constructor Create;
+ destructor Destroy; override;
+
+ function Open(const FileName: IPath): boolean;
+ procedure Close;
- function Init(): boolean;
- function Finalize: boolean;
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetLoop(Enable: boolean);
+ function GetLoop(): boolean;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+ end;
- function Open(const FileName : IPath): boolean; // true if succeed
- procedure Close;
+ TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback )
+ private
+ fInitialized: boolean;
- procedure Play;
- procedure Pause;
- procedure Stop;
+ public
+ function GetName: String;
- procedure SetPosition(Time: real);
- function GetPosition: real;
+ function Init(): boolean;
+ function Finalize: boolean;
- procedure GetFrame(Time: Extended);
- procedure DrawGL(Screen: integer);
+ function Open(const FileName : IPath): IVideo;
end;
var
@@ -219,47 +237,46 @@ begin
FFmpegCore := TMediaCore_FFmpeg.GetInstance();
- Reset();
av_register_all();
- glGenTextures(1, PGLuint(@fFrameTex));
end;
function TVideoPlayback_FFmpeg.Finalize(): boolean;
begin
- Close();
- glDeleteTextures(1, PGLuint(@fFrameTex));
Result := true;
end;
-procedure TVideoPlayback_FFmpeg.Reset();
+function TVideoPlayback_FFmpeg.Open(const FileName : IPath): IVideo;
+var
+ Video: IVideo_FFmpeg;
begin
- // close previously opened video
- Close();
+ Video := TVideo_FFmpeg.Create;
+ if Video.Open(FileName) then
+ Result := Video
+ else
+ Result := nil;
+end;
- fOpened := False;
- fPaused := False;
- fTimeBase := 0;
- fTime := 0;
- fStream := nil;
- fStreamIndex := -1;
- fFrameTexValid := false;
- fEOF := false;
+{* TVideo_FFmpeg *}
- // TODO: do we really want this by default?
- fLoop := true;
- fLoopTime := 0;
+constructor TVideo_FFmpeg.Create;
+begin
+ glGenTextures(1, PGLuint(@fFrameTex));
+ Reset();
+end;
- fAspectCorrection := acoCrop;
+destructor TVideo_FFmpeg.Destroy;
+begin
+ Close();
+ glDeleteTextures(1, PGLuint(@fFrameTex));
end;
-function TVideoPlayback_FFmpeg.Open(const FileName : IPath): boolean; // true if succeed
+function TVideo_FFmpeg.Open(const FileName : IPath): boolean;
var
errnum: Integer;
AudioStreamIndex: integer;
begin
Result := false;
-
Reset();
// use custom 'ufile' protocol for UTF-8 support
@@ -408,6 +425,7 @@ begin
end;
{$ENDIF}
+
fTexWidth := Round(Power(2, Ceil(Log2(fCodecContext^.width))));
fTexHeight := Round(Power(2, Ceil(Log2(fCodecContext^.height))));
@@ -420,11 +438,32 @@ begin
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- fOpened := True;
+ fOpened := true;
Result := true;
end;
-procedure TVideoPlayback_FFmpeg.Close;
+procedure TVideo_FFmpeg.Reset();
+begin
+ // close previously opened video
+ Close();
+
+ fOpened := False;
+ fPaused := False;
+ fTimeBase := 0;
+ fTime := 0;
+ fStream := nil;
+ fStreamIndex := -1;
+ fFrameTexValid := false;
+
+ fEOF := false;
+
+ fLoop := false;
+ fLoopTime := 0;
+
+ fAspectCorrection := acoCrop;
+end;
+
+procedure TVideo_FFmpeg.Close;
begin
if (fFrameBuffer <> nil) then
av_free(fFrameBuffer);
@@ -457,7 +496,7 @@ begin
fOpened := False;
end;
-procedure TVideoPlayback_FFmpeg.SynchronizeTime(Frame: PAVFrame; var pts: double);
+procedure TVideo_FFmpeg.SynchronizeTime(Frame: PAVFrame; var pts: double);
var
FrameDelay: double;
begin
@@ -484,7 +523,7 @@ end;
* @param pts will be updated to the presentation time of the decoded frame.
* returns true if a frame could be decoded. False if an error or EOF occured.
*}
-function TVideoPlayback_FFmpeg.DecodeFrame(): boolean;
+function TVideo_FFmpeg.DecodeFrame(): boolean;
var
FrameFinished: Integer;
VideoPktPts: int64;
@@ -522,7 +561,10 @@ begin
// check for errors
if (url_ferror(pbIOCtx) <> 0) then
+ begin
+ Log.LogError('Video decoding file error', 'TVideoPlayback_FFmpeg.DecodeFrame');
Exit;
+ end;
// url_feof() does not detect an EOF for some mov-files (e.g. deluxe.mov)
// so we have to do it this way.
@@ -533,18 +575,9 @@ begin
Exit;
end;
- // no error -> wait for user input
-{
- SDL_Delay(100); // initial version, left for documentation
- continue;
-}
-
- // Patch by Hawkear:
- // Why should this function loop in an endless loop if there is an error?
- // This runs in the main thread, so it halts the whole program
- // Therefore, it is better to exit when an error occurs
+ // error occured, log and exit
+ Log.LogError('Video decoding error', 'TVideoPlayback_FFmpeg.DecodeFrame');
Exit;
-
end;
// if we got a packet from the video stream, then decode it
@@ -593,7 +626,7 @@ begin
Result := true;
end;
-procedure TVideoPlayback_FFmpeg.GetFrame(Time: Extended);
+procedure TVideo_FFmpeg.GetFrame(Time: Extended);
var
errnum: Integer;
NewTime: Extended;
@@ -749,7 +782,7 @@ begin
{$ENDIF}
end;
-procedure TVideoPlayback_FFmpeg.GetVideoRect(var ScreenRect, TexRect: TRectCoords);
+procedure TVideo_FFmpeg.GetVideoRect(var ScreenRect, TexRect: TRectCoords);
var
ScreenAspect: double; // aspect of screen resolution
ScaledVideoWidth, ScaledVideoHeight: double;
@@ -799,7 +832,7 @@ begin
TexRect.Lower := fCodecContext^.height / fTexHeight;
end;
-procedure TVideoPlayback_FFmpeg.DrawGL(Screen: integer);
+procedure TVideo_FFmpeg.DrawGL(Screen: integer);
var
ScreenRect: TRectCoords;
TexRect: TRectCoords;
@@ -862,7 +895,7 @@ begin
{$IFEND}
end;
-procedure TVideoPlayback_FFmpeg.ShowDebugInfo();
+procedure TVideo_FFmpeg.ShowDebugInfo();
begin
{$IFDEF Info}
if (fTime+fTimeBase < 0) then
@@ -899,17 +932,28 @@ begin
{$ENDIF}
end;
-procedure TVideoPlayback_FFmpeg.Play;
+procedure TVideo_FFmpeg.Play;
begin
end;
-procedure TVideoPlayback_FFmpeg.Pause;
+procedure TVideo_FFmpeg.Pause;
begin
fPaused := not fPaused;
end;
-procedure TVideoPlayback_FFmpeg.Stop;
+procedure TVideo_FFmpeg.Stop;
+begin
+end;
+
+procedure TVideo_FFmpeg.SetLoop(Enable: boolean);
+begin
+ fLoop := Enable;
+ fLoopTime := 0;
+end;
+
+function TVideo_FFmpeg.GetLoop(): boolean;
begin
+ Result := fLoop;
end;
{**
@@ -920,7 +964,7 @@ end;
* actual frame time when GetFrame() is called the next time.
* @param Time new position in seconds
*}
-procedure TVideoPlayback_FFmpeg.SetPosition(Time: real);
+procedure TVideo_FFmpeg.SetPosition(Time: real);
var
SeekFlags: integer;
begin
@@ -955,7 +999,7 @@ begin
avcodec_flush_buffers(fCodecContext);
end;
-function TVideoPlayback_FFmpeg.GetPosition: real;
+function TVideo_FFmpeg.GetPosition: real;
begin
Result := fTime;
end;
diff --git a/src/media/UVisualizer.pas b/src/media/UVisualizer.pas
index b25d68a9..4f553521 100644
--- a/src/media/UVisualizer.pas
+++ b/src/media/UVisualizer.pas
@@ -60,12 +60,17 @@ interface
{$I switches.inc}
+{.$DEFINE UseTexture}
+
uses
SDL,
UGraphicClasses,
textgl,
math,
gl,
+ {$IFDEF UseTexture}
+ glu,
+ {$ENDIF}
SysUtils,
UIni,
projectM,
@@ -91,31 +96,29 @@ const
{$IFEND}
type
+ TProjectMState = ( pmPlay, pmStop, pmPause );
+
+type
TGLMatrix = array[0..3, 0..3] of GLdouble;
TGLMatrixStack = array of TGLMatrix;
type
- TVideoPlayback_ProjectM = class( TInterfacedObject, IVideoPlayback, IVideoVisualization )
+ TVideo_ProjectM = class( TInterfacedObject, IVideo )
private
- pm: TProjectM;
- ProjectMPath : string;
- Initialized: boolean;
-
- VisualizerStarted: boolean;
- VisualizerPaused: boolean;
+ fPm: TProjectM;
+ fProjectMPath : string;
- VisualTex: GLuint;
- PCMData: TPCMData;
- RndPCMcount: integer;
+ fState: TProjectMState;
- ModelviewMatrixStack: TGLMatrixStack;
- ProjectionMatrixStack: TGLMatrixStack;
- TextureMatrixStack: TGLMatrixStack;
+ fVisualTex: GLuint;
+ fPCMData: TPCMData;
+ fRndPCMcount: integer;
- procedure VisualizerStart;
- procedure VisualizerStop;
+ fModelviewMatrixStack: TGLMatrixStack;
+ fProjectionMatrixStack: TGLMatrixStack;
+ fTextureMatrixStack: TGLMatrixStack;
- procedure VisualizerTogglePause;
+ procedure InitProjectM;
function GetRandomPCMData(var Data: TPCMData): Cardinal;
@@ -126,12 +129,9 @@ type
procedure RestoreOpenGLState();
public
- function GetName: String;
+ constructor Create;
+ destructor Destroy; override;
- function Init(): boolean;
- function Finalize(): boolean;
-
- function Open(const aFileName: IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -141,10 +141,28 @@ type
procedure SetPosition(Time: real);
function GetPosition: real;
+ procedure SetLoop(Enable: boolean);
+ function GetLoop(): boolean;
+
procedure GetFrame(Time: Extended);
procedure DrawGL(Screen: integer);
end;
+ TVideoPlayback_ProjectM = class( TInterfacedObject, IVideoVisualization )
+ private
+ fInitialized: boolean;
+
+ public
+ function GetName: String;
+
+ function Init(): boolean;
+ function Finalize(): boolean;
+
+ function Open(const aFileName: IPath): IVideo;
+ end;
+
+
+{ TVideoPlayback_ProjectM }
function TVideoPlayback_ProjectM.GetName: String;
begin
@@ -154,76 +172,100 @@ end;
function TVideoPlayback_ProjectM.Init(): boolean;
begin
Result := true;
-
- if (Initialized) then
+ if (fInitialized) then
Exit;
- Initialized := true;
+ fInitialized := true;
+end;
- RndPCMcount := 0;
+function TVideoPlayback_ProjectM.Finalize(): boolean;
+begin
+ Result := true;
+end;
+
+function TVideoPlayback_ProjectM.Open(const aFileName: IPath): IVideo;
+begin
+ Result := TVideo_ProjectM.Create;
+end;
- ProjectMPath := ProjectM_DataDir + PathDelim;
- VisualizerStarted := False;
- VisualizerPaused := False;
+{ TVideo_ProjectM }
+
+constructor TVideo_ProjectM.Create;
+begin
+ fRndPCMcount := 0;
+
+ fProjectMPath := ProjectM_DataDir + PathDelim;
+
+ fState := pmStop;
{$IFDEF UseTexture}
- glGenTextures(1, PglUint(@VisualTex));
- glBindTexture(GL_TEXTURE_2D, VisualTex);
+ glGenTextures(1, PglUint(@fVisualTex));
+ glBindTexture(GL_TEXTURE_2D, fVisualTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
{$ENDIF}
+
+ InitProjectM();
end;
-function TVideoPlayback_ProjectM.Finalize(): boolean;
+destructor TVideo_ProjectM.Destroy;
begin
- VisualizerStop();
+ Close();
{$IFDEF UseTexture}
- glDeleteTextures(1, PglUint(@VisualTex));
+ glDeleteTextures(1, PglUint(@fVisualTex));
{$ENDIF}
- Result := true;
end;
-function TVideoPlayback_ProjectM.Open(const aFileName: IPath): boolean; // true if succeed
+procedure TVideo_ProjectM.Close;
begin
- Result := false;
+ FreeAndNil(fPm);
end;
-procedure TVideoPlayback_ProjectM.Close;
+procedure TVideo_ProjectM.Play;
begin
- VisualizerStop();
+ if (fState = pmStop) and (assigned(fPm)) then
+ fPm.RandomPreset();
+ fState := pmPlay;
end;
-procedure TVideoPlayback_ProjectM.Play;
+procedure TVideo_ProjectM.Pause;
begin
- VisualizerStart();
+ if (fState = pmPlay) then
+ fState := pmPause
+ else if (fState = pmPause) then
+ fState := pmPlay;
end;
-procedure TVideoPlayback_ProjectM.Pause;
+procedure TVideo_ProjectM.Stop;
begin
- VisualizerTogglePause();
+ fState := pmStop;
end;
-procedure TVideoPlayback_ProjectM.Stop;
+procedure TVideo_ProjectM.SetPosition(Time: real);
begin
- VisualizerStop();
+ if assigned(fPm) then
+ fPm.RandomPreset();
end;
-procedure TVideoPlayback_ProjectM.SetPosition(Time: real);
+function TVideo_ProjectM.GetPosition: real;
begin
- if assigned(pm) then
- pm.RandomPreset();
+ Result := 0;
end;
-function TVideoPlayback_ProjectM.GetPosition: real;
+procedure TVideo_ProjectM.SetLoop(Enable: boolean);
begin
- Result := 0;
+end;
+
+function TVideo_ProjectM.GetLoop(): boolean;
+begin
+ Result := true;
end;
{**
* Returns the stack depth of the given OpenGL matrix mode stack.
*}
-function TVideoPlayback_ProjectM.GetMatrixStackDepth(MatrixMode: GLenum): GLint;
+function TVideo_ProjectM.GetMatrixStackDepth(MatrixMode: GLenum): GLint;
begin
// get number of matrices on stack
case (MatrixMode) of
@@ -253,7 +295,7 @@ end;
* By saving the whole stack we are on the safe side, so a nasty bug in the
* visualizer does not corrupt USDX.
*}
-procedure TVideoPlayback_ProjectM.SaveMatrixStack(MatrixMode: GLenum;
+procedure TVideo_ProjectM.SaveMatrixStack(MatrixMode: GLenum;
var MatrixStack: TGLMatrixStack);
var
I: integer;
@@ -289,7 +331,7 @@ end;
{**
* Restores the OpenGL matrix stack stored with SaveMatrixStack.
*}
-procedure TVideoPlayback_ProjectM.RestoreMatrixStack(MatrixMode: GLenum;
+procedure TVideo_ProjectM.RestoreMatrixStack(MatrixMode: GLenum;
var MatrixStack: TGLMatrixStack);
var
I: integer;
@@ -325,15 +367,15 @@ end;
* - Modelview-matrix is pushed to the Modelview-stack
* - the OpenGL error-state (glGetError) is cleared
*}
-procedure TVideoPlayback_ProjectM.SaveOpenGLState();
+procedure TVideo_ProjectM.SaveOpenGLState();
begin
// save all OpenGL state-machine attributes
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
- SaveMatrixStack(GL_PROJECTION, ProjectionMatrixStack);
- SaveMatrixStack(GL_MODELVIEW, ModelviewMatrixStack);
- SaveMatrixStack(GL_TEXTURE, TextureMatrixStack);
+ SaveMatrixStack(GL_PROJECTION, fProjectionMatrixStack);
+ SaveMatrixStack(GL_MODELVIEW, fModelviewMatrixStack);
+ SaveMatrixStack(GL_TEXTURE, fTextureMatrixStack);
glMatrixMode(GL_MODELVIEW);
@@ -345,15 +387,15 @@ end;
* Restores the OpenGL state saved by SaveOpenGLState()
* and resets the error-state.
*}
-procedure TVideoPlayback_ProjectM.RestoreOpenGLState();
+procedure TVideo_ProjectM.RestoreOpenGLState();
begin
// reset OpenGL error-state
glGetError();
// restore matrix stacks
- RestoreMatrixStack(GL_PROJECTION, ProjectionMatrixStack);
- RestoreMatrixStack(GL_MODELVIEW, ModelviewMatrixStack);
- RestoreMatrixStack(GL_TEXTURE, TextureMatrixStack);
+ RestoreMatrixStack(GL_PROJECTION, fProjectionMatrixStack);
+ RestoreMatrixStack(GL_MODELVIEW, fModelviewMatrixStack);
+ RestoreMatrixStack(GL_TEXTURE, fTextureMatrixStack);
// restore all OpenGL state-machine attributes
// (also restores the matrix mode)
@@ -361,22 +403,19 @@ begin
glPopAttrib();
end;
-procedure TVideoPlayback_ProjectM.VisualizerStart;
+procedure TVideo_ProjectM.InitProjectM;
begin
- if VisualizerStarted then
- Exit;
-
// the OpenGL state must be saved before TProjectM.Create is called
SaveOpenGLState();
try
try
{$IF PROJECTM_VERSION >= 1000000} // >= 1.0
- pm := TProjectM.Create(ProjectMPath + 'config.inp');
+ fPm := TProjectM.Create(fProjectMPath + 'config.inp');
{$ELSE}
- pm := TProjectM.Create(
+ fPm := TProjectM.Create(
meshX, meshY, fps, textureSize, ScreenW, ScreenH,
- ProjectMPath + 'presets', ProjectMPath + 'fonts');
+ fProjectMPath + 'presets', fProjectMPath + 'fonts');
{$IFEND}
except on E: Exception do
begin
@@ -387,72 +426,51 @@ begin
end;
// initialize OpenGL
- pm.ResetGL(ScreenW, ScreenH);
+ fPm.ResetGL(ScreenW, ScreenH);
// skip projectM default-preset
- pm.RandomPreset();
+ fPm.RandomPreset();
// projectM >= 1.0 uses the OpenGL FramebufferObject (FBO) extension.
// Unfortunately it does NOT reset the framebuffer-context after
// TProjectM.Create. Either glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) for
// a manual reset or TProjectM.RenderFrame() must be called.
// We use the latter so we do not need to load the FBO extension in USDX.
- pm.RenderFrame();
-
- VisualizerPaused := false;
- VisualizerStarted := true;
+ fPm.RenderFrame();
finally
RestoreOpenGLState();
end;
end;
-procedure TVideoPlayback_ProjectM.VisualizerStop;
-begin
- if VisualizerStarted then
- begin
- VisualizerPaused := false;
- VisualizerStarted := false;
- FreeAndNil(pm);
- end;
-end;
-
-procedure TVideoPlayback_ProjectM.VisualizerTogglePause;
-begin
- VisualizerPaused := not VisualizerPaused;
-end;
-
-procedure TVideoPlayback_ProjectM.GetFrame(Time: Extended);
+procedure TVideo_ProjectM.GetFrame(Time: Extended);
var
nSamples: cardinal;
begin
- if not VisualizerStarted then
- Exit;
-
- if VisualizerPaused then
+ if (fState <> pmPlay) then
Exit;
// get audio data
- nSamples := AudioPlayback.GetPCMData(PcmData);
+ nSamples := AudioPlayback.GetPCMData(fPCMData);
// generate some data if non is available
if (nSamples = 0) then
- nSamples := GetRandomPCMData(PcmData);
+ nSamples := GetRandomPCMData(fPCMData);
// send audio-data to projectM
if (nSamples > 0) then
- pm.AddPCM16Data(PSmallInt(@PcmData), nSamples);
+ fPm.AddPCM16Data(PSmallInt(@fPCMData), nSamples);
// store OpenGL state (might be messed up otherwise)
SaveOpenGLState();
try
// setup projectM's OpenGL state
- pm.ResetGL(ScreenW, ScreenH);
+ fPm.ResetGL(ScreenW, ScreenH);
// let projectM render a frame
- pm.RenderFrame();
+ fPm.RenderFrame();
{$IFDEF UseTexture}
- glBindTexture(GL_TEXTURE_2D, VisualTex);
+ glBindTexture(GL_TEXTURE_2D, fVisualTex);
glFlush();
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, VisualWidth, VisualHeight, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, fVisualWidth, fVisualHeight, 0);
{$ENDIF}
finally
// restore USDX OpenGL state
@@ -467,7 +485,7 @@ end;
* Draws the current frame to screen.
* TODO: this is not used yet. Data is directly drawn on GetFrame().
*}
-procedure TVideoPlayback_ProjectM.DrawGL(Screen: integer);
+procedure TVideo_ProjectM.DrawGL(Screen: integer);
begin
{$IFDEF UseTexture}
// have a nice black background to draw on
@@ -478,7 +496,7 @@ begin
end;
// exit if there's nothing to draw
- if not VisualizerStarted then
+ if (fState <> pmPlay) then
Exit;
// setup display
@@ -497,7 +515,7 @@ begin
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glBindTexture(GL_TEXTURE_2D, VisualTex);
+ glBindTexture(GL_TEXTURE_2D, fVisualTex);
glColor4f(1, 1, 1, 1);
// draw projectM frame
@@ -524,12 +542,12 @@ end;
* Produces random "sound"-data in case no audio-data is available.
* Otherwise the visualization will look rather boring.
*}
-function TVideoPlayback_ProjectM.GetRandomPCMData(var Data: TPCMData): Cardinal;
+function TVideo_ProjectM.GetRandomPCMData(var Data: TPCMData): Cardinal;
var
i: integer;
begin
// Produce some fake PCM data
- if (RndPCMcount mod 500 = 0) then
+ if (fRndPCMcount mod 500 = 0) then
begin
FillChar(Data, SizeOf(TPCMData), 0);
end
@@ -541,7 +559,7 @@ begin
Data[i][1] := Random(High(Word)+1);
end;
end;
- Inc(RndPCMcount);
+ Inc(fRndPCMcount);
Result := 512;
end;