@@ -21,25 +21,30 @@ namespace sndx::audio {
2121 static constexpr std::array<char , 4 > ID = { ' f' , ' m' , ' t' , ' ' };
2222
2323 struct ExtendedNone {
24- static void deserialize (const serialize::Deserializer&) {};
25- static void serialize (const serialize::Serializer&) {};
24+ template <class DeserializeIt >
25+ static constexpr void deserialize (DeserializeIt&, DeserializeIt) {};
26+
27+ template <class SerializeIt >
28+ static constexpr void serialize (SerializeIt&) {};
2629
2730 static constexpr uint32_t size () noexcept {
2831 return 0 + 16 ;
2932 }
3033 };
3134
3235 struct Extended0 {
33- static void deserialize (serialize::Deserializer& deserializer) {
36+ template <class DeserializeIt >
37+ static constexpr void deserialize (DeserializeIt& in, DeserializeIt end) {
3438 uint16_t size;
35- deserializer. deserialize <std::endian::little> (size);
39+ deserializeFromAdjust (size, in, end );
3640
3741 if (size != 0 )
3842 throw deserialize_error (" Extended0 didn't have size 0" );
3943 };
4044
41- static void serialize (serialize::Serializer& serializer) noexcept {
42- serializer.serialize <std::endian::little>(static_cast <uint16_t >(0 ));
45+ template <class SerializeIt >
46+ static constexpr void serialize (SerializeIt& out) noexcept {
47+ serializeToAdjust (out, static_cast <uint16_t >(0 ));
4348 };
4449
4550 static constexpr uint32_t size () noexcept {
@@ -50,28 +55,30 @@ namespace sndx::audio {
5055 struct Extended {
5156 uint16_t validBitsPerSample = 0 ;
5257 uint32_t channelMask = 0 ;
53- char guid[ 16 ] = { 0 };
58+ std::array< char , 16 > guid { 0 };
5459
5560 static constexpr uint16_t dataSize = sizeof (validBitsPerSample) + sizeof (channelMask) + sizeof (guid);
5661
57- void deserialize (serialize::Deserializer& deserializer) {
62+ template <class DeserializeIt >
63+ constexpr void deserialize (DeserializeIt& in, DeserializeIt end) {
5864 uint16_t size;
59- deserializer. deserialize <std::endian::little> (size);
65+ deserializeFromAdjust (size, in, end );
6066
6167 if (size != dataSize)
6268 throw deserialize_error (" Extended format didn't have size 22" );
6369
64- deserializer. deserialize <std::endian::little> (validBitsPerSample);
65- deserializer. deserialize <std::endian::little> (channelMask);
66- deserializer. deserialize (guid, sizeof (guid) );
70+ deserializeFromAdjust (validBitsPerSample, in, end );
71+ deserializeFromAdjust (channelMask, in, end );
72+ deserializeFromAdjust (guid, in, end );
6773 };
6874
69- void serialize (serialize::Serializer& serializer) const {
70- serializer.serialize <std::endian::little>(dataSize);
75+ template <class SerializeIt >
76+ void serialize (SerializeIt& out) const {
77+ serializeToAdjust (out, dataSize);
7178
72- serializer. serialize <std::endian::little>( validBitsPerSample);
73- serializer. serialize <std::endian::little>( channelMask);
74- serializer. serialize (guid, sizeof ( guid) );
79+ serializeToAdjust (out, validBitsPerSample);
80+ serializeToAdjust (out, channelMask);
81+ serializeToAdjust (out, guid);
7582 };
7683
7784 static constexpr uint32_t size () noexcept {
@@ -102,7 +109,7 @@ namespace sndx::audio {
102109 ext = Extended ();
103110 break ;
104111 default :
105- throw deserialize_error (" Invalid fmt size" );
112+ throw bad_field_error (" Invalid fmt size" );
106113 }
107114 }
108115
@@ -111,36 +118,42 @@ namespace sndx::audio {
111118 return blockAlign / channels;
112119 }
113120
114- void deserialize (serialize::Deserializer& deserializer) override {
115- deserializer.deserialize <std::endian::little>(format);
116- deserializer.deserialize <std::endian::little>(channels);
117- deserializer.deserialize <std::endian::little>(sampleRate);
118- deserializer.deserialize <std::endian::little>(byteRate);
119- deserializer.deserialize <std::endian::little>(blockAlign);
120- deserializer.deserialize <std::endian::little>(bitDepth);
121+ void deserialize (const std::vector<uint8_t >& in) override {
122+ auto it = in.begin ();
123+ deserializeFromAdjust (format, it, in.end ());
124+ deserializeFromAdjust (channels, it, in.end ());
125+ deserializeFromAdjust (sampleRate, it, in.end ());
126+ deserializeFromAdjust (byteRate, it, in.end ());
127+ deserializeFromAdjust (blockAlign, it, in.end ());
128+ deserializeFromAdjust (bitDepth, it, in.end ());
121129
122- std::visit ([&deserializer ]<typename T>(T&& arg) {
123- deserializer. deserialize (std::forward<T>(arg));
130+ std::visit ([&it, end = in. end () ]<typename T>(T&& arg) {
131+ deserializeFromAdjust (std::forward<T>(arg), it, end );
124132 }, ext);
125133 };
126134
127- void serialize (serialize::Serializer& serializer) const override {
128- serializer.serialize (" fmt " , 4 );
135+ std::vector<uint8_t > serialize () const override {
136+ std::vector<uint8_t > out{};
137+ auto it = std::back_inserter (out);
138+
139+ serializeToAdjust (it, std::array{ ' f' , ' m' , ' t' , ' ' });
129140
130- std::visit ([&serializer ]<typename T>(const T&) {
131- serializer. serialize <std::endian::little>( static_cast <uint32_t >(T::size ()));
141+ std::visit ([&it ]<typename T>(const T&) {
142+ serializeToAdjust (it, static_cast <uint32_t >(T::size ()));
132143 }, ext);
133144
134- serializer. serialize <std::endian::little>( format);
135- serializer. serialize <std::endian::little>( channels);
136- serializer. serialize <std::endian::little>( sampleRate);
137- serializer. serialize <std::endian::little>( byteRate);
138- serializer. serialize <std::endian::little>( blockAlign);
139- serializer. serialize <std::endian::little>( bitDepth);
140-
141- std::visit ([&serializer ]<typename T>(T&& arg) {
142- serializer. serialize (std::forward<T>( arg) );
145+ serializeToAdjust (it, format);
146+ serializeToAdjust (it, channels);
147+ serializeToAdjust (it, sampleRate);
148+ serializeToAdjust (it, byteRate);
149+ serializeToAdjust (it, blockAlign);
150+ serializeToAdjust (it, bitDepth);
151+
152+ std::visit ([&it ]<typename T>(T&& arg) {
153+ serializeToAdjust (it, arg);
143154 }, ext);
155+
156+ return out;
144157 };
145158
146159 [[nodiscard]]
@@ -180,15 +193,19 @@ namespace sndx::audio {
180193
181194 explicit constexpr FACTchunk (const RIFF::ChunkHeader&) noexcept {};
182195
183- void deserialize (serialize::Deserializer& deserializer ) override {
184- deserializer. deserialize <std::endian::little> (sampleLength);
196+ void deserialize (const std::vector< uint8_t >& data ) override {
197+ sndx::deserialize (sampleLength, data );
185198 }
186199
187- void serialize (serialize::Serializer& serializer) const override {
188- serializer.serialize (" fact" , 4 );
189- serializer.serialize <std::endian::little>(static_cast <uint32_t >(sizeof (sampleLength)));
200+ std::vector<uint8_t > serialize () const override {
201+ std::vector<uint8_t > out{};
202+ auto it = std::back_inserter (out);
203+
204+ serializeToAdjust (it, std::array{ ' f' , ' a' , ' c' , ' t' });
205+ serializeToAdjust (it, static_cast <uint32_t >(sizeof (sampleLength)));
206+ serializeToAdjust (it, sampleLength);
190207
191- serializer. serialize <std::endian::little>(sampleLength) ;
208+ return out ;
192209 }
193210
194211 [[nodiscard]]
@@ -208,25 +225,29 @@ namespace sndx::audio {
208225 data.resize (header.size );
209226 }
210227
211- void deserialize (serialize::Deserializer& deserializer) override {
212- deserializer.deserialize (data.data (), data.size ());
213-
214- uint8_t padding = 0 ;
215- if (data.size () % 2 == 1 )
216- deserializer.deserialize (padding);
228+ void deserialize (const std::vector<uint8_t >& data) override {
229+ auto it = data.begin ();
230+ for (auto & b : this ->data ) {
231+ deserializeFromAdjust (b, it, data.end ());
232+ }
217233 }
218234
219- void serialize (serialize::Serializer& serializer) const override {
220- serializer.serialize (" data" , 4 );
221- serializer.serialize <std::endian::little>(static_cast <uint32_t >(data.size ()));
235+ std::vector<uint8_t > serialize () const override {
236+ std::vector<uint8_t > out{};
237+ auto it = std::back_inserter (out);
238+
239+ serializeToAdjust (it, std::array{ ' d' , ' a' , ' t' , ' a' });
240+ serializeToAdjust (it, static_cast <uint32_t >(data.size ()));
222241
223242 for (const auto & b : data) {
224- serializer. serialize ( b);
243+ serializeToAdjust (it, b);
225244 }
226245
227246 if (data.size () % 2 == 1 ) {
228- serializer. serialize ( static_cast <uint8_t >(0 ));
247+ serializeToAdjust (it, static_cast <uint8_t >(0 ));
229248 }
249+
250+ return out;
230251 }
231252
232253 [[nodiscard]]
@@ -307,20 +328,25 @@ namespace sndx::audio {
307328 return *m_fmt;
308329 }
309330
310- void deserialize (serialize::Deserializer& deserializer) {
311- m_file.deserialize (deserializer, ID);
331+ template <class InputIt >
332+ void deserialize (InputIt& in, InputIt end) {
333+ deserializeFromAdjust (m_file, in, end);
334+
335+ if (m_file.getHeader ().type != ID)
336+ throw bad_field_error (" WAVE file missing WAVE" );
312337
313338 m_fmt = m_file.getChunk <FMTchunk>();
314339 m_data = m_file.getChunk <DATAchunk>();
315340
316341 if (!m_fmt || !m_data)
317- throw deserialize_error (" WAVE file missing fmt or data" );
342+ throw bad_field_error (" WAVE file missing fmt or data" );
318343 }
319344
320- void serialize (serialize::Serializer& serializer) const {
345+ template <class SerializeIt >
346+ void serialize (SerializeIt& it) const {
321347
322348 if (!m_fmt || !m_data)
323- throw serialize_error (" WAVE file missing fmt or data" );
349+ throw std::logic_error (" WAVE file missing fmt or data" );
324350
325351 auto tmp = m_file.getHeader ();
326352 const auto & chunks = m_file.getChunks ();
@@ -330,8 +356,12 @@ namespace sndx::audio {
330356 tmp.size += chunk->getLength ();
331357 }
332358
333- serializer.serialize (tmp);
334- serializer.serialize (*m_fmt);
359+ serializeToAdjust (it, tmp);
360+
361+ auto buf = m_fmt->serialize ();
362+ for (auto b : buf) {
363+ serializeToAdjust (it, b);
364+ }
335365
336366 for (const auto & [id, chunk] : chunks) {
337367 if (id == RIFF::idToRawID (FMTchunk::ID) ||
@@ -340,10 +370,16 @@ namespace sndx::audio {
340370 continue ;
341371 }
342372
343- serializer.serialize (*chunk);
373+ buf = chunk->serialize ();
374+ for (auto b : buf) {
375+ serializeToAdjust (it, b);
376+ }
344377 }
345378
346- serializer.serialize (*m_data);
379+ buf = m_fmt->serialize ();
380+ for (auto b : buf) {
381+ serializeToAdjust (it, b);
382+ }
347383 }
348384 };
349385
@@ -362,36 +398,39 @@ namespace sndx::audio {
362398 explicit WAVdecoder (std::istream& stream) :
363399 m_stream(stream.rdbuf()) {
364400
365- serialize::Deserializer deserializer{ stream } ;
366- bool seekable = true ;
401+ auto it = std::istream_iterator< uint8_t >(stream) ;
402+ auto end = std::istream_iterator< uint8_t >() ;
367403
368404 RIFF::RIFFheader head;
369- deserializer. deserialize (head);
405+ deserializeFromAdjust (head, it, end );
370406
371407 if (head.type != std::array<char , 4 >{' W' , ' A' , ' V' , ' E' })
372- throw identifier_error (" RIFF file is not WAVE" );
408+ throw bad_field_error (" RIFF file is not WAVE" );
373409
374410 RIFF::ChunkHeader header;
375- deserializer. deserialize (header);
411+ deserializeFromAdjust (header, it, end );
376412
377413
378414 if (header.id != std::array<char , 4 >{' f' , ' m' , ' t' , ' ' })
379- throw identifier_error (" fmt not first subchunk in RIFF" );
415+ throw bad_field_error (" fmt not first subchunk in RIFF" );
380416
381417 m_meta = FMTchunk (header);
382- deserializer.deserialize (m_meta);
418+ std::vector<uint8_t > buf{};
419+ buf.resize (m_meta.getLength () - 4 - sizeof (uint32_t ));
420+ for (auto & b : buf) {
421+ deserializeFromAdjust (b, it, end);
422+ }
423+ m_meta.deserialize (buf);
383424
384425 do {
385- deserializer. deserialize (header);
426+ deserializeFromAdjust (header, it, end );
386427
387428 m_size = header.size ;
388429
389430 if (header.id == std::array<char , 4 >{' d' , ' a' , ' t' , ' a' }) {
390431 m_offset = size_t (m_stream.tellg ());
391432 return ;
392433 }
393-
394- seekable = deserializer.discard (header.size , seekable);
395434 } while (m_stream.good ());
396435
397436 throw deserialize_error (" Invalid .wav file" );
@@ -553,4 +592,30 @@ namespace sndx::audio {
553592 registerDecoder<WAVdecoder>(" .wav" ) &&
554593 registerDecoder<WAVdecoder>(" .wave" );
555594 }();
595+ }
596+
597+ namespace sndx {
598+ template <class T >
599+ requires
600+ std::is_same_v<T, audio::FMTchunk::ExtendedNone> ||
601+ std::is_same_v<T, audio::FMTchunk::Extended0> ||
602+ std::is_same_v<T, audio::FMTchunk::Extended>
603+ struct Serializer <T> {
604+ template <class SerializeIt >
605+ constexpr void serialize (const T& v, SerializeIt& it) const {
606+ v.serialize (it);
607+ }
608+ };
609+
610+ template <class T >
611+ requires
612+ std::is_same_v<T, audio::FMTchunk::ExtendedNone> ||
613+ std::is_same_v<T, audio::FMTchunk::Extended0> ||
614+ std::is_same_v<T, audio::FMTchunk::Extended>
615+ struct Deserializer <T> {
616+ template <class DeserializeIt >
617+ constexpr void deserialize (T& to, DeserializeIt& in, DeserializeIt end) const {
618+ to.deserialize (in, end);
619+ }
620+ };
556621}
0 commit comments