C++ 将缓冲区导出到C+中的WAV+;
我有一个简单的程序,可以创建一个单周期正弦波,并将浮点数放入缓冲区。然后将其导出为文本文件。 但我希望能够将其导出到WAV文件(24位)。有没有一种简单的方法可以像在文本文件上那样执行 以下是我目前掌握的代码:C++ 将缓冲区导出到C+中的WAV+;,c++,audio,wav,cycle,trigonometry,C++,Audio,Wav,Cycle,Trigonometry,我有一个简单的程序,可以创建一个单周期正弦波,并将浮点数放入缓冲区。然后将其导出为文本文件。 但我希望能够将其导出到WAV文件(24位)。有没有一种简单的方法可以像在文本文件上那样执行 以下是我目前掌握的代码: #include <iostream> #include <fstream> #include <cmath> using namespace std; int main () { long double pi = 3.14159265359
#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
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
长双pi=3.14159265359;//pi的声明
ofstream textfile;//文本对象
textfile.open(“sine.txt”);//创建txt
双采样率=44100.00;//采样率
双频=200.00;//频率
int bufferSize=(1/频率)*采样器;//缓冲区大小
双缓冲区[bufferSize];//缓冲区
对于(inti=0;i,首先需要打开二进制文件的流
ofstream stream;
stream.open("sine.wav", ios::out | ios::binary);
接下来,您需要写出一个wave头。您可以搜索以找到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
int bufferSize=(1/频率)*采样器;
stream.write(“RIFF”,4);//RIFF chunk
写入(流,36+bufferSize*sizeof(int));//RIFF块大小(字节)
stream.write(“WAVE”,4);//WAVE块
stream.write(“fmt”,4);//fmt chunk
write32(stream,16);//fmt块的大小
write16(流,1);//格式=PCM
写入16(流,1);/#个通道
write32(流,采样器);//采样率
write32(流,samplerate*sizeof(int));//字节率
write16(流,sizeof(int));//帧大小
write16(流,24);//每个采样位
stream.write(“data”,4);//数据块
write32(流,bufferSize*sizeof(int));//数据块大小(字节)
既然标头已经不存在了,那么您只需要修改循环以首先转换double(-1.0,1.0)将样本转换为32位带符号整数。截断底部8位,因为您只需要24位,然后写出数据。正如您所知,通常的做法是将24位样本存储在32位字中,因为使用本机类型更容易跨越
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;
}
for(int i=0;i 流侧注释:intbuffersize=(1/频率)*采样器;双缓冲区[bufferSize]这是无效的ANSI C++,因为数组必须用常量表达式来声明为条目。这个行的另一个问题是浮点计算不准确。“代码”>缓冲区大小< /代码>可以根据编译器、编译器优化等不同。wav格式和程序的标准,或者使用一个库,也请参见,定义一个常量值(如bufferSize[1000])是否更好?@JesusGinard也许使用一个固定的大小更好。此外,对于(inti=0;i@PaulMcKenzie,但是如果我只想导出一个循环呢?如果我在for上输入一个固定值,我将有多个循环。