lsnes/avidump/sox.hpp
2011-09-26 19:02:43 +03:00

99 lines
2.1 KiB
C++

#ifndef _sox__hpp__included__
#define _sox__hpp__included__
#include <cstdint>
#include <fstream>
#include <stdexcept>
#include <vector>
/**
* .sox sound dumper.
*/
class sox_dumper
{
public:
/**
* Create new dumper with specified sound sampling rate and channel count.
*
* parameter filename: The name of file to dump to.
* parameter samplerate: The sampling rate (must be positive)
* parameter channels: The channel count.
*
* throws std::bad_alloc: Not enough memory
* throws std::runtime_error: Error opening .sox file
*/
sox_dumper(const std::string& filename, double samplerate, uint32_t channels) throw(std::bad_alloc,
std::runtime_error);
/**
* Destructor.
*/
~sox_dumper() throw();
/**
* Close the dump.
*
* throws std::bad_alloc: Not enough memory
* throws std::runtime_error: Error fixing and closing .sox file
*/
void close() throw(std::bad_alloc, std::runtime_error);
/**
* Dump a sample
*
* parameters a: Sample channel values.
*/
template<typename... args>
void sample(args... a)
{
sample2<0>(a...);
}
private:
template<size_t o>
void sample2()
{
for(size_t i = o; i < samplebuffer.size(); ++i)
samplebuffer[i] = 0;
internal_dump_sample();
}
template<size_t o, typename itype, typename... args>
void sample2(itype v, args... a)
{
if(o < samplebuffer.size())
place_sample(o, v);
sample2<o + 1>(a...);
}
void place_sample(size_t index, int8_t v)
{
samplebuffer[index] = static_cast<int32_t>(v) << 24;
}
void place_sample(size_t index, uint8_t v)
{
place_sample(index, static_cast<uint32_t>(v) << 24);
}
void place_sample(size_t index, int16_t v)
{
samplebuffer[index] = static_cast<int32_t>(v) << 16;
}
void place_sample(size_t index, uint16_t v)
{
place_sample(index, static_cast<uint32_t>(v) << 16);
}
void place_sample(size_t index, int32_t v)
{
samplebuffer[index] = v;
}
void place_sample(size_t index, uint32_t v)
{
place_sample(index, static_cast<int32_t>(v + 0x80000000U));
}
void internal_dump_sample();
std::vector<char> databuf;
std::vector<int32_t> samplebuffer;
std::ofstream sox_file;
uint64_t samples_dumped;
};
#endif