Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将缓冲区导出到C+中的WAV+;_C++_Audio_Wav_Cycle_Trigonometry - Fatal编程技术网

C++ 将缓冲区导出到C+中的WAV+;

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

我有一个简单的程序,可以创建一个单周期正弦波,并将浮点数放入缓冲区。然后将其导出为文本文件。 但我希望能够将其导出到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
}
#包括
#包括
#包括
使用名称空间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上输入一个固定值,我将有多个循环。