Я пытался сделать простой писатель WAV. Я хотел сделать это так, чтобы я мог читать в файле WAV (используя ранее существующий WAV-ридер), повторно дискретизировать аудиоданные, а затем записать пересчитанные данные в другой файл WAV. Входные файлы могут быть 16 bitsPerSample или 32 bitsPerSample, и я хотел сохранить преобразованный звук с тем же числом битPerSample.
Писатель работает, но есть пара вещей, которые я не понимаю в связи с порядком байтов, и я надеялся, что кто-то сможет мне помочь?
Раньше у меня не было опыта чтения или записи двоичных файлов. Я начал с поиска в Интернете формата файла wav и попытался записать данные в правильном формате. Сначала запись не работала, но потом я обнаружил, что wav-файлы имеют порядок байтов, и он пытался сделать так, чтобы мой файловый писатель соответствовал этому, что подняло большинство моих проблем.
У меня теперь работает wav-писатель (с помощью теста, в ходе которого я прочитал в wav-файл и проверил, могу ли я записать несэмплированный звук и воспроизвести точно такой же файл), однако есть пара моментов, в которых я до сих пор не уверен делать с порядком байтов, и я надеялся, что кто-то сможет мне помочь?
Предполагая, что соответствующие переменные уже установлены, вот мой код для wav writer:
// Write RIFF header
out_stream.write(chunkID.c_str(),4);
out_stream.write((char*)&chunkSize,4);
out_stream.write(format.c_str());
// Write format chunk
out_stream.write(subchunk1ID.c_str(),4);
out_stream.write((char*)&subchunk1Size,4);
out_stream.write((char*)&audioFormat,2);
out_stream.write((char*)&numOfChannels,2);
out_stream.write((char*)&sampleRate,4);
out_stream.write((char*)&byteRate,4);
out_stream.write((char*)&blockAlign,2);
out_stream.write((char*)&bitsPerSample,2);
// Write data chunk
out_stream.write(subchunk2ID.c_str(),4);
out_stream.write((char*)&subchunk2Size,4);
// Variables for writing 16 bitsPerSample data
std::vector<short> soundDataShort;
soundDataShort.resize(numSamples);
char theSoundDataBytes [2];
// soundData samples are written as shorts if bitsPerSample=16 and floats if bitsPerSample=32
switch( bitsPerSample )
{
case (16):
// cast each of the soundData samples from floats to shorts
// then save the samples in little-endian form (requires reversal of byte-order of the short variable)
for (int sample=0; sample < numSamples; sample++)
{
soundDataShort[sample] = static_cast<short>(soundData[sample]);
theSoundDataBytes[0] = (soundDataShort[sample]) & 0xFF;
theSoundDataBytes[1] = (soundDataShort[sample] >> 8) & 0xFF;
out_stream.write(theSoundDataBytes,2);
}
break;
case (32):
// save the soundData samples in binary form (does not require change to byte order for floats)
out_stream.write((char*)&soundData[0],numSamples);
}
У меня есть следующие вопросы:
В векторе soundData почему порядковый номер вектора шорт имеет значение, а вектор чисел с плавающей запятой - нет? В моем коде я изменил порядок байтов шорт, но не поплавков.
Первоначально я пытался написать шорты, не меняя порядок следования байтов. Когда я написал файл, он оказался вдвое меньше, чем должен был быть (т. Е. Половина аудиоданных отсутствовала, но половина была правильной), почему это было бы?
Я не менял порядок байтов шортов и длинных в других единичных переменных, которые, по сути, являются всеми другими полями, составляющими файл wav, например. sampleRate, numOfChannels и т. д., но это, похоже, не влияет на воспроизведение файла wav. Это потому, что медиаплееры не используют эти поля (и, следовательно, я не могу сказать, что я их неправильно понял), или это потому, что порядок байтов этих переменных не имеет значения?