From a6547fdc146339b34600c89cb0f71e3f54069478 Mon Sep 17 00:00:00 2001 From: yangjixian Date: Thu, 9 Feb 2012 15:48:39 +0000 Subject: [PATCH] Sound works but just once. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2278 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpsound/fpsound.pas | 15 ++-- components/fpsound/fpsound_openal.pas | 105 +++++++++++++++++--------- 2 files changed, 78 insertions(+), 42 deletions(-) diff --git a/components/fpsound/fpsound.pas b/components/fpsound/fpsound.pas index c6e3784d7..76bf8c271 100644 --- a/components/fpsound/fpsound.pas +++ b/components/fpsound/fpsound.pas @@ -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 diff --git a/components/fpsound/fpsound_openal.pas b/components/fpsound/fpsound_openal.pas index 8839afe5c..bfe2f714c 100644 --- a/components/fpsound/fpsound_openal.pas +++ b/components/fpsound/fpsound_openal.pas @@ -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.