wavfile.hh
#ifndef __SDR_WAVFILE_HH__
#define __SDR_WAVFILE_HH__
#include "node.hh"
#include <fstream>
namespace sdr {
template <class Scalar>
class WavSink: public Sink<Scalar>
{
public:
WavSink(const std::string &filename)
: Sink<Scalar>(), _file(filename.c_str(), std::ios_base::out|std::ios_base::binary),
_frameCount(0), _sampleRate(0)
{
if (!_file.is_open()) {
ConfigError err;
err << "Can not open wav file for output: " << filename;
throw err;
}
// Fill first 36+8 bytes with 0, the headers are written once close() gets called.
for (size_t i=0; i<44; i++) { _file.write("\x00", 1); }
// check format
switch (Config::typeId<Scalar>()) {
case Config::Type_u8:
case Config::Type_s8:
_bitsPerSample = 8;
_numChanels = 1;
break;
case Config::Type_cu8:
case Config::Type_cs8:
_bitsPerSample = 8;
_numChanels = 2;
break;
case Config::Type_u16:
case Config::Type_s16:
_bitsPerSample = 16;
_numChanels = 1;
break;
case Config::Type_cu16:
case Config::Type_cs16:
_bitsPerSample = 16;
_numChanels = 2;
break;
default:
ConfigError err;
err << "WAV format only allows (real) integer typed data.";
throw err;
}
}
virtual ~WavSink() {
if (_file.is_open()) {
this->close();
}
}
virtual void config(const Config &src_cfg) {
// Requires type, samplerate
if (!src_cfg.hasType() || !src_cfg.hasSampleRate()) { return; }
// Check if type matches
if (Config::typeId<Scalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure WavSink: Invalid buffer type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// Store sample rate
_sampleRate = src_cfg.sampleRate();
}
void close() {
if (! _file.is_open()) { return; }
uint32_t val4;
uint16_t val2;
_file.seekp(0);
_file.write("RIFF", 4);
val4 = (uint32_t)(36u+2u*_frameCount); _file.write((char *)&val4, 4);
_file.write("WAVE", 4);
_file.write("fmt ", 4);
val4 = 16; _file.write((char *)&val4, 4); // sub header size = 16
val2 = 1; _file.write((char *)&val2, 2); // format PCM = 1
_file.write((char *)&_numChanels, 2); // num chanels = 1
_file.write((char *)&_sampleRate, 4);
val4 = _numChanels*_sampleRate*(_bitsPerSample/8);
_file.write((char *)&val4, 4); // byte rate
val2 = _numChanels*(_bitsPerSample/8);
_file.write((char *)&val2, 2); // block align
_file.write((char *)&_bitsPerSample, 2); // bits per sample
_file.write("data", 4);
val4 = _numChanels*_frameCount*(_bitsPerSample/8); _file.write((char *)&val4, 4);
_file.close();
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
if (! _file.is_open()) { return; }
_file.write(buffer.data(), buffer.size()*sizeof(Scalar));
_frameCount += buffer.size();
}
protected:
std::fstream _file;
uint16_t _bitsPerSample;
uint32_t _frameCount;
uint32_t _sampleRate;
uint16_t _numChanels;
};
class WavSource: public Source
{
public:
WavSource(size_t buffer_size=1024);
WavSource(const std::string &filename, size_t buffer_size=1024);
virtual ~WavSource();
bool isOpen() const;
void open(const std::string &filename);
void close();
bool isReal() const;
void next();
protected:
std::fstream _file;
RawBuffer _buffer;
size_t _buffer_size;
size_t _frame_count;
Config::Type _type;
double _sample_rate;
size_t _frames_left;
};
}
#endif // __SDR_WAVFILE_HH__
sdr::WavSource::_sample_rate
double _sample_rate
The sample rate.
Definition: wavfile.hh:169
sdr::Config
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
sdr::RawBuffer
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
sdr::WavSource::WavSource
WavSource(size_t buffer_size=1024)
Constructor, buffer_size specified the output buffer size.
Definition: wavfile.cc:9
sdr::WavSink
Stores the received buffers into a WAV file.
Definition: wavfile.hh:12
sdr::Config::Type_s16
Real signed 16b ints.
Definition: node.hh:44
sdr::Sink
Typed sink.
Definition: node.hh:192
sdr::Config::Type_cu16
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
sdr
Definition: autocast.hh:8
sdr::WavSource::_frames_left
size_t _frames_left
The number of frames left to be read.
Definition: wavfile.hh:171
sdr::WavSink::WavSink
WavSink(const std::string &filename)
Constructor, filename specifies the file name, the WAV data is stored into.
Definition: wavfile.hh:17
sdr::Config::Type_s8
Real signed 8b ints.
Definition: node.hh:42
std
Definition: operators.hh:9
sdr::WavSource
A simple imput source that reads from a wav file.
Definition: wavfile.hh:133
sdr::WavSink::_bitsPerSample
uint16_t _bitsPerSample
The number of bits per sample (depends on the template type).
Definition: wavfile.hh:119
sdr::Config::hasSampleRate
bool hasSampleRate() const
If true, the configuration has a sample rate.
Definition: node.hh:75
sdr::Source
Generic source class.
Definition: node.hh:213
sdr::Config::Type_u8
Real unsigned 8b ints.
Definition: node.hh:41
sdr::WavSink::_file
std::fstream _file
The file output stream.
Definition: wavfile.hh:117
sdr::WavSink::close
void close()
Completes the WAV header and closes the file.
Definition: wavfile.hh:81
sdr::Buffer::size
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
sdr::Config::hasType
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
sdr::WavSource::_type
Config::Type _type
The type of the data in the WAV file.
Definition: wavfile.hh:167
sdr::RawBuffer::data
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
sdr::Config::Type_u16
Real unsigned 16b ints.
Definition: node.hh:43
sdr::WavSource::_buffer_size
size_t _buffer_size
The current buffer size.
Definition: wavfile.hh:162
sdr::WavSink::_sampleRate
uint32_t _sampleRate
The sample rate.
Definition: wavfile.hh:123
sdr::WavSource::open
void open(const std::string &filename)
Open a new file.
Definition: wavfile.cc:33
sdr::WavSink::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Writes some data into the WAV file.
Definition: wavfile.hh:108
sdr::Config::type
Type type() const
Returns the type.
Definition: node.hh:71
sdr::WavSink::_frameCount
uint32_t _frameCount
The total number of frame counts.
Definition: wavfile.hh:121
sdr::WavSink::config
virtual void config(const Config &src_cfg)
Configures the sink.
Definition: wavfile.hh:66
sdr::WavSource::close
void close()
Close the current file.
Definition: wavfile.cc:188
sdr::WavSource::next
void next()
Read the next data.
Definition: wavfile.cc:199
sdr::ConfigError
The configuration error class.
Definition: exception.hh:24
sdr::WavSink::~WavSink
virtual ~WavSink()
Destructor, closes the file if not done yet.
Definition: wavfile.hh:59
sdr::Config::Type
Type
The type IDs.
Definition: node.hh:39
sdr::WavSource::_buffer
RawBuffer _buffer
The output buffer.
Definition: wavfile.hh:160
sdr::WavSink::_numChanels
uint16_t _numChanels
The number of chanels.
Definition: wavfile.hh:125
sdr::WavSource::isOpen
bool isOpen() const
Returns true if the file is open.
Definition: wavfile.cc:28
sdr::Config::Type_cs8
Complex (aka I/Q) type of signed 8b ints.
Definition: node.hh:48
sdr::Config::Type_cs16
Complex (aka I/Q) type of signed 16b ints.
Definition: node.hh:50
sdr::Config::Type_cu8
Complex (aka I/Q) type of unsigned 8b ints.
Definition: node.hh:47
sdr::WavSource::_file
std::fstream _file
The input file stream.
Definition: wavfile.hh:158
sdr::WavSource::isReal
bool isReal() const
Returns true, if the input is real (stereo files are handled as I/Q signals).
Definition: wavfile.cc:194
sdr::WavSource::_frame_count
size_t _frame_count
The number of available frames.
Definition: wavfile.hh:165
sdr::Buffer< Scalar >
sdr::Config::sampleRate
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77
sdr::WavSource::~WavSource
virtual ~WavSource()
Destructor.
Definition: wavfile.cc:23