波文件导出损坏

wave file export is corrupted

本文关键字:损坏 文件      更新时间:2023-10-16

我编写了两个函数,它们应该将音频浮点缓冲区导出为. wave文件,但我在播放导出文件时遇到了问题。Audacity播放它应该是(听起来完全像我的应用程序),然而,Ableton (daw软件)似乎误解了一些部分的波,所以它听起来真的很扭曲。(像一个扭曲效果)

我猜ableton不知怎么假设了一个错误的样本深度(更小),所以实际的样本超出了极限。

我有两个函数,一个是从两个浮动缓冲区创建int32_t缓冲区(将左和右混合到一个缓冲区中),另一个函数写入. wave文件,包括格式块等。我想一定是哪里出了问题。

类成员/结构

// static I use in the export function
static const int FORMAT_PCM = 1;
static const int CHANNEL_COUNT = 2;    // fix stereo
static const int BYTES_PER_SAMPLE = 4; // fix bytes per sample, 32bit audio
// a function I found in the internet, helps writting the bytes to the file
template <typename T>
static void write(std::ofstream& stream, const T& t) {
    stream.write((const char*)&t, sizeof(T));
};
// used "structure" to store the buffer
class StereoAudioBuffer {
public:
    StereoAudioBuffer(int length) : sizeInSamples(2*length){
        samples = new int32_t[2*length];
    };
    ~StereoAudioBuffer() {delete samples;};
    int32_t *samples;
    const int sizeInSamples;
};

转换函数

StereoAudioBuffer* WaveExport::convertTo32BitStereo(
        float *leftSamples, 
        float*rightSamples, 
        int length) 
{
    StereoAudioBuffer *buffer = new StereoAudioBuffer(length);
    float max = 0;
    // find max sample 
    for(int i = 0; i < length; i++) {
        if(abs(leftSamples[i]) > max) {
            max = abs(leftSamples[i]);
        }
        if(abs(rightSamples[i]) > max) {
            max = abs(rightSamples[i]);
        }
    }

    // normalise and scale to size(int32_t)
    float factor = 2147483000.0f / max;
    for(int i = 0; i < length; i++) {
        buffer->samples[2*i] = leftSamples[i] * factor ;
        buffer->samples[2*i+1] = rightSamples[i] * factor;
    }
    return buffer;
}

导出函数(部分代码来自互联网,遗憾的是,我再也找不到源代码了

void WaveExport::writeStereoWave(
        const char *path, 
        StereoAudioBuffer* buffer, 
        int sampleRate) 
{
    std::ofstream stream(path, std::ios::binary);
    // RIFF
    stream.write("RIFF", 4);
    // FILE SIZE
    write<int>(stream, 36 + buffer->sizeInSamples * BYTES_PER_SAMPLE); // 32 bits -> 4 bytes
    // WAVE
    stream.write("WAVE", 4);
    // FORMAT CHUNK
    stream.write("fmt ", 4);
    write<int>(stream, 16);
    write<short>(stream, FORMAT_PCM);                                       // Format
    write<short>(stream, CHANNEL_COUNT);                                    // Channels
    write<int>(stream, sampleRate);                                         // Sample Rate
    write<int>(stream, sampleRate * CHANNEL_COUNT * BYTES_PER_SAMPLE);      // Byterate
    write<short>(stream, CHANNEL_COUNT * BYTES_PER_SAMPLE);                 // Frame size
    write<short>(stream, 8 * BYTES_PER_SAMPLE);                             // Bits per sample
    int dataChunkSize = buffer->sizeInSamples * BYTES_PER_SAMPLE;
    // SAMPLES
    stream.write("data", 4);
    stream.write((const char*)&dataChunkSize, 4);
    stream.write((const char*)buffer->samples, BYTES_PER_SAMPLE*buffer->sizeInSamples);
}

有没有人知道如何写。wav文件,也许可以告诉我我做错了什么或错过了?谢谢!

没有问题。我使用了32位的。wav,只是在应用程序中不支持,我用它来播放。

我将导出函数更改为使用int16_t, 16位深度,它工作得很好。