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
object pathEdit: TFileNameEdit
Left = 12
Height = 21
Height = 22
Top = 13
Width = 268
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 := SysUtils.ExpandFileName(pathEdit.FileName);
{$endif}
{$ifdef Darwin}
pathEdit.FileName := ExtractFilePath(Application.ExeName) + '..\..\..\..\testsounds\test.wav';
pathEdit.FileName := SysUtils.ExpandFileName(pathEdit.FileName);
{$endif}
end;
end.

View File

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

View File

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

View File

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

View File

@ -68,7 +68,6 @@ type
procedure ReadHeaders(AStream: TStream; ADest: TSoundDocument);
procedure ReadAllSamples(AStream: TStream; ADest: TSoundDocument);
procedure ReadSample(AStream: TStream; ADest: TSoundDocument);
procedure ReadChannelData(AStream: TStream; out AValue: Integer);
//function ReadBuf(var Buffer; BufferSize: Integer): Integer;
end;
@ -133,39 +132,38 @@ end;
procedure TWaveReader.ReadSample(AStream: TStream; ADest: TSoundDocument);
var
lSoundSample: TSoundSample;
lSoundSample8: TSoundSample8;
lSoundSample16: TSoundSample16;
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;
lWordData: SmallInt;
begin
if fmt.BitsPerSample = 8 then
begin
lByteData := AStream.ReadByte();
AValue := lByteData;
lSoundSample8 := TSoundSample8.Create;
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
else if fmt.BitsPerSample = 16 then
begin
AStream.Read(lWordData, 2);
AValue := lWordData;
lSoundSample16 := TSoundSample16.Create;
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
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;
{function TWaveReader.ReadBuf(var Buffer;BufferSize:Integer):Integer;