fpsound: Some more improvements

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2265 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2012-01-25 08:44:37 +00:00
parent 624d9b3283
commit 2b94c420ac
6 changed files with 62 additions and 47 deletions

View File

@@ -19,7 +19,7 @@ object Form1: TForm1
end end
object pathEdit: TFileNameEdit object pathEdit: TFileNameEdit
Left = 12 Left = 12
Height = 21 Height = 22
Top = 13 Top = 13
Width = 268 Width = 268
FileName = '/home/felipe/Programas/lazarus-ccr/components/fpsound/testsounds/test.wav' FileName = '/home/felipe/Programas/lazarus-ccr/components/fpsound/testsounds/test.wav'

View File

@@ -50,6 +50,10 @@ begin
pathEdit.FileName := ExtractFilePath(Application.ExeName) + '..\testsounds\test.wav'; pathEdit.FileName := ExtractFilePath(Application.ExeName) + '..\testsounds\test.wav';
pathEdit.FileName := SysUtils.ExpandFileName(pathEdit.FileName); pathEdit.FileName := SysUtils.ExpandFileName(pathEdit.FileName);
{$endif} {$endif}
{$ifdef Darwin}
pathEdit.FileName := ExtractFilePath(Application.ExeName) + '..\..\..\..\testsounds\test.wav';
pathEdit.FileName := SysUtils.ExpandFileName(pathEdit.FileName);
{$endif}
end; end;
end. end.

View File

@@ -56,7 +56,12 @@ type
Channels: Byte; // Number of channels Channels: Byte; // Number of channels
end; end;
TSoundSample = class(TSoundElement) TSoundSample8 = class(TSoundElement)
public
ChannelValues: array of Byte;
end;
TSoundSample16 = class(TSoundElement)
public public
ChannelValues: array of SmallInt; ChannelValues: array of SmallInt;
end; end;

View File

@@ -49,11 +49,11 @@ type
procedure Initialize; override; procedure Initialize; override;
procedure Finalize; override; procedure Finalize; override;
procedure Play(ASound: TSoundDocument); override; procedure Play(ASound: TSoundDocument); override;
procedure AdjustToKeyElement(AElement: TSoundKeyElement); procedure AdjustToKeyElement(ASound: TSoundDocument; AKeyElement: TSoundKeyElement);
//procedure OPCSoundPlayStreamEx(AStream: TStream); //procedure OPCSoundPlayStreamEx(AStream: TStream);
procedure alStop; procedure alStop;
function alProcess: Boolean; function alProcess(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Boolean;
procedure alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement); function alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Integer;
end; end;
@@ -296,7 +296,7 @@ begin
alSourcei(al_source, AL_BUFFER, 0); alSourcei(al_source, AL_BUFFER, 0);
end; end;
function TOpenALPlayer.alProcess: Boolean; function TOpenALPlayer.alProcess(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Boolean;
var var
processed : ALint; processed : ALint;
buffer : ALuint; buffer : ALuint;
@@ -306,7 +306,7 @@ begin
while (processed > 0) and (processed <= al_bufcount) do while (processed > 0) and (processed <= al_bufcount) do
begin begin
alSourceUnqueueBuffers(al_source, 1, @buffer); alSourceUnqueueBuffers(al_source, 1, @buffer);
//f/ sz:=wave.ReadBuf(al_readbuf^, al_bufsize); sz := alFillBuffer(ASound, AKeyELement);
if sz <= 0 then if sz <= 0 then
begin begin
Exit(False); Exit(False);
@@ -318,22 +318,24 @@ begin
Result := True; Result := True;
end; end;
procedure TOpenALPlayer.alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement); function TOpenALPlayer.alFillBuffer(ASound: TSoundDocument; AKeyElement: TSoundKeyElement): Integer;
var var
lCurSample: TSoundSample; lCurElement: TSoundElement;
lReadCount: Integer = 0; lReadCount: Integer = 0;
begin begin
Result := 0;
while lReadCount < al_bufsize do while lReadCount < al_bufsize do
begin begin
lCurSample := ASound.GetNextSoundElement() as TSoundSample; lCurElement := ASound.GetNextSoundElement();
if lCurSample = nil then Exit; if lCurElement = nil then Exit;
Inc(Result);
lReadCount := lReadCount + AKeyElement.BitsPerSample div 8; lReadCount := lReadCount + AKeyElement.BitsPerSample div 8;
if AKeyElement.BitsPerSample = 8 then if AKeyElement.BitsPerSample = 8 then
PByte(al_readbuf)[lReadCount] := Lo(lCurSample.ChannelValues[0]) PByte(al_readbuf)[lReadCount] := Lo((lCurElement as TSoundSample8).ChannelValues[0])
else else
PWord(al_readbuf)[lReadCount div 2] := Word(lCurSample.ChannelValues[0]) PWord(al_readbuf)[lReadCount div 2] := Word((lCurElement as TSoundSample16).ChannelValues[0])
end; end;
end; end;
@@ -372,7 +374,7 @@ var
begin begin
// First adjust to the first key element // First adjust to the first key element
lKeyElement := ASound.GetFirstSoundElement(); lKeyElement := ASound.GetFirstSoundElement();
AdjustToKeyElement(lKeyElement); AdjustToKeyElement(ASound, lKeyElement);
// Now clean up the source // Now clean up the source
alSourceStop(al_source); alSourceStop(al_source);
@@ -395,7 +397,8 @@ begin
done:=False; done:=False;
queued:=0; queued:=0;
repeat repeat
if alProcess then begin if alProcess(ASound, lKeyElement) then
begin
alGetSourcei(al_source, AL_BUFFERS_QUEUED, queued); alGetSourcei(al_source, AL_BUFFERS_QUEUED, queued);
done:=queued=0; done:=queued=0;
end; end;
@@ -403,33 +406,33 @@ begin
until done; until done;
end; end;
procedure TOpenALPlayer.AdjustToKeyElement(AElement: TSoundKeyElement); procedure TOpenALPlayer.AdjustToKeyElement(ASound: TSoundDocument; AKeyElement: TSoundKeyElement);
begin begin
// define codec // define codec
//source := AStream; //source := AStream;
// inittialize codec // inittialize codec
if AElement.Channels = 1 then if AKeyElement.Channels = 1 then
begin begin
if AElement.BitsPerSample=8 then al_format:=AL_FORMAT_MONO8 if AKeyElement.BitsPerSample=8 then al_format:=AL_FORMAT_MONO8
else al_format:=AL_FORMAT_MONO16 else al_format:=AL_FORMAT_MONO16
end end
else else
begin begin
if AElement.BitsPerSample=8 then al_format := AL_FORMAT_STEREO8 if AKeyElement.BitsPerSample=8 then al_format := AL_FORMAT_STEREO8
else al_format:=AL_FORMAT_STEREO16 else al_format:=AL_FORMAT_STEREO16
end; end;
codec_bs:=2*AElement.Channels; codec_bs:=2*AKeyElement.Channels;
al_bufsize := 20000 - (20000 mod codec_bs); al_bufsize := 20000 - (20000 mod codec_bs);
al_rate:=AElement.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);
alProcess(); alProcess(ASound, AKeyElement);
end; end;
end. end.

