Fixed music looping

Former-commit-id: 2484c81da5e2f0c0ef72cfbad26e53df129662e7
This commit is contained in:
Lynix 2013-04-02 01:40:19 +02:00
parent 2fb46d6317
commit d989069336
5 changed files with 43 additions and 48 deletions

View File

@ -52,7 +52,7 @@ class NAZARA_API NzMusic : public NzSoundEmitter
bool OpenFromStream(NzInputStream& stream, const NzMusicParams& params = NzMusicParams()); bool OpenFromStream(NzInputStream& stream, const NzMusicParams& params = NzMusicParams());
void Pause(); void Pause();
bool Play(); void Play();
void SetPlayingOffset(nzUInt32 offset); void SetPlayingOffset(nzUInt32 offset);

View File

@ -34,7 +34,7 @@ class NAZARA_API NzSound : public NzSoundEmitter
bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams()); bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams());
void Pause(); void Pause();
bool Play(); void Play();
void SetBuffer(const NzSoundBuffer* buffer); void SetBuffer(const NzSoundBuffer* buffer);
void SetPlayingOffset(nzUInt32 offset); void SetPlayingOffset(nzUInt32 offset);

View File

@ -35,7 +35,7 @@ class NAZARA_API NzSoundEmitter
bool IsSpatialized() const; bool IsSpatialized() const;
virtual void Pause() = 0; virtual void Pause() = 0;
virtual bool Play() = 0; virtual void Play() = 0;
void SetAttenuation(float attenuation); void SetAttenuation(float attenuation);
void SetMinDistance(float minDistance); void SetMinDistance(float minDistance);

View File

@ -22,7 +22,7 @@ struct NzMusicImpl
NzSoundStream* stream; NzSoundStream* stream;
NzThread thread; NzThread thread;
bool loop = false; bool loop = false;
bool playing = false; bool streaming = false;
bool paused = false; bool paused = false;
unsigned int sampleRate; unsigned int sampleRate;
}; };
@ -118,7 +118,7 @@ nzSoundStatus NzMusic::GetStatus() const
nzSoundStatus status = GetInternalStatus(); nzSoundStatus status = GetInternalStatus();
if (m_impl->playing && status == nzSoundStatus_Stopped) if (m_impl->streaming && status == nzSoundStatus_Stopped)
status = nzSoundStatus_Playing; status = nzSoundStatus_Playing;
return status; return status;
@ -154,34 +154,32 @@ bool NzMusic::OpenFromStream(NzInputStream& stream, const NzMusicParams& params)
void NzMusic::Pause() void NzMusic::Pause()
{ {
return; alSourcePause(m_source);
} }
bool NzMusic::Play() void NzMusic::Play()
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
if (!m_impl) if (!m_impl)
{ {
NazaraError("Music not created"); NazaraError("Music not created");
return false; return;
} }
#endif #endif
/*if (m_impl->playing) if (m_impl->streaming)
{ {
if (m_impl->paused) if (GetStatus() != nzSoundStatus_Playing)
alSourcePlay(m_source); alSourcePlay(m_source);
else
// On repositionne au début
m_impl->stream->Seek(0);
return true; return;
}*/ }
m_impl->playing = true; m_impl->stream->Seek(0);
m_impl->streaming = true;
m_impl->thread = NzThread(&NzMusic::MusicThread, this); m_impl->thread = NzThread(&NzMusic::MusicThread, this);
return true; return;
} }
void NzMusic::Stop() void NzMusic::Stop()
@ -194,20 +192,31 @@ void NzMusic::Stop()
} }
#endif #endif
if (m_impl->playing) if (m_impl->streaming)
{ {
m_impl->playing = false; m_impl->streaming = false;
m_impl->thread.Join(); m_impl->thread.Join();
} }
} }
bool NzMusic::FillBuffer(unsigned int buffer) bool NzMusic::FillBuffer(unsigned int buffer)
{ {
unsigned int sampleRead = m_impl->stream->Read(&m_impl->chunkSamples[0], m_impl->chunkSamples.size()); unsigned int sampleCount = m_impl->chunkSamples.size();
unsigned int sampleRead = 0;
for (;;)
{
sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount-sampleRead);
if (sampleRead != sampleCount && m_impl->loop)
m_impl->stream->Seek(0);
else
break;
}
if (sampleRead > 0) if (sampleRead > 0)
alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate); alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate);
return sampleRead != m_impl->chunkSamples.size(); // Fin du fichier return sampleRead != sampleCount; // Fin du fichier (N'arrive pas en cas de loop)
} }
void NzMusic::MusicThread() void NzMusic::MusicThread()
@ -217,52 +226,40 @@ void NzMusic::MusicThread()
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMEDBUFFERCOUNT; ++i) for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMEDBUFFERCOUNT; ++i)
{ {
FillBuffer(buffers[i]); bool eof = FillBuffer(buffers[i]);
alSourceQueueBuffers(m_source, 1, &buffers[i]); alSourceQueueBuffers(m_source, 1, &buffers[i]);
if (eof)
break; // Nous avons fini, nous ne continuons pas
} }
alSourcePlay(m_source); alSourcePlay(m_source);
while (m_impl->playing) while (m_impl->streaming)
{ {
nzSoundStatus status = GetInternalStatus(); nzSoundStatus status = GetInternalStatus();
if (status == nzSoundStatus_Stopped) if (status == nzSoundStatus_Stopped)
{ {
NazaraError("Stopped !"); m_impl->streaming = false;
if (m_impl->loop)
{
m_impl->stream->Seek(0);
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMEDBUFFERCOUNT; ++i)
{
FillBuffer(buffers[i]);
alSourceQueueBuffers(m_source, 1, &buffers[i]);
}
alSourcePlay(m_source);
}
else
m_impl->playing = false;
break; break;
} }
ALint processedCount = 0; ALint processedCount = 0;
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
if (processedCount > 0)
NazaraWarning(NzString::Number(processedCount));
ALuint buffer; ALuint buffer;
while (processedCount--) while (processedCount--)
{ {
alSourceUnqueueBuffers(m_source, 1, &buffer); alSourceUnqueueBuffers(m_source, 1, &buffer);
FillBuffer(buffer); if (!FillBuffer(buffer)) // Fin du fichier ?
alSourceQueueBuffers(m_source, 1, &buffer); alSourceQueueBuffers(m_source, 1, &buffer);
} }
NzThread::Sleep(NAZARA_AUDIO_STREAMEDBUFFERCOUNT*500); NzThread::Sleep(50);
} }
alSourceStop(m_source);
ALint queuedBufferCount; ALint queuedBufferCount;
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);

View File

@ -133,19 +133,17 @@ void NzSound::Pause()
alSourcePause(m_source); alSourcePause(m_source);
} }
bool NzSound::Play() void NzSound::Play()
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("No sound buffer to play"); NazaraError("No sound buffer to play");
return false; return;
} }
#endif #endif
alSourcePlay(m_source); alSourcePlay(m_source);
return true;
} }
void NzSound::SetBuffer(const NzSoundBuffer* buffer) void NzSound::SetBuffer(const NzSoundBuffer* buffer)