Sound works but just once.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2278 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
yangjixian
2012-02-09 15:48:39 +00:00
parent 00912160a0
commit a6547fdc14
2 changed files with 78 additions and 42 deletions

View File

@ -79,7 +79,7 @@ type
TSoundDocument = class
private
AStream: TStream;
AStream: TMemoryStream;
FPlayer: TSoundPlayer;
FPlayerKind: TSoundPlayerKind;
FCurElementIndex: Integer;
@ -104,7 +104,7 @@ type
procedure Stop;
procedure Seek(ANewPos: Double);
procedure SetSoundPlayer(AKind: TSoundPlayerKind);
function GetSoundDocPtr: Pointer;
function GetSoundDocStream: TStream;
end;
var
@ -170,11 +170,13 @@ begin
inherited Create;
FSoundData := TFPList.Create;
aStream := TMemoryStream.Create;
end;
destructor TSoundDocument.Destroy;
begin
FSoundData.Free;
aStream.Free;
if FPlayer <> nil then FPlayer.Finalize;
inherited Destroy;
end;
@ -197,6 +199,8 @@ begin
try
Clear();
lReader.ReadFromStream(lStream, Self);
lStream.Position := 0;
aStream.LoadFromStream(lStream);
finally
lStream.Free;
end;
@ -286,11 +290,12 @@ begin
FPlayer := GSoundPlayers[AKind];
end;
function TSoundDocument.GetSoundDocPtr: Pointer;
function TSoundDocument.GetSoundDocStream: TStream;
begin
aStream.Position := 0;
{aStream.Position := 0;
getmem(Result, aStream.Size);
aStream.Read(Result^, aStream.Size);
aStream.Read(Result^, aStream.Size); }
Result := aStream;
end;
var

View File

