Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streaming music - WIP #127

Merged
merged 31 commits into from Aug 16, 2019
Merged
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
17314eb
Make vorbis decoder usable for streaming.
and3md Jul 31, 2019
912b122
Added TStreamedSoundFile and TStreamedSoundOggVorbis.
and3md Jul 31, 2019
d372e26
The first draft of streaming sound buffers.
and3md Jul 31, 2019
74dbeda
Draft 2 of streaming sound: Multiple playback at the same time, Don't…
and3md Aug 4, 2019
32a92f9
Fixed checking dangle pointer when setBuffer() with TOpenALSoundBuff…
and3md Aug 4, 2019
75e2895
Proper release stream resources.
and3md Aug 4, 2019
9bc7ab4
Rewind streamed sound file, this is necessary for looping.
and3md Aug 5, 2019
865e0af
Music streaming: Sound looping support
and3md Aug 5, 2019
8571620
Fixed typo Soc -> Sox.
and3md Aug 5, 2019
961aa9c
TSoundBufferType -> TSoundLoading.
and3md Aug 5, 2019
8ec769f
Backward compatibility version of LoadBuffer.
and3md Aug 6, 2019
80c2989
Added CASTLE_SUPPORTS_THREADING, when threads are not available, fall…
and3md Aug 6, 2019
365eec4
Streaming: Code cleaning and minor changes.
and3md Aug 6, 2019
2b66e08
Remove unneeded log.
and3md Aug 11, 2019
b77bd60
Fix LoadBuffer result not assigned, do not introduce new LoadBuffer d…
michaliskambi Aug 12, 2019
f310a85
Whitespace (only one empty line to separate)
michaliskambi Aug 12, 2019
129102d
Wrap OggVorbis loading in TOggVorbisStream
michaliskambi Aug 12, 2019
823af29
Allow testing streaming in examples/audio/play_sounds
michaliskambi Aug 12, 2019
2f08594
Past tense of "read" is "read", not "readed"
michaliskambi Aug 13, 2019
a999ad6
Fix raising exception
michaliskambi Aug 13, 2019
853c13a
Every sound format (OggVorbis, WAV) is now expressed as TSoundReadEvent
michaliskambi Aug 13, 2019
23cf2ba
Remove large and unused TSoundFile.DataStatistics implementation
michaliskambi Aug 13, 2019
d0b8504
Allow loading FMOD dynamically (so we know at runtime when FMOD is no…
michaliskambi Aug 15, 2019
2c965d0
FMOD supports streaming too, and some code cleanups
michaliskambi Aug 15, 2019
71f4b63
Improve comment - Pascal threads for streaming are required by OpenAL…
michaliskambi Aug 15, 2019
8429af5
Fix FMOD dynamic freeing, to work with any finalization order of units
michaliskambi Aug 16, 2019
8ee8042
Get correct Duration for OggVorbis sounds, even when streaming
michaliskambi Aug 16, 2019
5315ea5
Various code cleanups (no functional changes)
michaliskambi Aug 16, 2019
4167622
Small comment improvements and code cleanups
michaliskambi Aug 16, 2019
8a06c75
Fix playing short sounds with slStreaming, we may need less than 4 bu…
michaliskambi Aug 16, 2019
dbf7c90
Improve comments and tiny code cleanups
michaliskambi Aug 16, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Music streaming: Sound looping support

  • Loading branch information...
and3md committed Aug 5, 2019
commit 865e0afec72a2b778117d04a6885c6c848b9b9ad
@@ -106,11 +106,23 @@ TOpenALStreamFeedThread = class(TThread)

TOpenALSoundSourceBackend = class(TSoundSourceBackend)
strict private
{ Because TOpenALSoundBufferBackend is one for all sources we don't have pointer to sound source
to correctly set FBuffer to nil like in TOpenALStreamBuffersSoundSourceRes.ContextClose.
That makes a problem when FBuffer is checked in TOpenALSoundSourceBackend.SetBuffer
because FBuffer can be dangling pointer.
So we set this variable to see do we have to check remove the sourcefrom buffer at all.
FBuffer variable is always correct when is set to TOpenALStreamBuffersBackend and
can be dangling pointer when set to TOpenALSoundBufferBackend. }
FStreamedBuffer: Boolean;
function ALVersion11: Boolean;
private
FBuffer: TSoundBufferBackend;
ALSource: TALuint;
FLooping: Boolean;

{ When buffer is stremed, OpenAL source looping need to be off,
otherwise, one buffer will be looped. This procedure cares about that. }
procedure AdjustALLooping;
public
procedure ContextOpen; override;
procedure ContextClose; override;
@@ -263,7 +275,7 @@ function TOpenALStreamBuffersSoundSourceRes.FillBuffer(ALBuffer: TALuint): Integ
AL_FORMAT_STEREO8,
AL_FORMAT_STEREO16
);
BufSize = 1024 * 16; // 100kB for tests
BufSize = 1024 * 16; // 16kB for tests
begin
Buffer := GetMem(BufSize);
try
@@ -272,7 +284,11 @@ function TOpenALStreamBuffersSoundSourceRes.FillBuffer(ALBuffer: TALuint): Integ
begin
alBufferData(ALBuffer, ALDataFormat[StreamedSFile.DataFormat], Buffer, Result, StreamedSFile.Frequency);
end else
alBufferData(ALBuffer, ALDataFormat[StreamedSFile.DataFormat], nil, 0, StreamedSFile.Frequency);
if FSoundSource.FLooping then
begin
StreamedSFile.Rewind;
Result := FillBuffer(ALBuffer);
end;
finally
FreeMemNiling(Buffer);
end;
@@ -310,10 +326,18 @@ procedure TOpenALStreamFeedThread.Execute;
begin
alSourceQueueBuffers(ALSource, 1, @ALBuffer);
end else
begin
Exit;
end;

