libsdr  0.1.0
A simple SDR library
wavfile.hh
1 #ifndef __SDR_WAVFILE_HH__
2 #define __SDR_WAVFILE_HH__
3 
4 #include "node.hh"
5 #include <fstream>
6 
7 namespace sdr {
8 
11 template <class Scalar>
12 class WavSink: public Sink<Scalar>
13 {
14 public:
17  WavSink(const std::string &filename)
18  : Sink<Scalar>(), _file(filename.c_str(), std::ios_base::out|std::ios_base::binary),
20  {
21  if (!_file.is_open()) {
22  ConfigError err;
23  err << "Can not open wav file for output: " << filename;
24  throw err;
25  }
26  // Fill first 36+8 bytes with 0, the headers are written once close() gets called.
27  for (size_t i=0; i<44; i++) { _file.write("\x00", 1); }
28 
29  // check format
30  switch (Config::typeId<Scalar>()) {
31  case Config::Type_u8:
32  case Config::Type_s8:
33  _bitsPerSample = 8;
34  _numChanels = 1;
35  break;
36  case Config::Type_cu8:
37  case Config::Type_cs8:
38  _bitsPerSample = 8;
39  _numChanels = 2;
40  break;
41  case Config::Type_u16:
42  case Config::Type_s16:
43  _bitsPerSample = 16;
44  _numChanels = 1;
45  break;
46  case Config::Type_cu16:
47  case Config::Type_cs16:
48  _bitsPerSample = 16;
49  _numChanels = 2;
50  break;
51  default:
52  ConfigError err;
53  err << "WAV format only allows (real) integer typed data.";
54  throw err;
55  }
56  }
57 
59  virtual ~WavSink() {
60  if (_file.is_open()) {
61  this->close();
62  }
63  }
64 
66  virtual void config(const Config &src_cfg) {
67  // Requires type, samplerate
68  if (!src_cfg.hasType() || !src_cfg.hasSampleRate()) { return; }
69  // Check if type matches
70  if (Config::typeId<Scalar>() != src_cfg.type()) {
71  ConfigError err;
72  err << "Can not configure WavSink: Invalid buffer type " << src_cfg.type()
73  << ", expected " << Config::typeId<Scalar>();
74  throw err;
75  }
76  // Store sample rate
77  _sampleRate = src_cfg.sampleRate();
78  }
79 
81  void close() {
82  if (! _file.is_open()) { return; }
83  uint32_t val4;
84  uint16_t val2;
85 
86  _file.seekp(0);
87  _file.write("RIFF", 4);
88  val4 = (uint32_t)(36u+2u*_frameCount); _file.write((char *)&val4, 4);
89  _file.write("WAVE", 4);
90 
91  _file.write("fmt ", 4);
92  val4 = 16; _file.write((char *)&val4, 4); // sub header size = 16
93  val2 = 1; _file.write((char *)&val2, 2); // format PCM = 1
94  _file.write((char *)&_numChanels, 2); // num chanels = 1
95  _file.write((char *)&_sampleRate, 4);
97  _file.write((char *)&val4, 4); // byte rate
98  val2 = _numChanels*(_bitsPerSample/8);
99  _file.write((char *)&val2, 2); // block align
100  _file.write((char *)&_bitsPerSample, 2); // bits per sample
101 
102  _file.write("data", 4);
103  val4 = _numChanels*_frameCount*(_bitsPerSample/8); _file.write((char *)&val4, 4);
104  _file.close();
105  }
106 
108  virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
109  if (! _file.is_open()) { return; }
110  _file.write(buffer.data(), buffer.size()*sizeof(Scalar));
111  _frameCount += buffer.size();
112  }
113 
114 
115 protected:
117  std::fstream _file;
119  uint16_t _bitsPerSample;
121  uint32_t _frameCount;
123  uint32_t _sampleRate;
125  uint16_t _numChanels;
126 };
127 
128 
129 
133 class WavSource: public Source
134 {
135 public:
137  WavSource(size_t buffer_size=1024);
139  WavSource(const std::string &filename, size_t buffer_size=1024);
141  virtual ~WavSource();
142 
144  bool isOpen() const;
146  void open(const std::string &filename);
148  void close();
149 
151  bool isReal() const;
152 
154  void next();
155 
156 protected:
158  std::fstream _file;
162  size_t _buffer_size;
163 
165  size_t _frame_count;
169  double _sample_rate;
171  size_t _frames_left;
172 };
173 
174 }
175 
176 #endif // __SDR_WAVFILE_HH__
double _sample_rate
The sample rate.
Definition: wavfile.hh:169
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
WavSource(size_t buffer_size=1024)
Constructor, buffer_size specified the output buffer size.
Definition: wavfile.cc:9
Stores the received buffers into a WAV file.
Definition: wavfile.hh:12
Real signed 16b ints.
Definition: node.hh:44
Typed sink.
Definition: node.hh:192
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
Definition: autocast.hh:8
size_t _frames_left
The number of frames left to be read.
Definition: wavfile.hh:171
WavSink(const std::string &filename)
Constructor, filename specifies the file name, the WAV data is stored into.
Definition: wavfile.hh:17
Real signed 8b ints.
Definition: node.hh:42
Definition: operators.hh:9
A simple imput source that reads from a wav file.
Definition: wavfile.hh:133
uint16_t _bitsPerSample
The number of bits per sample (depends on the template type).
Definition: wavfile.hh:119
bool hasSampleRate() const
If true, the configuration has a sample rate.
Definition: node.hh:75
Generic source class.
Definition: node.hh:213
Real unsigned 8b ints.
Definition: node.hh:41
std::fstream _file
The file output stream.
Definition: wavfile.hh:117
void close()
Completes the WAV header and closes the file.
Definition: wavfile.hh:81
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
Config::Type _type
The type of the data in the WAV file.
Definition: wavfile.hh:167
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
Real unsigned 16b ints.
Definition: node.hh:43
size_t _buffer_size
The current buffer size.
Definition: wavfile.hh:162
uint32_t _sampleRate
The sample rate.
Definition: wavfile.hh:123
void open(const std::string &filename)
Open a new file.
Definition: wavfile.cc:33
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Writes some data into the WAV file.
Definition: wavfile.hh:108
Type type() const
Returns the type.
Definition: node.hh:71
uint32_t _frameCount
The total number of frame counts.
Definition: wavfile.hh:121
virtual void config(const Config &src_cfg)
Configures the sink.
Definition: wavfile.hh:66
void close()
Close the current file.
Definition: wavfile.cc:188
void next()
Read the next data.
Definition: wavfile.cc:199
The configuration error class.
Definition: exception.hh:24
virtual ~WavSink()
Destructor, closes the file if not done yet.
Definition: wavfile.hh:59
Type
The type IDs.
Definition: node.hh:39
RawBuffer _buffer
The output buffer.
Definition: wavfile.hh:160
uint16_t _numChanels
The number of chanels.
Definition: wavfile.hh:125
bool isOpen() const
Returns true if the file is open.
Definition: wavfile.cc:28
Complex (aka I/Q) type of signed 8b ints.
Definition: node.hh:48
Complex (aka I/Q) type of signed 16b ints.
Definition: node.hh:50
Complex (aka I/Q) type of unsigned 8b ints.
Definition: node.hh:47
std::fstream _file
The input file stream.
Definition: wavfile.hh:158
bool isReal() const
Returns true, if the input is real (stereo files are handled as I/Q signals).
Definition: wavfile.cc:194
size_t _frame_count
The number of available frames.
Definition: wavfile.hh:165
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77
virtual ~WavSource()
Destructor.
Definition: wavfile.cc:23