我有一个简单的程序,它创建一个单循环正弦波并将浮点数放入缓冲区。然后将其导出到文本文件。 但我希望能够将其导出为WAV文件(24位)。是否有一种简单的方法可以像在文本文件中那样进行操作?
这是我到目前为止的代码:
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
int main ()
{
long double pi = 3.14159265359; // Declaration of PI
ofstream textfile; // Text object
textfile.open("sine.txt"); // Creating the txt
double samplerate = 44100.00; // Sample rate
double frequency = 200.00; // Frequency
int bufferSize = (1/frequency)*samplerate; // Buffer size
double buffer[bufferSize]; // Buffer
for (int i = 0; i <= (1/frequency)*samplerate; ++i) // Single cycle
{
buffer[i] = sin(frequency * (2 * pi) * i / samplerate); // Putting into buffer the float values
textfile << buffer[i] << endl; // Exporting to txt
}
textfile.close(); // Closing the txt
return 0; // Success
}
答案 0 :(得分:3)
首先,您需要打开二进制流。
ofstream stream;
stream.open("sine.wav", ios::out | ios::binary);
接下来,您需要写出一个wave标头。您可以搜索以查找波形文件格式的详细信息。重要的位是采样率,位深度和数据长度。
int bufferSize = (1/frequency)*samplerate;
stream.write("RIFF", 4); // RIFF chunk
write<int>(stream, 36 + bufferSize*sizeof(int)); // RIFF chunk size in bytes
stream.write("WAVE", 4); // WAVE chunk
stream.write("fmt ", 4); // fmt chunk
write32(stream, 16); // size of fmt chunk
write16(stream, 1); // Format = PCM
write16(stream, 1); // # of Channels
write32(stream, samplerate); // Sample Rate
write32(stream, samplerate*sizeof(int)); // Byte rate
write16(stream, sizeof(int)); // Frame size
write16(stream, 24); // Bits per sample
stream.write("data", 4); // data chunk
write32(stream, bufferSize*sizeof(int)); // data chunk size in bytes
现在标题已经不在了,你只需要修改你的循环就可以先将double(-1.0,1.0)样本转换成32位signed int。截断底部的8位,因为您只需要24位然后写出数据。您知道,通常的做法是在32位字中存储24位样本,因为使用本机类型更容易实现。
for (int i = 0; i < bufferSize; ++i) // Single cycle
{
double tmp = sin(frequency * (2 * pi) * i / samplerate);
int intVal = (int)(tmp * 2147483647.0) & 0xffffff00;
stream << intVal;
}
其他一些事情:
1)我不知道你在循环中使用buffer
是如何溢出<=
的。我将其更改为<
。
2)再次考虑缓冲区大小。我不确定您是否知道,但是对于所有频率,您不能以单个周期表示重复波形。我的意思是,对于大多数频率,如果您使用此代码并期望重复播放波形,您将在每个周期听到一个小故障。它适用于1kHz等漂亮的同步频率,因为每个周期将有48个样本,它将会出现完全相同的相位。然而,999.9赫兹将是一个不同的故事。