annotate foosdk/sdk/foobar2000/helpers/writer_wav.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "StdAfx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <vector>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #ifndef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include "winmm-types.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #include "writer_wav.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 #include "audio_render_float.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 static const GUID guid_RIFF = pfc::GUID_from_text("66666972-912E-11CF-A5D6-28DB04C10000");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 static const GUID guid_WAVE = pfc::GUID_from_text("65766177-ACF3-11D3-8CD1-00C04F8EDB8A");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 static const GUID guid_FMT = pfc::GUID_from_text("20746D66-ACF3-11D3-8CD1-00C04F8EDB8A");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 static const GUID guid_DATA = pfc::GUID_from_text("61746164-ACF3-11D3-8CD1-00C04F8EDB8A");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 static const GUID guid_JUNK = pfc::GUID_from_text("6b6E756A-ACF3-11D3-8CD1-00C04f8EDB8A");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 struct RIFF_chunk_desc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 GUID m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 const char * m_name;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 static const RIFF_chunk_desc RIFF_chunks[] = {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 {guid_RIFF, "RIFF"},
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 {guid_WAVE, "WAVE"},
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 {guid_FMT , "fmt "},
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 {guid_DATA, "data"},
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 {guid_JUNK, "JUNK"},
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 bool wavWriterSetup_t::needWFXE() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 if (this->m_bpsValid != this->m_bps) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 switch(m_channels)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 case 1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 return m_channel_mask != audio_chunk::channel_config_mono;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 case 2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 return m_channel_mask != audio_chunk::channel_config_stereo;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 /* case 4:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 m_wfxe = m_setup.m_channel_mask != (audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_back_left | audio_chunk::channel_back_right);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 case 6:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 m_wfxe = m_setup.m_channel_mask != audio_chunk::channel_config_5point1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 break;*/
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 void wavWriterSetup_t::initialize3(const audio_chunk::spec_t & spec, unsigned bps, unsigned bpsValid, bool bFloat, bool bDither, bool bWave64) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 m_bps = bps;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 m_bpsValid = bpsValid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 m_samplerate = spec.sampleRate;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 m_channels = spec.chanCount;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 m_channel_mask = spec.chanMask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 m_float = bFloat;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 m_dither = bDither;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 m_wave64 = bWave64;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 m_rf64_explicit = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 m_rf64_implicit = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 void wavWriterSetup_t::initialize2(const audio_chunk & p_chunk, unsigned p_bps, unsigned p_bpsValid, bool p_float, bool p_dither, bool p_wave64) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 initialize3(p_chunk.get_spec(), p_bps, p_bpsValid, p_float, p_dither, p_wave64);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 void wavWriterSetup_t::initialize(const audio_chunk & p_chunk, unsigned p_bps, bool p_float, bool p_dither, bool p_wave64)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 unsigned bpsValid = p_bps;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 unsigned bps = (p_bps + 7) & ~7;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 initialize2(p_chunk, bps, bpsValid, p_float, p_dither, p_wave64);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 void wavWriterSetup_t::setup_wfx(WAVEFORMATEX & p_wfx)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 p_wfx.wFormatTag = m_float ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 p_wfx.nChannels = m_channels;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 p_wfx.nSamplesPerSec = m_samplerate;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 p_wfx.nAvgBytesPerSec = (m_bps >> 3) * m_channels * m_samplerate;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 p_wfx.nBlockAlign = (m_bps>>3) * m_channels;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 p_wfx.wBitsPerSample = m_bps;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 p_wfx.cbSize = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 void wavWriterSetup_t::setup_wfxe(WAVEFORMATEXTENSIBLE & p_wfxe)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 setup_wfx(p_wfxe.Format);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 p_wfxe.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 p_wfxe.Format.cbSize=22;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 p_wfxe.Samples.wValidBitsPerSample = this->m_bpsValid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 p_wfxe.dwChannelMask = audio_chunk::g_channel_config_to_wfx(m_channel_mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 p_wfxe.SubFormat = m_float ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 void CWavWriter::writeID(const GUID & id, abort_callback & abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 if (is64()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 m_file->write_object_t(id, abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 for( auto & walk : RIFF_chunks) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 if (id == walk.m_guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 m_file->write(walk.m_name, 4, abort); return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 uBugCheck();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 void CWavWriter::writeSize(t_uint64 size, abort_callback & abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 if (is64()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 if (size != UINT64_MAX) size += 24;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 m_file->write_lendian_t(size, abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 t_uint32 clipped;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 if (size > UINT32_MAX) clipped = UINT32_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 else clipped = (t_uint32) size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 m_file->write_lendian_t(clipped, abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 size_t CWavWriter::align(abort_callback & abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 t_uint8 dummy[8] = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 const t_uint32 val = is64() ? 8 : 2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 t_filesize pos = m_file->get_position(abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 t_size delta = (val - (pos%val)) % val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 if (delta > 0) m_file->write(dummy, delta, abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 return delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 void CWavWriter::open(const char * p_path, const wavWriterSetup_t & p_setup, abort_callback & p_abort)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 service_ptr_t<file> l_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 filesystem::g_open_write_new(l_file,p_path,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 open(l_file,p_setup,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 PFC_DECLARE_EXCEPTION(exceptionBadBitDepth, exception_io_data, "Invalid bit depth specified");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 void CWavWriter::open(service_ptr_t<file> p_file, const wavWriterSetup_t & p_setup, abort_callback & p_abort)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 m_file = p_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 m_setup = p_setup;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 if (m_setup.m_channels == 0 || m_setup.m_channels > 18 || m_setup.m_channels != audio_chunk::g_count_channels(m_setup.m_channel_mask)) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 if (!audio_chunk::g_is_valid_sample_rate(m_setup.m_samplerate)) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 if (m_setup.m_bpsValid > m_setup.m_bps) throw exceptionBadBitDepth();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 if (m_setup.m_float)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 if (m_setup.m_bps != 32 && m_setup.m_bps != 64) throw exceptionBadBitDepth();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (m_setup.m_bpsValid != m_setup.m_bps) throw exceptionBadBitDepth();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 if (m_setup.m_bps != 8 && m_setup.m_bps != 16 && m_setup.m_bps != 24 && m_setup.m_bps != 32) throw exceptionBadBitDepth();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 if (m_setup.m_bpsValid < 1) throw exceptionBadBitDepth();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 m_wfxe = m_setup.needWFXE();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 if (m_setup.m_wave64) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 m_file->write_object_t(guid_RIFF, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 } else if (m_setup.m_rf64_explicit) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 m_file->write("RF64", 4, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 m_file->write("RIFF", 4, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 m_offset_fix1 = m_file->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 writeSize(UINT64_MAX, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 writeID(guid_WAVE, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 if (!is64() && m_file->can_seek() && (m_setup.m_rf64_explicit || m_setup.m_rf64_implicit)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 // write JUNK placeholder for DS64
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 m_ds64_at = m_file->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 static const uint8_t dummy[28] = {}; // riffsize64, datasize64, samplecount64, tablecount32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 writeID(guid_JUNK, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 writeSize(sizeof(dummy), p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 m_file->write_object(dummy, sizeof(dummy), p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 writeID(guid_FMT, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if (m_wfxe) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 writeSize(sizeof(WAVEFORMATEXTENSIBLE),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 WAVEFORMATEXTENSIBLE wfxe = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 m_setup.setup_wfxe(wfxe);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 m_file->write_object(&wfxe,sizeof(wfxe),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 writeSize(sizeof(PCMWAVEFORMAT),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 WAVEFORMATEX wfx = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 m_setup.setup_wfx(wfx);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 m_file->write_object(&wfx,/* blah */ sizeof(PCMWAVEFORMAT),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 align(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 writeID(guid_DATA, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 m_offset_fix2 = m_file->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 writeSize(UINT64_MAX, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 m_offset_fix1_delta = m_file->get_position(p_abort) - chunkOverhead();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 m_bytes_written = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 if (!m_setup.m_float)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 m_postprocessor = standard_api_create_t<audio_postprocessor>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 void CWavWriter::write_raw( const void * raw, size_t rawSize, abort_callback & p_abort ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 m_file->write_object(raw,rawSize,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 m_bytes_written += rawSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 void CWavWriter::write(const audio_chunk & p_chunk, abort_callback & p_abort)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 if (p_chunk.get_channels() != m_setup.m_channels
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 || p_chunk.get_channel_config() != m_setup.m_channel_mask
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 || p_chunk.get_srate() != m_setup.m_samplerate
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 ) throw exception_unexpected_audio_format_change();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 if (m_setup.m_float)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 const size_t count = p_chunk.get_channels() * p_chunk.get_sample_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 const void* data = render_float_by_bps(m_setup.m_bps, m_postprocessor_output, p_chunk.get_data(), count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 write_raw(data, count * m_setup.m_bps / 8, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 m_postprocessor->run(p_chunk,m_postprocessor_output,m_setup.m_bpsValid,m_setup.m_bps,m_setup.m_dither,1.0f);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 write_raw( m_postprocessor_output.get_ptr(),m_postprocessor_output.get_size(), p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 void CWavWriter::finalize(abort_callback & p_abort)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 if (m_file.is_valid())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 const size_t alignG = align(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 if (m_file->can_seek()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 m_file->seek(m_offset_fix1,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 const uint64_t riffSize = m_bytes_written + alignG + m_offset_fix1_delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 writeSize(riffSize, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 m_file->seek(m_offset_fix2,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 writeSize(m_bytes_written, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 if (!is64() && (m_setup.m_rf64_explicit || (m_setup.m_rf64_implicit && m_bytes_written > UINT32_MAX))) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 if (!m_setup.m_rf64_explicit) { // turn RIFF into RF64?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 m_file->seek(0, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 m_file->write("RF64", 4, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 m_file->seek(m_ds64_at, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 m_file->write("ds64", 4, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 writeSize(28, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 // RIFF size, data size, sample count
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 m_file->write_lendian_t(riffSize, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 m_file->write_lendian_t(m_bytes_written, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 unsigned sampleBytes = (m_setup.m_bps + 7) / 8 * m_setup.m_channels;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 uint64_t samples = m_bytes_written / sampleBytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 m_file->write_lendian_t(samples, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 uint32_t tableCount = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 m_file->write_lendian_t(tableCount, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 m_file.release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 m_postprocessor.release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 void CWavWriter::close()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 m_file.release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 m_postprocessor.release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 audio_chunk::spec_t CWavWriter::get_spec() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 audio_chunk::spec_t spec = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 spec.sampleRate = m_setup.m_samplerate;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 spec.chanCount = m_setup.m_channels;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 spec.chanMask = m_setup.m_channel_mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 return spec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 class fileWav : public foobar2000_io::file {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 size_t read( void * buffer, size_t bytes, abort_callback & aborter ) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 aborter.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 uint8_t * out = (uint8_t*) buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 size_t ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 if (m_position < m_header.size()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 size_t delta = (size_t) ( m_header.size() - m_position );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 if (delta > bytes) delta = bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 memcpy( out, &m_header[(size_t)m_position], delta );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 m_position += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 out += delta; ret += delta; bytes -= delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 if (bytes > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 m_data->seek( m_position, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 size_t didRead = m_data->read( out, bytes, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 m_position += didRead;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 ret += didRead;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 void write( const void * buffer, size_t bytes, abort_callback & aborter ) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 throw exception_io_denied();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 fileWav( std::vector<uint8_t> const & header, file::ptr data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 m_data = data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 m_header = header;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 fileWav( std::vector<uint8_t> && header, file::ptr data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 m_data = data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 m_header = std::move(header);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 t_filesize get_size(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 t_filesize s = m_data->get_size( p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 if (s != filesize_invalid) s += m_header.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 return s;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 t_filesize get_position(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 return m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 void resize(t_filesize p_size,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 throw exception_io_denied();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 void seek(t_filesize p_position,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 if (p_position > get_size(p_abort)) throw exception_io_seek_out_of_range();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 m_position = p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 bool can_seek() override {return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 bool get_content_type(pfc::string_base & p_out) override { return false; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 void reopen(abort_callback & p_abort) override { seek(0, p_abort); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 bool is_remote() override { return m_data->is_remote(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 std::vector<uint8_t> m_header;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 t_filesize m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 file::ptr m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 static std::vector<uint8_t> makeWavHeader( const wavWriterSetup_t & setup, t_filesize dataSize, abort_callback & aborter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 std::vector<uint8_t> ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 file::ptr temp; filesystem::g_open_tempmem( temp, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 CWavWriter w;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 w.open( temp, setup, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 const size_t s = pfc::downcast_guarded<size_t>( temp->get_size( aborter ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 if (s > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 ret.resize( s );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 temp->seek( 0, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 temp->read_object( &ret[0], s, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 file::ptr makeLiveWAVFile( const wavWriterSetup_t & setup, file::ptr data ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 t_filesize size = data->get_size( fb2k::noAbort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 auto vec = makeWavHeader( setup, size, fb2k::noAbort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 return new service_impl_t< fileWav >( std::move(vec), data );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 }