2222
2323#include " wavencoder.h"
2424
25+ #include " ../dsp/audiomathutils.h"
26+
2527#include " log.h"
2628
2729using namespace muse ::audio;
2830using namespace muse ::audio::encode;
2931
3032struct WavHeader {
31- enum class WavFileType {
32- int16, // 16 bit signed integer
33- float32
34- };
35-
3633 uint32_t chunkSize = 0 ;
3734 uint16_t audioChannelsNumber = 0 ;
3835 uint16_t bitsPerSample = 0 ;
@@ -42,7 +39,7 @@ struct WavHeader {
4239
4340 void write (std::ofstream& stream)
4441 {
45- const uint32_t bytesPerSample = 4 ;
42+ const uint32_t bytesPerSample = bitsPerSample / 8 ;
4643 const uint32_t sampleDataLength = audioChannelsNumber * samplesPerChannel * bytesPerSample;
4744 const uint32_t headerLength = 20 + chunkSize + 8 ;
4845 const uint32_t file_length = headerLength + sampleDataLength;
@@ -58,7 +55,7 @@ struct WavHeader {
5855
5956 writeTagData<uint32_t >(stream, chunkSize);
6057 writeTagData<uint16_t >(stream, code);
61- writeTagData<uint16_t >(stream, 2 );
58+ writeTagData<uint16_t >(stream, audioChannelsNumber );
6259 writeTagData<uint32_t >(stream, sampleRate);
6360 writeTagData<uint32_t >(stream, bytesPerSec);
6461 writeTagData<uint16_t >(stream, bytesPerFrame);
@@ -89,8 +86,25 @@ size_t WavEncoder::encode(samples_t samplesPerChannel, const float* input)
8986
9087 WavHeader header;
9188 header.chunkSize = 18 ; // 18 is 2 bytes more to include cbsize field / extension size
92- header.bitsPerSample = 32 ;
93- header.code = 3 ; // IEEE_FLOAT = 3, PCM = 1
89+
90+ switch (m_format.sampleFormat ) {
91+ case AudioSampleFormat::Int16:
92+ header.bitsPerSample = 16 ;
93+ header.code = 1 ; // PCM
94+ break ;
95+ case AudioSampleFormat::Int24:
96+ header.bitsPerSample = 24 ;
97+ header.code = 1 ; // PCM
98+ break ;
99+ case AudioSampleFormat::Float32:
100+ header.bitsPerSample = 32 ;
101+ header.code = 3 ; // IEEE_FLOAT
102+ break ;
103+ case AudioSampleFormat::Undefined:
104+ default :
105+ return 0 ;
106+ }
107+
94108 header.audioChannelsNumber = m_format.outputSpec .audioChannelCount ;
95109 header.sampleRate = m_format.outputSpec .sampleRate ;
96110 header.samplesPerChannel = samplesPerChannel;
@@ -99,20 +113,34 @@ size_t WavEncoder::encode(samples_t samplesPerChannel, const float* input)
99113
100114 int total = header.samplesPerChannel ;
101115 int progressStep = (total * 5 ) / 100 ; // every 5%
102- QVector<samples_t > progressValues;
103- for (samples_t sampleIdx = 0 ; sampleIdx < header.samplesPerChannel ;) {
104- progressValues << sampleIdx;
105- sampleIdx += progressStep;
106- }
107116
108- for (samples_t sampleIdx = 0 ; sampleIdx < header.samplesPerChannel ; ++sampleIdx) {
109- for (audioch_t audioChNum = 0 ; audioChNum < m_format.outputSpec .audioChannelCount ; ++audioChNum) {
110- int idx = sampleIdx * m_format.outputSpec .audioChannelCount + audioChNum;
111- m_fileStream.write (reinterpret_cast <const char *>(input + idx), 4 );
117+ const int channels = m_format.outputSpec .audioChannelCount ;
118+
119+ if (m_format.sampleFormat == AudioSampleFormat::Float32) {
120+ for (samples_t sampleIdx = 0 ; sampleIdx < header.samplesPerChannel ; ++sampleIdx) {
121+ for (audioch_t audioChNum = 0 ; audioChNum < channels; ++audioChNum) {
122+ int idx = sampleIdx * channels + audioChNum;
123+ m_fileStream.write (reinterpret_cast <const char *>(input + idx), 4 );
124+ }
125+ if (sampleIdx % progressStep == 0 ) {
126+ m_progress.progress (sampleIdx, total);
127+ }
112128 }
129+ } else {
130+ const int bits = header.bitsPerSample ;
131+ const int bytesToWrite = bits / 8 ;
132+
133+ for (samples_t sampleIdx = 0 ; sampleIdx < header.samplesPerChannel ; ++sampleIdx) {
134+ for (audioch_t audioChNum = 0 ; audioChNum < channels; ++audioChNum) {
135+ int idx = sampleIdx * channels + audioChNum;
136+
137+ int32_t sampleInt = dsp::convertFloatSamples<int32_t >(input[idx], bits);
113138
114- if (progressValues.contains (sampleIdx)) {
115- m_progress.progress (sampleIdx, total);
139+ m_fileStream.write (reinterpret_cast <const char *>(&sampleInt), bytesToWrite);
140+ }
141+ if (sampleIdx % progressStep == 0 ) {
142+ m_progress.progress (sampleIdx, total);
143+ }
116144 }
117145 }
118146
0 commit comments