OSSIA
Open Scenario System for Interactive Application
drwav_write_handle.hpp
1 #pragma once
2 #include <ossia/dataflow/float_to_sample.hpp>
3 
4 #include <boost/container/vector.hpp>
5 
6 #include <dr_wav.h>
7 
8 #include <ossia-config.hpp>
9 namespace ossia
10 {
11 
12 struct drwav_write_handle
13 {
14  drwav_data_format format;
15  static constexpr auto static_cutoff = 4096 * 2;
16 
17 public:
18  drwav_write_handle()
19  : impl{new drwav}
20  {
21  }
22 
23  ~drwav_write_handle()
24  {
25  close();
26  delete impl;
27  }
28 
29  void open(std::string_view path, int channels, int rate, int bits)
30  {
31  close();
32 
33  if(channels <= 0)
34  return;
35  if(rate <= 0)
36  return;
37  if(path.empty())
38  return;
39 
40  format.container = drwav_container_riff;
41  format.format = DR_WAVE_FORMAT_PCM;
42  format.channels = channels;
43  format.sampleRate = rate;
44  format.bitsPerSample = bits;
45 
46  bool ok = drwav_init_file_write(impl, path.data(), &format, nullptr);
47 
48  buffer.reserve(channels * 8192 * (bits / 8));
49  m_started = ok;
50  m_written_frames = 0;
51  }
52 
53  void close()
54  {
55  if(impl)
56  {
57  if(m_started)
58  {
59  drwav_uninit(impl);
60  }
61  }
62  m_started = false;
63  m_written_frames = 0;
64  }
65 
66  drwav_uint64 write_pcm_frames(drwav_uint64 frames, const double* const* in)
67  {
68  if(!m_started)
69  return 0;
70 
71  this->buffer.clear();
72  this->buffer.resize(
73  frames * format.channels * (format.bitsPerSample / 8),
74  boost::container::default_init);
75 
76  switch(format.bitsPerSample)
77  {
78  case 16:
79  m_written_frames += frames;
80  interleave<int16_t, 16, 2>(
81  in, reinterpret_cast<int16_t*>(buffer.data()), format.channels, frames);
82 
83  return drwav_write_raw(impl, frames * 2 * format.channels, buffer.data());
84  case 24:
85  m_written_frames += frames;
86  interleave<int32_t, 24, 3>(
87  in, reinterpret_cast<int32_t*>(buffer.data()), format.channels, frames);
88 
89  return drwav_write_raw(impl, frames * 3 * format.channels, buffer.data());
90  case 32:
91  m_written_frames += frames;
92  interleave<int32_t, 32, 4>(
93  in, reinterpret_cast<int32_t*>(buffer.data()), format.channels, frames);
94 
95  return drwav_write_raw(impl, frames * 4 * format.channels, buffer.data());
96  break;
97  }
98  return 0;
99  }
100 
101  bool is_open() const noexcept { return m_started; }
102  int64_t written_frames() const noexcept { return m_written_frames; }
103 
104 private:
105  ::drwav* impl{};
106  ossia::pod_vector<char> buffer;
107  bool m_started{};
108  int64_t m_written_frames = 0;
109 };
110 }
Definition: git_info.h:7