Line data Source code
1 : /** 2 : * \file OutWavFilter.cpp 3 : */ 4 : 5 : #include "OutWavFilter.h" 6 : #include <ATK/Core/Utilities.h> 7 : 8 : #include <cstring> 9 : #include <stdexcept> 10 : 11 : namespace 12 : { 13 : template<typename DataType1, typename DataType2> 14 : void convert(std::vector<std::vector<DataType1> >& outputs, const std::vector<char>& inputs) 15 : { 16 : int nbChannels = outputs.size(); 17 : int64_t size = outputs[0].size(); 18 : for(gsl::index j = 0; j < nbChannels; ++j) 19 : { 20 : ATK::ConversionUtilities<DataType2, DataType1>::convert_array(reinterpret_cast<const DataType2*>(inputs.data() + j * sizeof(DataType2)), outputs[j].data(), size, nbChannels); 21 : } 22 : } 23 : } 24 : 25 : namespace ATK 26 : { 27 : template<typename DataType> 28 2 : OutWavFilter<DataType>::OutWavFilter(const std::string& filename) 29 2 : :TypedBaseFilter<DataType>(0, 0) 30 : { 31 2 : wavstream.open(filename, std::ios_base::binary); 32 2 : if(!wavstream.good()) 33 : { 34 0 : throw RuntimeError("Could not WAV file " + filename); 35 : } 36 2 : } 37 : 38 : template<typename DataType> 39 2 : void OutWavFilter<DataType>::process_impl(gsl::index size) const 40 : { 41 2 : gsl::index nb_inputs = converted_inputs.size(); 42 4 : std::vector<DataType> buffer(nb_inputs * size); 43 : 44 2050 : for(gsl::index i = 0; i < size; ++i) 45 : { 46 5120 : for(gsl::index j = 0; j < nb_inputs; ++j) 47 : { 48 3072 : buffer[j + i * nb_inputs] = converted_inputs[j][i]; 49 : } 50 : } 51 : 52 2 : wavstream.write(reinterpret_cast<const char*>(buffer.data()), buffer.size() * sizeof(DataType)); 53 2 : write_header(); 54 2 : } 55 : 56 : template<typename DataType> 57 2 : void OutWavFilter<DataType>::set_nb_input_ports(gsl::index nb_ports) 58 : { 59 2 : Parent::set_nb_input_ports(nb_ports); 60 2 : setup(); 61 2 : } 62 : 63 : template<typename DataType> 64 5 : void OutWavFilter<DataType>::setup() 65 : { 66 5 : write_header(); 67 5 : } 68 : 69 : template<typename DataType> 70 7 : void OutWavFilter<DataType>::write_header() const 71 : { 72 : WavHeader header; 73 : WavFormat format; 74 : WavData data; 75 : 76 7 : std::strncpy(header.FileTypeBlocID, "RIFF", 4); 77 7 : std::strncpy(header.FileFormatID, "WAVE", 4); 78 7 : std::strncpy(format.FormatBlocID, "fmt ", 4); 79 7 : std::strncpy(data.DataBlocID, "data", 4); 80 7 : format.AudioFormat = WavTraits<DataType>::get_wav_type(); 81 7 : format.Frequence = static_cast<int32_t>(input_sampling_rate); 82 7 : format.BitsPerSample = sizeof(DataType)* 8; 83 7 : format.BytePerBloc = format.NbChannels * format.BitsPerSample / 8; 84 7 : format.BytePerSec = static_cast<int32_t>(format.BytePerBloc * input_sampling_rate); 85 7 : format.NbChannels = static_cast<int16_t>(nb_input_ports); 86 : 87 7 : gsl::index total_size = wavstream.tellp(); 88 7 : gsl::index bloc_size = sizeof(WavFormat); 89 7 : gsl::index data_size = total_size - sizeof(WavFormat) - sizeof(WavHeader) - sizeof(WavData); 90 7 : wavstream.seekp(0); 91 7 : header.FileSize = static_cast<std::int32_t>(total_size - 8); 92 7 : format.BlocSize = static_cast<std::int32_t>(bloc_size - 8); 93 7 : data.DataSize = static_cast<std::int32_t>(data_size); 94 7 : wavstream.write(reinterpret_cast<char*>(&header), sizeof(WavHeader)); 95 7 : wavstream.write(reinterpret_cast<char*>(&format), sizeof(WavFormat)); 96 7 : wavstream.write(reinterpret_cast<char*>(&data), sizeof(WavData)); 97 : 98 7 : wavstream.seekp(0, std::ios_base::end); 99 7 : } 100 : 101 : #if ATK_ENABLE_INSTANTIATION 102 : template class OutWavFilter<std::int16_t>; 103 : template class OutWavFilter<double>; 104 : #endif 105 : template class OutWavFilter<float>; 106 : }