Line data Source code
1 : /** 2 : * \file InWavFilter.cpp 3 : */ 4 : 5 : #include "InWavFilter.h" 6 : #include <ATK/Core/Utilities.h> 7 : 8 : #include <stdexcept> 9 : 10 : namespace 11 : { 12 : template<typename DataType1, typename DataType2> 13 12 : void convert(std::vector<std::vector<DataType1> >& outputs, const std::vector<char>& inputs) 14 : { 15 12 : gsl::index nbChannels = outputs.size(); 16 12 : gsl::index size = outputs[0].size(); 17 29 : for(gsl::index j = 0; j < nbChannels; ++j) 18 : { 19 17 : ATK::ConversionUtilities<DataType2, DataType1>::convert_array(reinterpret_cast<const DataType2*>(inputs.data()), outputs[j].data(), size, j, static_cast<int>(nbChannels)); 20 : } 21 12 : } 22 : } 23 : 24 : namespace ATK 25 : { 26 : template<typename DataType> 27 10 : InWavFilter<DataType>::InWavFilter(const std::string& filename) 28 10 : :TypedBaseFilter<DataType>(0, 0), filename(filename) 29 : { 30 10 : wavstream.open(filename, std::ios_base::binary); 31 10 : if(!wavstream.good()) 32 : { 33 0 : throw RuntimeError("Could not open WAV file " + filename); 34 : } 35 : // Read wave header 36 10 : wavstream.read(reinterpret_cast<char*>(&header), sizeof(WavHeader)); 37 : 38 : // Get the format block 39 10 : wavstream.read(reinterpret_cast<char*>(&format), 4+4); 40 10 : if(format.FormatBlocID[0] != 'f') // OK, assume we have bext instead 41 : { 42 0 : wavstream.seekg(static_cast<int32_t>(wavstream.tellg()) + format.BlocSize); 43 0 : wavstream.read(reinterpret_cast<char*>(&format), sizeof(WavFormat)); 44 : } 45 : else 46 : { 47 10 : wavstream.read(reinterpret_cast<char*>(&format) + 4 + 4, sizeof(WavFormat) - 4 - 4); 48 : } 49 : 50 : // Get the data block 51 10 : wavstream.read(reinterpret_cast<char*>(&data), sizeof(WavData)); 52 10 : while(data.DataBlocID[0] != 'd') 53 : { 54 0 : wavstream.seekg(static_cast<int32_t>(wavstream.tellg()) + data.DataSize); 55 0 : wavstream.read(reinterpret_cast<char*>(&data), sizeof(WavData)); 56 : } 57 : 58 10 : offset = wavstream.tellg(); 59 10 : wavstream.close(); 60 : 61 10 : set_nb_output_ports(format.NbChannels); 62 10 : set_output_sampling_rate(format.Frequence); 63 10 : temp_arrays.resize(format.NbChannels); 64 10 : } 65 : 66 : template<typename DataType> 67 12 : void InWavFilter<DataType>::process_impl(gsl::index size) const 68 : { 69 12 : assert(output_sampling_rate == format.Frequence); 70 12 : read_from_file(size); 71 : 72 10252 : for(gsl::index i = 0; i < size; ++i) 73 : { 74 25600 : for(gsl::index j = 0; j < format.NbChannels; ++j) 75 : { 76 15360 : outputs[j][i] = temp_arrays[j][i]; 77 : } 78 : } 79 12 : } 80 : 81 : template<typename DataType> 82 12 : void InWavFilter<DataType>::read_from_file(gsl::index size) const 83 : { 84 12 : if(!wavstream.is_open()) 85 : { 86 10 : wavstream.open(filename, std::ios_base::binary); 87 10 : wavstream.seekg(offset); 88 : } 89 24 : std::vector<char> buffer(size * format.NbChannels * format.BitsPerSample / 8); 90 12 : wavstream.read(buffer.data(), buffer.size()); 91 : 92 12 : if(temp_arrays[0].size() != static_cast<gsl::index>(size)) 93 : { 94 25 : for(gsl::index j = 0; j < format.NbChannels; ++j) 95 : { 96 15 : temp_arrays[j].resize(size); 97 : } 98 : } 99 : 100 12 : switch(format.BitsPerSample) 101 : { 102 0 : case 8: 103 0 : convert<DataType, std::int8_t>(temp_arrays, buffer); 104 0 : break; 105 0 : case 16: 106 0 : convert<DataType, std::int16_t>(temp_arrays, buffer); 107 0 : break; 108 0 : case 24: 109 0 : convert<DataType, char[3]>(temp_arrays, buffer); 110 0 : break; 111 12 : case 32: 112 12 : convert<DataType, float>(temp_arrays, buffer); 113 12 : break; 114 0 : case 64: 115 0 : convert<DataType, double>(temp_arrays, buffer); 116 0 : break; 117 0 : default: 118 0 : throw RuntimeError("Don't know how to process bits per sample=" + std::to_string(format.BitsPerSample)); 119 : } 120 12 : } 121 : 122 : #if ATK_ENABLE_INSTANTIATION 123 : template class InWavFilter<std::int16_t>; 124 : template class InWavFilter<std::int32_t>; 125 : template class InWavFilter<int64_t>; 126 : #endif 127 : template class InWavFilter<float>; 128 : template class InWavFilter<double>; 129 : }