IT++ Logo
audiofile.cpp
Go to the documentation of this file.
1
31#include <itpp/base/ittypes.h>
32#include <itpp/base/itassert.h>
33#include <iostream>
34
36namespace itpp
37{
38
39//magic id of snd file header
40static const uint32_t snd_magic = 0x2e736e64;
41//maximum length of annotation to extract from snd file
42static const std::size_t max_annotation_length = 1024;
43
45//
46// Audio_Samples_Reader - templated implementation of Audio_Samples_Reader_If
47//
49template<typename Binary_In_Stream, Audio_Encoding Encoding>
50class Audio_Samples_Reader : public audiofile_details::Audio_Samples_Reader_If
51{
52public:
53 Audio_Samples_Reader(Binary_In_Stream& str, std::streamoff start, int nc):
54 _str(str), _start_pos(start), _num_channels(nc), _cur_pos(0){}
55 bool read_sample(double& s, int ch);
56 //Read n samples from audio channel ch
57 vec read_channel(int n, int ch);
58 mat read(int n);
59 virtual std::streamoff tell() const;
60 virtual bool seek(std::streamoff n);
61 virtual std::streamoff num_samples();
62private:
63 static const std::size_t sample_size = Audio_Sample<Encoding>::enc_sample_size;
64 typedef typename Audio_Sample<Encoding>::enc_sample_type sample_type;
65 //Number of audio channels
66 int _num_channels;
68 std::streamoff _start_pos;
70 std::streamoff _cur_pos;
72 Binary_In_Stream& _str;
73};
74
75template<typename Binary_In_Stream, Audio_Encoding Encoding>
76std::streamoff Audio_Samples_Reader<Binary_In_Stream,Encoding>::tell() const
77{
78 return _cur_pos;
79}
80
81template<typename Binary_In_Stream, Audio_Encoding Encoding>
82bool Audio_Samples_Reader<Binary_In_Stream,Encoding>::seek(std::streamoff n)
83{
84 _str.seekg(_start_pos + (_cur_pos * _num_channels *sample_size), std::ios_base::beg);
85 if(_str){
86 _cur_pos = n;
87 return true;
88 }
89 else{
90 return false;
91 }
92}
93
94template<typename Binary_In_Stream, Audio_Encoding Encoding>
95std::streamoff Audio_Samples_Reader<Binary_In_Stream,Encoding>::num_samples()
96{
97 _str.seekg(0, std::ios_base::end);
98 if(!_str) return -1;
99 std::streamoff end_pos = _str.tellg();
100 return (end_pos - _start_pos)/(_num_channels * sample_size);
101}
102
103//read single channel samples starting at current position
104template<typename Binary_In_Stream, Audio_Encoding Encoding>
105bool Audio_Samples_Reader<Binary_In_Stream,Encoding>::read_sample(double& s, int ch)
106{
107 if(ch >= _num_channels) return false;
108 std::streamoff read_pos = _start_pos + (_cur_pos * _num_channels + ch )*sample_size;
109 _str.seekg(read_pos, std::ios_base::beg);
110 if(!_str) return false;
111 sample_type raw_sample;
112 _str >> raw_sample;
113 if(_str){
114 s = Audio_Sample<Encoding>::decode(raw_sample);
115 _cur_pos++;
116 return true;
117 }
118 return false;
119}
120
121//read n samples from channel ch starting at current position
122template<typename Binary_In_Stream, Audio_Encoding Encoding>
123vec Audio_Samples_Reader<Binary_In_Stream,Encoding>::read_channel(int n, int ch)
124{
125 //ignore threshold - ignore() is used instead of seekg()
126 //if stride between samples is smaller then this threshold
127 static const std::streamsize ignore_threshold = 64;
128
129 if((n <= 0) || (ch >= _num_channels)) return vec();
130 vec ret(n);
131
132 //read first n-1 samples
133 const std::streamsize stride = sample_size*(_num_channels - 1);
134 _str.seekg(_start_pos + (_cur_pos *_num_channels + ch) * sample_size, std::ios_base::beg);
135 for(int i = 0; (i < (n-1)) && _str; ++i) {
136 sample_type raw_sample; _str >> raw_sample;
137 ret(i) = Audio_Sample<Encoding>::decode(raw_sample);
138 if(stride > ignore_threshold)
139 _str.seekg(stride, std::ios_base::cur);
140 else
141 _str.ignore(stride);
142 }
143
144 //read last sample
145 if(_str){
146 sample_type raw_sample; _str >> raw_sample;
147 ret(n-1) = Audio_Sample<Encoding>::decode(raw_sample);
148 }
149
150 if(_str){
151 _cur_pos += n;
152 }
153 else{
154 ret.set_size(0);
155 }
156
157 return ret;
158}
159
160//read n samples from all channels starting at current position
161template<typename Binary_In_Stream, Audio_Encoding Encoding>
162mat Audio_Samples_Reader<Binary_In_Stream,Encoding>::read(int n)
163{
164 if(n <= 0) return mat();
165 mat ret(n,_num_channels);
166
167 //read samples
168 const std::streamsize stride = sample_size*(_num_channels - 1);
169 _str.seekg(_start_pos + _cur_pos * sample_size *_num_channels, std::ios_base::beg);
170 for(int i = 0; (i < n) && _str; ++i) {
171 for(int j = 0; j < _num_channels && _str; ++j) {
172 sample_type raw_sample; _str >> raw_sample;
173 ret(i,j) = Audio_Sample<Encoding>::decode(raw_sample);
174 }
175 }
176
177 if(_str){
178 _cur_pos += n;
179 }
180 else{
181 ret.set_size(0,0);
182 }
183 return ret;
184}
185
186//make audio samples reader to input data from stream
187template<typename Binary_In_Stream>
188audiofile_details::Audio_Samples_Reader_If* make_reader(Binary_In_Stream& str,
189 std::streamoff start_pos, Audio_Stream_Description* d)
190{
191 Audio_Encoding encoding = d->get_encoding();
192 int num_channels = d->get_num_channels();
193 switch(encoding){
194 case enc_mulaw8:
195 return new Audio_Samples_Reader<Binary_In_Stream, enc_mulaw8>(str,start_pos,num_channels);
196 case enc_alaw8:
197 return new Audio_Samples_Reader<Binary_In_Stream, enc_alaw8>(str,start_pos,num_channels);
198 case enc_linear8:
199 return new Audio_Samples_Reader<Binary_In_Stream, enc_linear8>(str,start_pos,num_channels);
200 case enc_linear16:
201 return new Audio_Samples_Reader<Binary_In_Stream, enc_linear16>(str,start_pos,num_channels);
202 case enc_linear24:
203 return new Audio_Samples_Reader<Binary_In_Stream, enc_linear24>(str,start_pos,num_channels);
204 case enc_linear32:
205 return new Audio_Samples_Reader<Binary_In_Stream, enc_linear32>(str,start_pos,num_channels);
206 case enc_float:
207 return new Audio_Samples_Reader<Binary_In_Stream, enc_float>(str,start_pos,num_channels);
208 case enc_double:
209 return new Audio_Samples_Reader<Binary_In_Stream, enc_double>(str,start_pos,num_channels);
210 case enc_unknown:
211 default:
212 return 0;
213 }
214}
216//
217// Audio_Samples_Writer - templated implementation of Audio_Samples_Writer_If
218//
220template<typename Binary_Out_Stream, Audio_Encoding Encoding>
221class Audio_Samples_Writer : public audiofile_details::Audio_Samples_Writer_If
222{
223public:
224 Audio_Samples_Writer(Binary_Out_Stream& str, std::streamoff start, int nc):
225 _str(str), _start_pos(start), _num_channels(nc), _cur_pos(0),
226 _zero(Audio_Sample<Encoding>::encode(0.0)){}
227 virtual bool write_sample(const double& s, int ch);
228 virtual bool write_channel(const vec& s, int ch);
229 //Write n samples to audio channel ch
230 virtual bool write(const mat& s);
231 virtual std::streamoff tell() const;
232 virtual bool seek(std::streamoff n);
233 virtual std::streamoff num_samples();
234private:
235 static const std::size_t sample_size = Audio_Sample<Encoding>::enc_sample_size;
236 typedef typename Audio_Sample<Encoding>::enc_sample_type sample_type;
237 //Number of audio channels
238 int _num_channels;
240 std::streamoff _start_pos;
242 std::streamoff _cur_pos;
244 Binary_Out_Stream& _str;
245 //Zero sample
246 sample_type _zero;
247};
248
249template<typename Binary_Out_Stream, Audio_Encoding Encoding>
250std::streamoff Audio_Samples_Writer<Binary_Out_Stream,Encoding>::tell() const
251{
252 return _cur_pos;
253}
254
255template<typename Binary_Out_Stream, Audio_Encoding Encoding>
256bool Audio_Samples_Writer<Binary_Out_Stream,Encoding>::seek(std::streamoff n)
257{
258 _str.seekp(_start_pos + (n * _num_channels *sample_size), std::ios_base::beg);
259 if(_str){
260 _cur_pos = n;
261 return true;
262 }
263 else{
264 return false;
265 }
266}
267
268template<typename Binary_Out_Stream, Audio_Encoding Encoding>
269std::streamoff Audio_Samples_Writer<Binary_Out_Stream,Encoding>::num_samples()
270{
271 _str.seekp(0, std::ios_base::end);
272 if(!_str) return -1;
273 std::streamoff end_pos = _str.tellp();
274 return (end_pos - _start_pos)/(_num_channels * sample_size);
275}
276
277//write single sample starting at current position
278template<typename Binary_Out_Stream, Audio_Encoding Encoding>
279bool Audio_Samples_Writer<Binary_Out_Stream,Encoding>::write_sample(const double& s, int ch)
280{
281 if(ch >= _num_channels) return false;
282 std::streamoff write_pos = _start_pos + (_cur_pos * _num_channels + ch )*sample_size;
283 _str.seekp(write_pos, std::ios_base::beg);
284 if(!_str) return false;
285 _str << Audio_Sample<Encoding>::encode(s);
286 if(_str){
287 _cur_pos++;
288 return true;
289 }
290 return false;
291}
292
293//write single channel samples starting at current position
294template<typename Binary_Out_Stream, Audio_Encoding Encoding>
295bool Audio_Samples_Writer<Binary_Out_Stream,Encoding>::write_channel(const vec& s, int ch)
296{
297 if(ch >= _num_channels) return false;
298
299 int len = s.length();
300 //overall number of already written samples
301 std::streamoff ns = num_samples();
302 if(ns < 0) return false;
303 //compute number of samples to overwrite and number of samples to add to the end of file
304 int to_overwrite = (int)std::min(ns - _cur_pos, (std::streamoff)len);
305
306 const std::streamoff stride = sample_size*(_num_channels - 1);
307
308 int i = 0;
309 //overwrite samples
310 if(to_overwrite)
311 {
312 //process first to_overwrite-1 samples
313 _str.seekp(_start_pos + (_cur_pos * _num_channels + ch )*sample_size, std::ios_base::beg);
314 for(i = 0; (i < (to_overwrite-1)) && _str; ++i) {
315 _str << Audio_Sample<Encoding>::encode(s(i));
316 if(stride) _str.seekp(stride,std::ios_base::cur);
317 }
318 if(_str){
319 _str << Audio_Sample<Encoding>::encode(s(i)); ++i;
320 }
321 }
322
323 //add samples to the end of file
324 if(i < len)
325 {
326 _str.seekp(_start_pos + ns * _num_channels * sample_size, std::ios_base::beg);
327 for(; (i < len) && _str; ++i) {
328 for(int j = 0; (j < _num_channels) && _str; ++j){
329 if(j == ch)
330 _str << Audio_Sample<Encoding>::encode(s(i));
331 else
332 _str << _zero;
333 }
334 }
335 }
336
337 if(_str){
338 _cur_pos += len;
339 return true;
340 }
341 return false;
342}
343
344//write samples starting at current position
345template<typename Binary_Out_Stream, Audio_Encoding Encoding>
346bool Audio_Samples_Writer<Binary_Out_Stream,Encoding>::write(const mat& s)
347{
348 if(s.cols() < _num_channels) return false;
349 int len = s.rows();
350 for(int i = 0; (i < len) && _str; ++i){
351 for(int j = 0; (j < _num_channels) && _str; ++j){
352 sample_type raw_sample = Audio_Sample<Encoding>::encode(s(i,j));
353 _str << raw_sample;
354 }
355 }
356 if(_str){
357 _cur_pos += len;
358 return true;
359 }
360 return false;
361}
362
363//make audio samples writer for stream output
364template<typename Binary_Out_Stream>
365audiofile_details::Audio_Samples_Writer_If* make_writer(Binary_Out_Stream& str,
366 std::streamoff start_pos, Audio_Stream_Description* d)
367{
368 Audio_Encoding encoding = d->get_encoding();
369 int num_channels = d->get_num_channels();
370 switch(encoding){
371 case enc_mulaw8:
372 return new Audio_Samples_Writer<Binary_Out_Stream, enc_mulaw8>(str,start_pos,num_channels);
373 case enc_alaw8:
374 return new Audio_Samples_Writer<Binary_Out_Stream, enc_alaw8>(str,start_pos,num_channels);
375 case enc_linear8:
376 return new Audio_Samples_Writer<Binary_Out_Stream, enc_linear8>(str,start_pos,num_channels);
377 case enc_linear16:
378 return new Audio_Samples_Writer<Binary_Out_Stream, enc_linear16>(str,start_pos,num_channels);
379 case enc_linear24:
380 return new Audio_Samples_Writer<Binary_Out_Stream, enc_linear24>(str,start_pos,num_channels);
381 case enc_linear32:
382 return new Audio_Samples_Writer<Binary_Out_Stream, enc_linear32>(str,start_pos,num_channels);
383 case enc_float:
384 return new Audio_Samples_Writer<Binary_Out_Stream, enc_float>(str,start_pos,num_channels);
385 case enc_double:
386 return new Audio_Samples_Writer<Binary_Out_Stream, enc_double>(str,start_pos,num_channels);
387 case enc_unknown:
388 default:
389 return 0;
390 }
391}
392
394//
395// SND Header helpers
396//
398//snd header consists of 6 uint32_t fixed fields possibly followed
399//by the variable length annotation
400static const std::size_t snd_fixed_header_size = 24;
401
402//read_header() reads audio stream information from snd file header.
403//returns true if successfull.
404//d - pointer to stream description to collect info from snd header
405//audio_offset - byte offset of first audio sample inside snd file
406//number of audio samples stored in snd file, num_samples
407template<typename Binary_In_Stream>
408bool read_header(Binary_In_Stream& _str, Audio_Stream_Description* d,
409 std::streamoff& audio_offset, std::streamoff& num_samples)
410{
411 //SND header fields
412 uint32_t magic, hdr_size, data_size, encoding, sampling_rate, num_channels;
413 //encoded sample size
414 std::size_t sample_size;
415 //annotation
416 std::string annotation;
417
418 //read fixed fields of snd file header
419 _str.seekg(0, std::ios_base::beg);
420 _str >> magic >> hdr_size>> data_size>> encoding >> sampling_rate>> num_channels;
421 if(!_str) return false;
422
423 //check magic
424 if(magic != snd_magic) return false; //invalid magic
425
426 //check header size (we do not verify divisibility of header size by 8 since we still able to
427 //read unaligned data samples)
428 if(hdr_size < snd_fixed_header_size) return false; //header is too short
429 audio_offset = hdr_size;
430
431 //check encoding
432 sample_size = encoded_sample_size((Audio_Encoding)encoding);
433 if(!sample_size) return false; //unknown or invalid encoding
434
435 //read annotation
436 if(hdr_size > snd_fixed_header_size)
437 {//annotation is present
438 //get annotation length
439 std::streamsize ann_length = (std::streamsize)std::min(hdr_size - snd_fixed_header_size, max_annotation_length);
440 for(int i = 0; i < ann_length; ++i){
441 char s; _str>>s;
442 if(_str && s)
443 annotation += s;
444 else
445 break;
446 }
447 if(!_str) return false; //failed to read annotation
448 }
449
450 //compute number of audio samples based on the file length
451 _str.seekg(0, std::ios_base::end);
452 if(!_str) return false; //failed to seek to the end
453 std::streamoff ns = ((std::streamoff)_str.tellg() - hdr_size)/(num_channels * sample_size);
454
455 //update number of samples just read from header
456 if(data_size = 0xffffffff){
457 //data size was set to unknown in file header, use number of smaples obtained from file length
458 num_samples = ns;
459 }
460 else{
461 num_samples = std::min<long unsigned int>((long unsigned int)ns,(std::streamoff)data_size/(num_channels * sample_size));
462 }
463
464 //update start position of audio samples
465 audio_offset = hdr_size;
466
467 //update stream description
468 d->set_encoding((Audio_Encoding) encoding);
469 d->set_num_channels(num_channels);
470 d->set_sampling_rate(sampling_rate);
471 d->set_description(annotation);
472 return true;
473}
474
475//write_header() writes audio stream information to snd file header.
476//it is assumed that stream description pointed by d is initialized with correct values
477template<typename Binary_Out_Stream>
478bool write_header(Binary_Out_Stream& _str, const Audio_Stream_Description* const d, std::streamoff& audio_offset)
479{
480 uint32_t hdr_size, data_size, encoding, sampling_rate, num_channels;
481 data_size = 0xffffffff;
482 encoding = (uint32_t)d->get_encoding();
483 sampling_rate = (uint32_t)d->get_sampling_rate();
484 num_channels = (uint32_t)d->get_num_channels();
485
486 //compute header size based on fixed fields length and length of the annotation
487 uint32_t ann_length = (uint32_t)std::min(d->get_description().length(), max_annotation_length);
488 uint32_t padding_length = (8 - ((ann_length+1) % 8)) % 8; //compute padding length
489 hdr_size = (uint32_t)snd_fixed_header_size + ann_length + padding_length + 1;
490
491 //position stream pointer at the beginning of the file
492 _str.seekp(0,std::ios_base::beg);
493 if(!_str) return false;
494
495 //write fixed-sized part of the header
496 _str << snd_magic << hdr_size << data_size << encoding << sampling_rate << num_channels;
497 if(!_str) return false;
498
499 //write annotationn and padding
500 _str.write(d->get_description().c_str(), ann_length);
501 for(uint32_t i = 0; (i < (padding_length + 1)) && _str; ++i) _str << '\0';
502
503 if(!_str) return false;
504 audio_offset = hdr_size;
505
506 return true;
507}
508
509//update_num_samples_in_header() updates numder of samples in snd file header
510template<typename Binary_Out_Stream>
511bool update_num_samples_in_header(Binary_Out_Stream& _str, const Audio_Stream_Description* const d, std::streamoff num_samples)
512{
513 uint32_t data_size = (uint32_t) std::min<long unsigned int>((long unsigned int)(num_samples *
514 d->get_num_channels() * encoded_sample_size(d->get_encoding())),
515 (long unsigned int)0xffffffff);
516 _str.seekp(2*sizeof(uint32_t),std::ios_base::beg);
517 if(!_str) return false;
518 _str << data_size;
519 if(!_str) return false;
520 return true;
521}
522
523
525//
526// SND_In_File
527//
529
530SND_In_File::SND_In_File():_samples_reader(0),
531 _description(new Audio_Stream_Description), _num_samples(0)
532{
533}
534
535SND_In_File::SND_In_File(const char *fname):_samples_reader(0),
536 _description(new Audio_Stream_Description), _num_samples(0)
537{
538 open(fname);
539}
540
541bool SND_In_File::open(const char *fname)
542{
543 //try to reopen the stream
544 if (_str.is_open()) close();
545 _str.clear();
546 _str.open(fname, bfstream_base::b_endian);
547 if (!_str) return false;
548
549 //read header and update description
550 std::streamoff audio_offset;
551 if (!read_header(_str,_description, audio_offset,_num_samples)) {
552 _str.close();
553 return false;
554 }
555
556 //create samples reader
557 it_assert(_samples_reader == 0, "SND_In_File::open: samples reader was not deallocated properly.");
558 _samples_reader = make_reader(_str,audio_offset,_description);
559 return true;
560}
561
562void SND_In_File::close()
563{
564 //close stream
565 if(_str.is_open()) _str.close();
566 //dispose reader
567 if(_samples_reader){
568 delete _samples_reader;
569 _samples_reader = 0;
570 }
571 //reset description
572 _num_samples = 0;
573 *_description = Audio_Stream_Description();
574}
575
576SND_In_File::~SND_In_File()
577{
578 //close file and dispose description
579 close();
580 delete _description;
581}
582
583
585//
586// SND_Out_File
587//
589SND_Out_File::SND_Out_File():_samples_writer(0),
590 _description(new Audio_Stream_Description), _num_samples(0)
591{
592}
593
594SND_Out_File::SND_Out_File(const char *fname, const Audio_Stream_Description& d):
595 _samples_writer(0), _description(new Audio_Stream_Description), _num_samples(0)
596{
597 open(fname, d);
598}
599
600bool SND_Out_File::open(const char *fname, const Audio_Stream_Description& d)
601{
602 //check if we have a valid description
603 if(!is_valid(d)) return false;
604 //try to reopen the stream
605 if (_str.is_open()) close();
606 _str.clear();
607 _str.open(fname, true, bfstream_base::b_endian);
608 if (!_str) return false;
609 //init description and write header
610 *_description = d;
611 std::streamoff audio_offset;
612 if (!write_header(_str, &d, audio_offset)){
613 _str.close();
614 return false;
615 }
616 //create samples writer
617 it_assert(_samples_writer == 0, "SND_Out_File::open: samples writer was not deallocated properly.");
618 _samples_writer = make_writer(_str,audio_offset,_description);
619 _num_samples = 0;
620 return true;
621}
622
623void SND_Out_File::close()
624{
625 //update file header with written samples counter and close the stream
626 if(_str.is_open()){
627 update_num_samples_in_header(_str,_description,_num_samples);
628 _str.close();
629 }
630 //dispose samples writer
631 if(_samples_writer){
632 delete _samples_writer;
633 _samples_writer = 0;
634 }
635 //reset description
636 _num_samples = 0;
637 *_description = Audio_Stream_Description();
638}
639
640SND_Out_File::~SND_Out_File()
641{
642 //close file and dispose description
643 close();
644 delete _description;
645}
647//
648// SND_IO_File
649//
651
652SND_IO_File::SND_IO_File():
653 _samples_reader(0), _samples_writer(0),
654 _description(new Audio_Stream_Description), _num_samples(0)
655{
656
657}
658
659SND_IO_File::SND_IO_File(const char *fname):
660 _samples_reader(0), _samples_writer(0),
661 _description(new Audio_Stream_Description), _num_samples(0)
662{
663 open(fname);
664}
665
666SND_IO_File::SND_IO_File(const char *fname, const Audio_Stream_Description& d):
667 _samples_reader(0), _samples_writer(0),
668 _description(new Audio_Stream_Description), _num_samples(0)
669{
670 open(fname, d);
671}
672
673//open IO file. Pick up information about audio stream from file header
674bool SND_IO_File::open(const char *fname)
675{
676 //try to reopen the stream
677 if (_str.is_open()) close();
678 _str.clear();
679 _str.open(fname, false, bfstream_base::b_endian);
680 if (!_str) return false;
681 //reader header and update description
682 std::streamoff audio_offset;
683 if (!read_header(_str,_description, audio_offset,_num_samples)) {
684 _str.close();
685 return false;
686 }
687 //create reader and writer for audio samples
688 it_assert(_samples_reader == 0, "SND_IO_File::open: samples reader was not deallocated properly.");
689 _samples_reader = make_reader(_str,audio_offset,_description);
690 it_assert(_samples_writer == 0, "SND_IO_File::open: samples writer was not deallocated properly.");
691 _samples_writer = make_writer(_str,audio_offset,_description);
692 return true;
693
694}
695
696//open file for IO with new descrition - truncates file contents
697bool SND_IO_File::open(const char *fname, const Audio_Stream_Description& d)
698{
699 //check if provided decription is valid
700 if(!is_valid(d)) return false;
701
702 //try reopen the stream
703 if (_str.is_open()) close();
704 _str.clear();
705 _str.open(fname, true, bfstream_base::b_endian);
706 if (!_str) return false;
707
708 //init description and write file header
709 *_description = d;
710 std::streamoff audio_offset;
711 if (!write_header(_str, &d, audio_offset)){
712 _str.close();
713 return false;
714 }
715 //create reader and writer for audio samples
716 it_assert(_samples_reader == 0, "SND_IO_File::open: samples reader was not deallocated properly.");
717 _samples_reader = make_reader(_str,audio_offset,_description);
718 it_assert(_samples_writer == 0, "SND_IO_File::open: samples writer was not deallocated properly.");
719 _samples_writer = make_writer(_str,audio_offset,_description);
720
721 _num_samples = 0;
722 return true;
723
724}
725
726
727void SND_IO_File::close()
728{
729 //close the stream and update number of written samples
730 if(_str.is_open()){
731 update_num_samples_in_header(_str,_description,_num_samples);
732 _str.close();
733 }
734 //dispose reader and writer of audio samples
735 if(_samples_writer){
736 delete _samples_writer;
737 _samples_writer = 0;
738 }
739
740 if(_samples_reader){
741 delete _samples_reader;
742 _samples_reader = 0;
743 }
744 //reset description
745 _num_samples = 0;
746 *_description = Audio_Stream_Description();
747}
748
749SND_IO_File::~SND_IO_File()
750{
751 //close audio file and dispose description
752 close();
753 delete _description;
754}
755
756} // namespace itpp
757
Definitions of audio Audio classes and functions.
SND_In_File()
Default constructor - creates uninitialized stream.
Definitions of converters between different vector and matrix types.
Audio_Encoding
Supported encoding types for audio samples.
Definition audiosample.h:58
#define it_assert(t, s)
Abort if t is not true.
Definition itassert.h:94
Error handling functions - header file.
IT++ type definitions.
itpp namespace
Definition itmex.h:37
bool is_valid(const Audio_Stream_Description &d)
validity check for stream description d
Definition audiofile.h:102
std::size_t encoded_sample_size(Audio_Encoding e)
Size of encoded sample based on the encoding type e.
SourceForge Logo

Generated on Mon Apr 7 2025 07:53:18 for IT++ by Doxygen 1.11.0