OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
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>
9namespace ossia
10{
11
12struct drwav_write_handle
13{
14 drwav_data_format format;
15 static constexpr auto static_cutoff = 4096 * 2;
16
17public:
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
104private:
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