View File

@@ -5,8 +5,13 @@
<CompilerOptions> <CompilerOptions>
<Version Value="11"/> <Version Value="11"/>
<SearchPaths> <SearchPaths>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/"/> <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths> </SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2"/>
</Debugging>
</Linking>
<Other> <Other>
<CompilerPath Value="$(CompPath)"/> <CompilerPath Value="$(CompPath)"/>
</Other> </Other>
@@ -22,7 +27,7 @@
</Item2> </Item2>
<Item3> <Item3>
<Filename Value="fpsound_wav.pas"/> <Filename Value="fpsound_wav.pas"/>
<UnitName Value="opcwav"/> <UnitName Value="fpsound_wav"/>
</Item3> </Item3>
</Files> </Files>
<Type Value="RunAndDesignTime"/> <Type Value="RunAndDesignTime"/>

View File

@@ -68,7 +68,6 @@ type
procedure ReadHeaders(AStream: TStream; ADest: TSoundDocument); procedure ReadHeaders(AStream: TStream; ADest: TSoundDocument);
procedure ReadAllSamples(AStream: TStream; ADest: TSoundDocument); procedure ReadAllSamples(AStream: TStream; ADest: TSoundDocument);
procedure ReadSample(AStream: TStream; ADest: TSoundDocument); procedure ReadSample(AStream: TStream; ADest: TSoundDocument);
procedure ReadChannelData(AStream: TStream; out AValue: Integer);
//function ReadBuf(var Buffer; BufferSize: Integer): Integer; //function ReadBuf(var Buffer; BufferSize: Integer): Integer;
end; end;
@@ -133,39 +132,38 @@ end;
procedure TWaveReader.ReadSample(AStream: TStream; ADest: TSoundDocument); procedure TWaveReader.ReadSample(AStream: TStream; ADest: TSoundDocument);
var var
lSoundSample: TSoundSample; lSoundSample8: TSoundSample8;
lSoundSample16: TSoundSample16;
i: Integer; i: Integer;
lValue: Integer;
begin
lSoundSample := TSoundSample.Create;
SetLength(lSoundSample.ChannelValues, fmt.Channels);
for i := 0 to fmt.Channels - 1 do
begin
ReadChannelData(AStream, lValue);
lSoundSample.ChannelValues[i] := lValue;
end;
ADest.AddSoundElement(lSoundSample);
end;
procedure TWaveReader.ReadChannelData(AStream: TStream; out AValue: Integer);
var
lByteData: Byte; lByteData: Byte;
lWordData: SmallInt; lWordData: SmallInt;
begin begin
if fmt.BitsPerSample = 8 then if fmt.BitsPerSample = 8 then
begin begin
lByteData := AStream.ReadByte(); lSoundSample8 := TSoundSample8.Create;
AValue := lByteData; SetLength(lSoundSample8.ChannelValues, fmt.Channels);
for i := 0 to fmt.Channels - 1 do
begin
lByteData := AStream.ReadByte();
lSoundSample8.ChannelValues[i] := lByteData;
end;
ADest.AddSoundElement(lSoundSample8);
end end
else if fmt.BitsPerSample = 16 then else if fmt.BitsPerSample = 16 then
begin begin
AStream.Read(lWordData, 2); lSoundSample16 := TSoundSample16.Create;
AValue := lWordData; SetLength(lSoundSample16.ChannelValues, fmt.Channels);
for i := 0 to fmt.Channels - 1 do
begin
AStream.Read(lWordData, 2);
lSoundSample16.ChannelValues[i] := lWordData;
end;
ADest.AddSoundElement(lSoundSample16);
end end
else else
raise Exception.Create(Format('[TWaveReader.ReadChannelData] Invalid number of bits per sample: %d', [fmt.BitsPerSample])); raise Exception.Create(Format('[TWaveReader.ReadSample] Invalid number of bits per sample: %d', [fmt.BitsPerSample]));
end; end;
{function TWaveReader.ReadBuf(var Buffer;BufferSize:Integer):Integer; {function TWaveReader.ReadBuf(var Buffer;BufferSize:Integer):Integer;