Dec(ALBuffersProcessed);
end;

if not FStreamSoundSourceRes.FSoundSource.PlayingOrPaused then
begin
alSourcePlay(ALSource);
end;

end;
end;

@@ -425,6 +449,14 @@ function TOpenALSoundSourceBackend.ALVersion11: Boolean;
Result := (SoundEngine as TOpenALSoundEngineBackend).ALVersion11;
end;

procedure TOpenALSoundSourceBackend.AdjustALLooping;
begin
if FStreamedBuffer then
alSourcei(ALSource, AL_LOOPING, BoolToAL[false])
else
alSourcei(ALSource, AL_LOOPING, BoolToAL[FLooping]);
end;

procedure TOpenALSoundSourceBackend.ContextOpen;
var
ErrorCode: TALenum;
@@ -472,32 +504,9 @@ procedure TOpenALSoundSourceBackend.Play(const BufferChangedRecently: Boolean);

alSourcePlay(ALSource);

// tutaj wątek
// start feed buffers thread
StreamedBuffer.FeedBuffers(Self);

{ALBuffersProcessed := 0;
while (true) do
begin
Sleep(10);
alGetSourcei(ALSource, AL_BUFFERS_PROCESSED, @ALBuffersProcessed);
while ALBuffersProcessed > 0 do
begin
alSourceUnqueueBuffers(ALSource, 1, @ALBuffer);
if StreamedBuffer.FillBuffer(ALBuffer) > 0 then
begin
alSourceQueueBuffers(ALSource, 1, @ALBuffer);
end
else
Exit;
Dec(ALBuffersProcessed);
end;
end; }

Exit;
end;

@@ -568,7 +577,8 @@ procedure TOpenALSoundSourceBackend.SetVelocity(const Value: TVector3);

procedure TOpenALSoundSourceBackend.SetLooping(const Value: boolean);
begin
//alSourcei(ALSource, AL_LOOPING, BoolToAL[Value]);
FLooping := Value;
AdjustALLooping;
end;

procedure TOpenALSoundSourceBackend.SetRelative(const Value: boolean);
@@ -598,7 +608,7 @@ procedure TOpenALSoundSourceBackend.SetBuffer(const Value: TSoundBufferBackend);
FullLoaded: TOpenALSoundBufferBackend;
begin
{ If some streamed buffer was connected to this source, disconnect it before
the change. }
the change. Why FStreamedBuffer? See comment above FStreamedBuffer declaration. }
if FStreamedBuffer and Assigned(FBuffer) and (FBuffer is TOpenALStreamBuffersBackend) then
TOpenALStreamBuffersBackend(FBuffer).RemoveSoundSource(Self);

@@ -610,6 +620,7 @@ procedure TOpenALSoundSourceBackend.SetBuffer(const Value: TSoundBufferBackend);
if FBuffer is TOpenALSoundBufferBackend then
begin
FStreamedBuffer := false;
AdjustALLooping;
FullLoaded := TOpenALSoundBufferBackend(FBuffer);
{ TSoundBuffer is unsigned, while alSourcei is declared as taking signed integer.
But we know we can pass TSoundBuffer to alSourcei, just typecasting it to
@@ -621,6 +632,7 @@ procedure TOpenALSoundSourceBackend.SetBuffer(const Value: TSoundBufferBackend);
if FBuffer is TOpenALStreamBuffersBackend then
begin
This conversation was marked as resolved by and3md

This comment has been minimized.

Copy link
@michaliskambi

michaliskambi Jul 31, 2019

Member

Make a newline before if here, we usually write code in CGE like this:

if xxxx then
begin
  ...
end else 
if yyy then
begin
  ...
end;

So the else is at the end of the line with end, not at the beginning of the line with next begin.

This comment has been minimized.

Copy link
@and3md

and3md Aug 1, 2019

Author Contributor

Sometimes I forget in which line what should be, so usually before PR I check all blocks with the open coding convention page. Because I considered this implementation as an early draft, I skipped this step. Now when I know the direction is OK and you want this, I will polish the code :)

FStreamedBuffer := true;
AdjustALLooping;
Stream := TOpenALStreamBuffersBackend(FBuffer);
Stream.AddSoundSource(Self);
end;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.