写波头和添加数据,不关闭流

Write Wave header and Add Data, without closing ofstream

本文关键字:数据 添加      更新时间:2023-10-16

正如主题所说,下面是代码:

    template <typename SampleType>
void writeWAVHeader
(
char const* outFile,
SampleType* buf,
int sizeMult,
size_t bufSize,
int sampleRate,
short channels,
int Flush
)
{ 
    if (sizeMult != 0)
        bufSize = bufSize*sizeMult;
        std::ofstream stream(outFile, std::ios::in | std::ios::binary | std::ios::app);
    stream.seekp(0);
    stream.write("RIFF", 4);
    write<int>(stream, 36 + bufSize);
    stream.write("WAVE", 4);
    stream.write("fmt ", 4);
    write<int>(stream, 16);
    writeFormat<SampleType>(stream);                                // Format
    write<short>(stream, channels);                                 // Channels
    write<int>(stream, sampleRate);                                 // Sample Rate
    write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate
    write<short>(stream, channels * sizeof(SampleType));            // Frame size
    write<short>(stream, 8 * sizeof(SampleType));                   // Bits per sample
    stream.write("data", 4);
    stream.write((const char*)&bufSize, 4);
    stream.seekp(stream.end);
    if(sizeMult != 0)
        bufSize = bufSize/sizeMult;
    stream.write((const char*)buf, bufSize);
    stream.flush();
    if (Flush >= 100)
    stream.close();
}

你可以看到我一直在尝试的注释掉的东西。

在我看来,这应该很容易。

我用这些参数打开文件,查找到开始,写头,然后查找到结束,因为我正在附加到波以及重写头,但它不会工作。它只是一直重写整个内容。

代码是它工作时的样子。我必须关闭并重新打开,这对我来说在这种情况下没有意义。

更新:

我更改了代码,这并没有像预期的那样工作,这让我感到困惑。

I seekp(0) =文件开头

写标题

查找到文件末尾,.

添加新的音频数据

问题的第一部分在于std::ios::app标志的使用。如cppreference所示:

应用程序在每次写

之前寻求流的结束

因此,如果你使用这个选项,头和数据将被附加在文件的末尾,而不管seekp(0)调用。因此,您应该使用:

打开流。
std::ofstream stream(outFile, std::ios::in | std::ios::binary);

你的问题的另一部分是seekp的使用。当使用单个参数seekp调用时,将常量std::ios::end(经过某种类型转换)解释为文件中的绝对位置(相对于文件的开始),而不是使用对应于文件结束的偏移量。

所以你应该改变行:

stream.seekp(stream.end)

:

steam.seekp(0, stream.end);

这是一段按预期工作的代码。它可能有问题,但如果没有人说什么,那么这很可能是我问题的答案。

template <>
void writeFormat<float>(std::ofstream& stream) {
    write<short>(stream, 3);
}

template <typename SampleType>
void writeWAVHeader
(
char const* outFile,
SampleType* buf,
int sizeMult,
size_t bufSize,
int sampleRate,
short channels,
int Flush
)
{ 
    if (sizeMult != 0)
        bufSize = bufSize*sizeMult;

    std::ofstream stream(outFile, std::ios::in | std::ios::binary);
    stream.write("RIFF", 4);
    write<int>(stream, 36 + bufSize);
    stream.write("WAVE", 4);
    stream.write("fmt ", 4);
    write<int>(stream, 16);
    writeFormat<SampleType>(stream);                                // Format
    write<short>(stream, channels);                                 // Channels
    write<int>(stream, sampleRate);                                 // Sample Rate
    write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate
    write<short>(stream, channels * sizeof(SampleType));            // Frame size
    write<short>(stream, 8 * sizeof(SampleType));                   // Bits per sample
    stream.write("data", 4);
    stream.write((const char*)&bufSize, 4);
    stream.seekp(0,stream.end);
    if(sizeMult != 0)
        bufSize = bufSize/sizeMult;
    stream.write((const char*)buf, bufSize);
    stream.flush();
    if (Flush >= 100) //Prevent close on each run.
        {
        stream.close();
    }
}