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

View File

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