Skip to content

Commit

Permalink
#5345: Improve TaskQueue and start working on SoundManager::getSoundF…
Browse files Browse the repository at this point in the history
…ileDuration
  • Loading branch information
codereader committed Oct 4, 2020
1 parent 4ceae9e commit b77ff04
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 94 deletions.
4 changes: 4 additions & 0 deletions include/isound.h
Expand Up @@ -121,6 +121,10 @@ class ISoundManager :
*/
virtual void stopSound() = 0;

// Returns the duration of the given sound file in seconds
// Will throw a std::out_of_range exception if the path cannot be resolved
virtual float getSoundFileDuration(const std::string& vfsPath) = 0;

// Reloads all sound shader definitions from the VFS
virtual void reloadSounds() = 0;

Expand Down
47 changes: 35 additions & 12 deletions libs/TaskQueue.h
Expand Up @@ -11,11 +11,12 @@ namespace util
class TaskQueue
{
private:
std::mutex _lock;

mutable std::mutex _queueLock;
std::list<std::function<void()>> _queue;

mutable std::mutex _currentLock;
std::future<void> _current;
std::future<void> _finished;

public:
~TaskQueue()
Expand All @@ -28,7 +29,7 @@ class TaskQueue
void enqueue(const std::function<void()>& task)
{
{
std::lock_guard<std::mutex> lock(_lock);
std::lock_guard<std::mutex> lock(_queueLock);
_queue.push_front(task);
}

Expand All @@ -44,38 +45,60 @@ class TaskQueue
{
{
// Lock the queue and remove any tasks such that no new ones are added
std::lock_guard<std::mutex> lock(_lock);
std::lock_guard<std::mutex> lock(_queueLock);
_queue.clear();
}

// Clear (and possibly) wait for the currently active future object
_current = std::future<void>();
_finished = std::future<void>();
}

private:
bool isIdle() const
{
return !_current.valid() ||
_current.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
std::lock_guard<std::mutex> lock(_currentLock);
return !_current.valid() || _current.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}

void startNextTask()
std::function<void()> dequeueOne()
{
std::lock_guard<std::mutex> lock(_lock);
std::lock_guard<std::mutex> lock(_queueLock);

if (_queue.empty())
{
return;
return std::function<void()>();
}

// No active task, dispatch a new one
auto frontOfQueue = _queue.front();
_queue.pop_front();

return frontOfQueue;
}

void startNextTask()
{
auto task = dequeueOne();

if (!task)
{
return;
}

// Wrap the given task in our own lambda to start the next task right afterwards
_current = std::async(std::launch::async, [this, frontOfQueue]()
std::lock_guard<std::mutex> lock(_currentLock);
_current = std::async(std::launch::async, [this, task]()
{
frontOfQueue();
task();

{
// Move our own task to the finished lane,
// to avoid blocking when assigning a new future
std::lock_guard<std::mutex> lock(_currentLock);
_finished = std::move(_current);
}

// _current is now empty, so we can start a new task
startNextTask();
});
}
Expand Down
122 changes: 75 additions & 47 deletions plugins/sound/SoundManager.cpp
Expand Up @@ -5,13 +5,61 @@
#include "icommandsystem.h"

#include "debugging/ScopedDebugTimer.h"
#include "os/path.h"
#include "string/case_conv.h"

#include <algorithm>
#include "itextstream.h"

#include "WavFileLoader.h"

namespace sound
{

namespace
{

// Load the given file, trying different extensions (first OGG, then WAV) as fallback
ArchiveFilePtr openSoundFile(const std::string& fileName)
{
// Make a copy of the filename
std::string name = fileName;

// Try to open the file as it is
auto file = GlobalFileSystem().openFile(name);

if (file)
{
// File found, play it
return file;
}

std::string root = name;

// File not found, try to strip the extension
if (name.rfind(".") != std::string::npos)
{
root = name.substr(0, name.rfind("."));
}

// Try to open the .ogg variant
name = root + ".ogg";

file = GlobalFileSystem().openFile(name);

if (file)
{
return file;
}

// Try to open the file with .wav extension
name = root + ".wav";

return GlobalFileSystem().openFile(name);
}

}

// Constructor
SoundManager::SoundManager() :
_defLoader(std::bind(&SoundManager::loadShadersFromFilesystem, this)),
Expand All @@ -36,58 +84,15 @@ bool SoundManager::playSound(const std::string& fileName)

bool SoundManager::playSound(const std::string& fileName, bool loopSound)
{
// Make a copy of the filename
std::string name = fileName;

// Try to open the file as it is
ArchiveFilePtr file = GlobalFileSystem().openFile(name);
rConsole() << "Trying: " << name << std::endl;

if (file)
{
// File found, play it
rConsole() << "Found file: " << name << std::endl;
if (_soundPlayer) _soundPlayer->play(*file, loopSound);
return true;
}

std::string root = name;

// File not found, try to strip the extension
if (name.rfind(".") != std::string::npos)
{
root = name.substr(0, name.rfind("."));
}

// Try to open the .ogg variant
name = root + ".ogg";

rConsole() << "Trying: " << name << std::endl;

file = GlobalFileSystem().openFile(name);

if (file)
{
rConsole() << "Found file: " << name << std::endl;
if (_soundPlayer) _soundPlayer->play(*file, loopSound);
return true;
}

// Try to open the file with .wav extension
name = root + ".wav";
rConsole() << "Trying: " << name << std::endl;

file = GlobalFileSystem().openFile(name);
auto file = openSoundFile(fileName);

if (file)
if (file && _soundPlayer)
{
rConsole() << "Found file: " << name << std::endl;
if (_soundPlayer) _soundPlayer->play(*file, loopSound);
_soundPlayer->play(*file, loopSound);
return true;
}

// File not found
return false;
return false;
}

void SoundManager::stopSound()
Expand Down Expand Up @@ -172,6 +177,29 @@ void SoundManager::initialiseModule(const IApplicationContext& ctx)
_defLoader.start();
}

float SoundManager::getSoundFileDuration(const std::string& vfsPath)
{
auto file = openSoundFile(vfsPath);

if (!file)
{
throw std::out_of_range("Could not resolve sound file " + vfsPath);
}

auto extension = string::to_lower_copy(os::getExtension(file->getName()));

if (extension == "wav")
{
return WavFileLoader::GetDuration(file->getInputStream());
}
else if (extension == "ogg")
{
return 23.45f;
}

return 0.0f;
}

void SoundManager::reloadSounds()
{
_defLoader.reset();
Expand Down
1 change: 1 addition & 0 deletions plugins/sound/SoundManager.h
Expand Up @@ -50,6 +50,7 @@ class SoundManager :
bool playSound(const std::string& fileName, bool loopSound) override;
void stopSound() override;
void reloadSounds() override;
float getSoundFileDuration(const std::string& vfsPath) override;
sigc::signal<void>& signal_soundShadersReloaded() override;

// RegisterableModule implementation
Expand Down
40 changes: 10 additions & 30 deletions plugins/sound/WavFileLoader.h
Expand Up @@ -22,6 +22,10 @@ namespace sound {
class WavFileLoader
{
public:
static float GetDuration(InputStream& stream)
{
return -1.0f;
}

/**
* greebo: Loads a WAV file from a stream into OpenAL,
Expand Down Expand Up @@ -94,37 +98,13 @@ class WavFileLoader
unsigned short bps = 0;
stream.read(reinterpret_cast<byte*>(&bps), 2);

//int bufferSize = 0;

if (channels == 1) {
if (bps == 8) {
format = AL_FORMAT_MONO8;
// Set BufferSize to 250ms (Frequency divided by 4 (quarter of a second))
//bufferSize = freq / 4;
}
else {
format = AL_FORMAT_MONO16;
// Set BufferSize to 250ms (Frequency * 2 (16bit) divided by 4 (quarter of a second))
//bufferSize = freq >> 1;
// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
//bufferSize -= (bufferSize % 2);
}
if (channels == 1)
{
format = bps == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16;
}
else {
if (bps == 8) {
format = AL_FORMAT_STEREO16;
// Set BufferSize to 250ms (Frequency * 2 (8bit stereo) divided by 4 (quarter of a second))
//bufferSize = freq >> 1;
// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
//bufferSize -= (bufferSize % 2);
}
else {
format = AL_FORMAT_STEREO16;
// Set BufferSize to 250ms (Frequency * 4 (16bit stereo) divided by 4 (quarter of a second))
//bufferSize = freq;
// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
//bufferSize -= (bufferSize % 4);
}
else
{
format = bps == 8 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO16;
}

// check 'data' sub chunk (2)
Expand Down

0 comments on commit b77ff04

Please sign in to comment.