aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/base/UMusic.pas1
-rw-r--r--src/media/UAudioPlaybackBase.pas128
-rw-r--r--src/media/UMedia_dummy.pas7
3 files changed, 133 insertions, 3 deletions
diff --git a/src/base/UMusic.pas b/src/base/UMusic.pas
index be6b8baf..c85e3417 100644
--- a/src/base/UMusic.pas
+++ b/src/base/UMusic.pas
@@ -454,6 +454,7 @@ type
// PlaySound/StopSound will be removed then, OpenSound will be renamed to
// CreateSound.
function OpenSound(const Filename: IPath): TAudioPlaybackStream;
+ function OpenSoundBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
procedure PlaySound(Stream: TAudioPlaybackStream);
procedure StopSound(Stream: TAudioPlaybackStream);
diff --git a/src/media/UAudioPlaybackBase.pas b/src/media/UAudioPlaybackBase.pas
index 5f317257..ffee671d 100644
--- a/src/media/UAudioPlaybackBase.pas
+++ b/src/media/UAudioPlaybackBase.pas
@@ -36,7 +36,9 @@ interface
uses
UMusic,
UTime,
- UPath;
+ UPath,
+ Classes,
+ SysUtils;
type
TAudioPlaybackBase = class(TInterfacedObject, IAudioPlayback)
@@ -49,6 +51,7 @@ type
// open sound or music stream (used by Open() and OpenSound())
function OpenStream(const Filename: IPath): TAudioPlaybackStream;
+ function OpenStreamBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
function OpenDecodeStream(const Filename: IPath): TAudioDecodeStream;
public
function GetName: string; virtual; abstract;
@@ -82,6 +85,7 @@ type
// Sounds
function OpenSound(const Filename: IPath): TAudioPlaybackStream;
+ function OpenSoundBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
procedure PlaySound(Stream: TAudioPlaybackStream);
procedure StopSound(Stream: TAudioPlaybackStream);
@@ -94,12 +98,30 @@ type
function CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; virtual; abstract;
end;
+ TAudioBufferSourceStream = class(TAudioSourceStream)
+ private
+ fLoop: boolean;
+ fStream: TStream;
+ fFormat: TAudioFormatInfo;
+ protected
+ function IsEOF(): boolean; override;
+ function IsError(): boolean; override;
+ function GetLength(): real; override;
+ function GetPosition(): real; override;
+ procedure SetPosition(Time: real); override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ public
+ constructor Create(Buffer: TStream; Format: TAudioFormatInfo);
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer; override;
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+ procedure Close(); override;
+ end;
implementation
uses
- ULog,
- SysUtils;
+ ULog;
{ TAudioPlaybackBase }
@@ -189,6 +211,28 @@ begin
Result := PlaybackStream;
end;
+function TAudioPlaybackBase.OpenStreamBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
+var
+ PlaybackStream: TAudioPlaybackStream;
+ SourceStream: TAudioSourceStream;
+begin
+ Result := nil;
+
+ // create a matching playback-stream for the decoder
+ PlaybackStream := CreatePlaybackStream();
+ SourceStream := TAudioBufferSourceStream.Create(Buffer, Format);
+ if (not PlaybackStream.Open(SourceStream)) then
+ begin
+ FreeAndNil(PlaybackStream);
+ FreeAndNil(SourceStream);
+ Exit;
+ end;
+
+ PlaybackStream.AddOnCloseHandler(OnClosePlaybackStream);
+
+ Result := PlaybackStream;
+end;
+
procedure TAudioPlaybackBase.Play;
begin
if assigned(MusicStream) then
@@ -290,6 +334,11 @@ begin
Result := OpenStream(Filename);
end;
+function TAudioPlaybackBase.OpenSoundBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
+begin
+ Result := OpenStreamBuffer(Buffer, Format);
+end;
+
procedure TAudioPlaybackBase.PlaySound(stream: TAudioPlaybackStream);
begin
if assigned(stream) then
@@ -316,4 +365,77 @@ begin
Result := OutputDeviceList;
end;
+{ TAudioBufferSourceStream }
+
+constructor TAudioBufferSourceStream.Create(Buffer: TStream; Format: TAudioFormatInfo);
+begin
+ fStream := Buffer;
+ fFormat := Format.Copy;
+end;
+
+function TAudioBufferSourceStream.IsEOF(): boolean;
+begin
+ Result := (not fLoop and (fStream.Position >= fStream.Size));
+end;
+
+function TAudioBufferSourceStream.IsError(): boolean;
+begin
+ Result := false;
+end;
+
+function TAudioBufferSourceStream.GetLength(): real;
+begin
+ Result := fStream.Size / fFormat.BytesPerSec;
+end;
+
+function TAudioBufferSourceStream.GetPosition(): real;
+begin
+ Result := fStream.Position / fFormat.BytesPerSec;
+end;
+
+procedure TAudioBufferSourceStream.SetPosition(Time: real);
+begin
+ fStream.Position := Trunc(Time * fFormat.BytesPerSec);
+end;
+
+function TAudioBufferSourceStream.GetLoop(): boolean;
+begin
+ Result := fLoop;
+end;
+
+procedure TAudioBufferSourceStream.SetLoop(Enabled: boolean);
+begin
+ fLoop := Enabled;
+end;
+
+function TAudioBufferSourceStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
+var
+ BufSizeLeft: integer;
+ NumRead: integer;
+begin
+ Result := fStream.Read(Buffer^, BufferSize);
+ if (fLoop) then
+ begin
+ BufSizeLeft := BufferSize - Result;
+ while (BufSizeLeft > 0) do
+ begin
+ fStream.Position := 0;
+ NumRead := fStream.Read(Buffer^, BufSizeLeft);
+ BufSizeLeft := BufSizeLeft - NumRead;
+ end;
+ Result := BufferSize;
+ end;
+end;
+
+function TAudioBufferSourceStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := fFormat;
+end;
+
+procedure TAudioBufferSourceStream.Close();
+begin
+ FreeAndNil(fFormat);
+ fStream := nil;
+end;
+
end.
diff --git a/src/media/UMedia_dummy.pas b/src/media/UMedia_dummy.pas
index 46cbe6b8..34f85226 100644
--- a/src/media/UMedia_dummy.pas
+++ b/src/media/UMedia_dummy.pas
@@ -38,6 +38,7 @@ implementation
uses
SysUtils,
math,
+ Classes,
UTime,
UMusic,
UPath;
@@ -90,6 +91,7 @@ type
function Length: real;
function OpenSound(const Filename: IPath): TAudioPlaybackStream;
+ function OpenSoundBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
procedure CloseSound(var PlaybackStream: TAudioPlaybackStream);
procedure PlaySound(stream: TAudioPlaybackStream);
procedure StopSound(stream: TAudioPlaybackStream);
@@ -305,6 +307,11 @@ begin
Result := nil;
end;
+function TAudio_Dummy.OpenSoundBuffer(Buffer: TStream; Format: TAudioFormatInfo): TAudioPlaybackStream;
+begin
+ Result := nil;
+end;
+
procedure TAudio_Dummy.CloseSound(var PlaybackStream: TAudioPlaybackStream);
begin
end;