Added new Class for playing WAVE files from memory

Signed-off-by: Ralf Ramsauer <ralf@ramses-pyramidenbau.de>
This commit is contained in:
Ralf Ramsauer 2015-10-11 19:06:05 +02:00
parent bb703cb5b5
commit 365bdb755c
2 changed files with 121 additions and 0 deletions

86
doorlockd/client/wave.cpp Normal file
View File

@ -0,0 +1,86 @@
#include <cstring>
#include <fstream>
#include <stdexcept>
#include <sndfile.h>
#include "wave.h"
Wave::Wave(int bits,
int channels,
int rate,
Raw data) :
_format(new ao_sample_format),
_data(data)
{
_format->bits = bits;
_format->rate = rate;
_format->channels = channels;
_format->byte_format = AO_FMT_LITTLE;
_format->matrix = nullptr;
int default_driver;
default_driver = ao_default_driver_id();
_device = ao_open_live(default_driver,
_format.get(),
nullptr);
}
Wave::~Wave()
{
if (_device != nullptr)
ao_close(_device);
}
Wave Wave::fromFile(const std::string &filename)
{
SF_INFO sfinfo;
SNDFILE *file = sf_open(filename.c_str(), SFM_READ, &sfinfo);
if (file == nullptr)
throw std::runtime_error("Unable to open soundfile " + filename);
size_t rawSize = sfinfo.channels * sfinfo.frames * sizeof(short);
Raw data;
data.resize(rawSize);
sf_read_raw(file, &data.front(), data.size());
sf_close(file);
int bits;
switch (sfinfo.format & SF_FORMAT_SUBMASK) {
case SF_FORMAT_PCM_16:
bits = 16;
break;
case SF_FORMAT_PCM_24:
bits = 24;
break;
case SF_FORMAT_PCM_32:
bits = 32;
break;
case SF_FORMAT_PCM_S8:
bits = 8;
break;
case SF_FORMAT_PCM_U8:
bits = 8;
break;
default:
bits = 16;
break;
}
return Wave(bits,
sfinfo.channels,
sfinfo.samplerate,
data);
}
void Wave::play() const
{
if (_device == nullptr) {
return;
}
ao_play(_device,
(char*)&_data.front(),
_data.size());
}

35
doorlockd/client/wave.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef WAVE_H
#define WAVE_H
#include <string>
#include <vector>
#include <memory>
#include <ao/ao.h>
class Wave {
public:
using Raw = std::vector<char>;
static Wave fromFile(const std::string &filename);
Wave(int bits,
int channels,
int rate,
Raw data);
Wave(const Wave &rhs);
~Wave();
Wave &operator=(const Wave &rhs);
void play() const;
private:
std::unique_ptr<ao_sample_format> _format;
ao_device* _device = { nullptr };
const Raw _data;
};
#endif