@ -25,27 +25,42 @@ type
private
al_device: PALCdevice;
al_context: PALCcontext;
codec_bs : Longword;
al_source : TALuint;
al_format : Integer;
al_buffers : array[0..0] of TALuint;
al_bufsize : Longword;
al_readbuf : Pointer;
al_rate : Longword;
al_bufcount : Integer;
codec_bs: longword;
al_source: TALuint;
al_format: integer;
al_buffers: array[0..0] of TALuint;
al_bufsize: longword;
al_readbuf: Pointer;
al_rate: longword;
al_bufcount: integer;
public
constructor Create; override;
destructor Destroy; override;
procedure Initialize; override;
procedure Finalize; override;
procedure Play(ASound: TSoundDocument); override;
procedure AdjustToKeyElement(ASound: TSoundDocument; AKeyElement: TSoundKeyElement);
procedure alStop;
//function alProcess(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Boolean;
function alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Integer;
function alFillBuffer(ASound: TSoundDocument;
AKeyElement: TSoundKeyElement): integer;
end;
implementation
constructor TOpenALPlayer.Create;
begin
inherited;
Initialize;
end;
destructor TOpenALPlayer.Destroy;
begin
inherited;
Finalize;
end;
procedure TOpenALPlayer.alStop;
begin
alSourceStop(al_source);
@ -75,12 +90,14 @@ begin
Result := True;
end;}
function TOpenALPlayer.alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Integer;
function TOpenALPlayer.alFillBuffer(ASound: TSoundDocument;
AKeyElement: TSoundKeyElement): integer;
var
lCurElement: TSoundElement;
lReadCount: Integer = 0;
lReadCount: integer = 0;
lBufferBytePtr: PByte;
lBufferWordPtr: PWord;
loop: TALInt;
begin
GetMem(al_readbuf, al_bufsize);
Result := 0;
@ -91,7 +108,8 @@ begin
while lReadCount < al_bufsize do
begin
lCurElement := ASound.GetNextSoundElement();
if lCurElement = nil then Exit;
if lCurElement = nil then
Exit;
Inc(Result);
lReadCount := lReadCount + AKeyElement.BitsPerSample div 8;
@ -103,17 +121,21 @@ begin
end
else
begin
lBufferWordPtr^ := Word((lCurElement as TSoundSample16).ChannelValues[0]);
lBufferWordPtr^ := word((lCurElement as TSoundSample16).ChannelValues[0]);
Inc(lBufferWordPtr, 2);
end;
end;
al_readbuf := ASound.GetSoundDocPtr;
//AlutLoadWavFile('T:\fpsound\testsounds\test.wav', al_format, al_readbuf, al_bufsize, al_rate, loop);
//alutLoadWAVMemory(ASound.GetSoundDocPtr, al_format, al_readbuf, al_bufsize, al_rate, loop);
LoadWavStream(ASound.GetSoundDocStream, al_format, al_readbuf, al_bufsize, al_rate, loop);
end;
procedure TOpenALPlayer.Initialize;
var argv: array of PALbyte;
var
argv: array of PALbyte;
begin
if FInitialized then Exit;
if FInitialized then
Exit;
IsMultiThread := False;
if not InitOpenAL then
@ -138,7 +160,7 @@ begin
alSource3f(al_source, AL_VELOCITY, 0, 0, 0);
alSourcei(al_source, AL_LOOPING, AL_FALSE);
// alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
// alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
FInitialized := True;
end;
@ -148,19 +170,21 @@ begin
// finalize openal
alDeleteSources(1, @al_source);
alDeleteBuffers(al_bufcount, @al_buffers);
if al_readbuf <> nil then FreeMem(al_readbuf);
alcDestroyContext(al_context);
alcCloseDevice(al_device);
AlutExit();
if al_readbuf <> nil then
FreeMem(al_readbuf);
// alcDestroyContext(al_context);
// alcCloseDevice(al_device);
FInitialized := False;
end;
procedure TOpenALPlayer.Play(ASound: TSoundDocument);
var
queued : Integer;
done : Boolean;
queued: integer;
done: boolean;
lKeyElement: TSoundKeyElement;
begin
Initialize;
// Initialize;
// First adjust to the first key element
lKeyElement := ASound.GetFirstSoundElement();
@ -180,35 +204,42 @@ begin
alSourcePlay(al_source);
end;
procedure TOpenALPlayer.AdjustToKeyElement(ASound: TSoundDocument; AKeyElement: TSoundKeyElement);
procedure TOpenALPlayer.AdjustToKeyElement(ASound: TSoundDocument;
AKeyElement: TSoundKeyElement);
begin
// initialize codec
if AKeyElement.Channels = 1 then
begin
if AKeyElement.BitsPerSample=8 then al_format:=AL_FORMAT_MONO8
else al_format:=AL_FORMAT_MONO16
if AKeyElement.BitsPerSample = 8 then
al_format := AL_FORMAT_MONO8
else
al_format := AL_FORMAT_MONO16;
end
else
begin
if AKeyElement.BitsPerSample=8 then al_format := AL_FORMAT_STEREO8
else al_format:=AL_FORMAT_STEREO16
if AKeyElement.BitsPerSample = 8 then
al_format := AL_FORMAT_STEREO8
else
al_format := AL_FORMAT_STEREO16;
end;
codec_bs:=2*AKeyElement.Channels;
al_bufsize := 20000 - (20000 mod codec_bs);
al_rate:=AKeyElement.SampleRate;
// WriteLn('Blocksize : ', codec_bs);
// WriteLn('Rate : ', wave.fmt.SampleRate);
// WriteLn('Channels : ', wave.fmt.Channels);
// WriteLn('OpenAL Buffers : ', al_bufcount);
// WriteLn('OpenAL Buffer Size : ', al_bufsize);
codec_bs := 2 * AKeyElement.Channels;
// al_bufsize := 20000 - (20000 mod codec_bs);
al_rate := AKeyElement.SampleRate;
// WriteLn('Blocksize : ', codec_bs);
// WriteLn('Rate : ', wave.fmt.SampleRate);
// WriteLn('Channels : ', wave.fmt.Channels);
// WriteLn('OpenAL Buffers : ', al_bufcount);
// WriteLn('OpenAL Buffer Size : ', al_bufsize);
if al_readbuf <> nil then FreeMem(al_readbuf);
// if al_readbuf <> nil then
// FreeMem(al_readbuf);
//alProcess(ASound, AKeyElement);
end;
initialization
RegisterSoundPlayer(TOpenALPlayer.Create, spOpenAL);
end.