Порядковый номер в файлах wav - PullRequest
1 голос
/ 25 марта 2019

Я пытался сделать простой писатель 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);
}

У меня есть следующие вопросы:

  1. В векторе soundData почему порядковый номер вектора шорт имеет значение, а вектор чисел с плавающей запятой - нет? В моем коде я изменил порядок байтов шорт, но не поплавков.

  2. Первоначально я пытался написать шорты, не меняя порядок следования байтов. Когда я написал файл, он оказался вдвое меньше, чем должен был быть (т. Е. Половина аудиоданных отсутствовала, но половина была правильной), почему это было бы?

  3. Я не менял порядок байтов шортов и длинных в других единичных переменных, которые, по сути, являются всеми другими полями, составляющими файл wav, например. sampleRate, numOfChannels и т. д., но это, похоже, не влияет на воспроизведение файла wav. Это потому, что медиаплееры не используют эти поля (и, следовательно, я не могу сказать, что я их неправильно понял), или это потому, что порядок байтов этих переменных не имеет значения?

1 Ответ

1 голос
/ 25 марта 2019

В векторе soundData почему порядковый номер вектора шорт имеет значение, а вектор чисел с плавающей запятой - нет? В моем коде я изменил порядок байтов шорт, но не поплавков.

На самом деле, если вы присмотритесь к своему коду, вы увидите, что вы не обращаете вспять порядок своих шорт вообще. Вам также не нужно это делать на процессорах Intel (или на любом другом процессоре с низким порядком байтов).

Первоначально я пытался написать шорты, не меняя порядок следования байтов. Когда я написал файл, он оказался вдвое меньше, чем должен был быть (т. Е. Половина аудиоданных отсутствовала, но половина была правильной), почему это было бы?

Понятия не имею, не увидев код, но подозреваю, что в игре был какой-то другой фактор.

Я не менял порядок байтов шортов и длинных в других единичных переменных, которые по сути являются всеми остальными полями, составляющими файл wav, например. sampleRate, numOfChannels и т. д., но это, похоже, не влияет на воспроизведение файла wav. Это потому, что медиаплееры не используют эти поля (и, следовательно, я не могу сказать, что я их неправильно понял), или это потому, что порядок байтов этих переменных не имеет значения?

Эти поля на самом деле очень важны и также должны иметь порядок байтов, но, как мы видели, вам тоже не нужно их менять.

...