Refactor the way resources are loaded (#191)
* WIP * WIP * Font works * WIP: Only Music remains * Looks like it's working * Fix oopsie * Core/ObjectRef: Add cast functions * Update ChangeLog.md * Audio/SoundStream: Make sound stream thread-safe
This commit is contained in:
@@ -5,9 +5,12 @@
|
||||
#include <Nazara/Audio/Music.hpp>
|
||||
#include <Nazara/Audio/OpenAL.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
@@ -21,24 +24,15 @@ namespace Nz
|
||||
* \remark Module Audio needs to be initialized to use this class
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the parameters for the loading of the music are correct
|
||||
* \return true If parameters are valid
|
||||
*/
|
||||
|
||||
bool MusicParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct MusicImpl
|
||||
{
|
||||
ALenum audioFormat;
|
||||
std::unique_ptr<SoundStream> stream;
|
||||
std::atomic<UInt64> processedSamples;
|
||||
std::vector<Int16> chunkSamples;
|
||||
Mutex bufferLock;
|
||||
SoundStreamRef stream;
|
||||
Thread thread;
|
||||
UInt64 processedSamples;
|
||||
UInt64 playingOffset;
|
||||
bool loop = false;
|
||||
bool streaming = false;
|
||||
unsigned int sampleRate;
|
||||
@@ -74,7 +68,7 @@ namespace Nz
|
||||
m_impl->sampleRate = soundStream->GetSampleRate();
|
||||
m_impl->audioFormat = OpenAL::AudioFormat[format];
|
||||
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
|
||||
m_impl->stream.reset(soundStream);
|
||||
m_impl->stream = soundStream;
|
||||
|
||||
SetPlayingOffset(0);
|
||||
|
||||
@@ -221,9 +215,12 @@ namespace Nz
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the music
|
||||
*/
|
||||
bool Music::OpenFromFile(const String& filePath, const MusicParams& params)
|
||||
bool Music::OpenFromFile(const String& filePath, const SoundStreamParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromFile(this, filePath, params);
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromFile(filePath, params))
|
||||
return Create(soundStream);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -236,9 +233,12 @@ namespace Nz
|
||||
*
|
||||
* \remark The memory pointer must stay valid (accessible) as long as the music is playing
|
||||
*/
|
||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params)
|
||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromMemory(this, data, size, params);
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromMemory(data, size, params))
|
||||
return Create(soundStream);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -250,9 +250,12 @@ namespace Nz
|
||||
*
|
||||
* \remark The stream must stay valid as long as the music is playing
|
||||
*/
|
||||
bool Music::OpenFromStream(Stream& stream, const MusicParams& params)
|
||||
bool Music::OpenFromStream(Stream& stream, const SoundStreamParams& params)
|
||||
{
|
||||
return MusicLoader::LoadFromStream(this, stream, params);
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromStream(stream, params))
|
||||
return Create(soundStream);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -324,7 +327,7 @@ namespace Nz
|
||||
if (isPlaying)
|
||||
Stop();
|
||||
|
||||
m_impl->stream->Seek(offset);
|
||||
m_impl->playingOffset = offset;
|
||||
m_impl->processedSamples = UInt64(offset) * m_impl->sampleRate * m_impl->stream->GetFormat() / 1000ULL;
|
||||
|
||||
if (isPlaying)
|
||||
@@ -349,6 +352,10 @@ namespace Nz
|
||||
std::size_t sampleCount = m_impl->chunkSamples.size();
|
||||
std::size_t sampleRead = 0;
|
||||
|
||||
Nz::LockGuard lock(m_impl->stream->GetMutex());
|
||||
|
||||
m_impl->stream->Seek(m_impl->playingOffset);
|
||||
|
||||
// Fill the buffer by reading from the stream
|
||||
for (;;)
|
||||
{
|
||||
@@ -364,6 +371,10 @@ namespace Nz
|
||||
break;
|
||||
}
|
||||
|
||||
m_impl->playingOffset = m_impl->stream->Tell();
|
||||
|
||||
lock.Unlock();
|
||||
|
||||
// Update the buffer (send it to OpenAL) and queue it if we got any data
|
||||
if (sampleRead > 0)
|
||||
{
|
||||
@@ -380,9 +391,9 @@ namespace Nz
|
||||
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
|
||||
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
|
||||
|
||||
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
|
||||
for (unsigned int buffer : buffers)
|
||||
{
|
||||
if (FillAndQueueBuffer(buffers[i]))
|
||||
if (FillAndQueueBuffer(buffer))
|
||||
break; // We have reached the end of the stream, there is no use to add new buffers
|
||||
}
|
||||
|
||||
@@ -448,6 +459,4 @@ namespace Nz
|
||||
m_impl->thread.Join();
|
||||
}
|
||||
}
|
||||
|
||||
MusicLoader::LoaderList Music::s_loaders;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user