C++中的音频操作

C++中的音频操作,c++,audio,signal-processing,C++,Audio,Signal Processing,我希望这是一个正确的地方张贴这一点,有人可以帮助 我是一名音乐技术专业的学生,最近我开始学习C++,因为它对我的编程语言有很大帮助,尤其是在电子游戏行业中使用的。 不管怎么说,都是关于主题的。我想创建的是C++程序,让用户加载16位线性PCM波文件。然后我想处理wave文件中的音频样本数据。我想移除每N个样本,或者在某个±10%的参数范围内随机化它们。然后将其作为新的WAVE文件写入 我更熟悉WAVE文件的结构和RIFF头。我现在也使用Xcode作为我的IDE,因为我的MacBookPro是我的

我希望这是一个正确的地方张贴这一点,有人可以帮助

<>我是一名音乐技术专业的学生,最近我开始学习C++,因为它对我的编程语言有很大帮助,尤其是在电子游戏行业中使用的。 不管怎么说,都是关于主题的。我想创建的是C++程序,让用户加载16位线性PCM波文件。然后我想处理wave文件中的音频样本数据。我想移除每N个样本,或者在某个±10%的参数范围内随机化它们。然后将其作为新的WAVE文件写入

我更熟悉WAVE文件的结构和RIFF头。我现在也使用Xcode作为我的IDE,因为我的MacBookPro是我的工作电脑,但如果必要的话,我可以使用代码块在我的电脑上编码

简单地说,它应该显示类似的东西?我知道这里面有错误,只是为了让你知道我在追求什么:

#include <iostream>
using namespace std;

class main()    //function start
{
    string fileinput;   //variable
    string outlocation; //variable

    cout << "please type file path directory: \n \n";
    cin >> fileinput;   //navigate to file by typing

    cout << "Where would you like to save new file? \n \n";
    cin >> outlocation; //select output by typing

    // Then all the maths and manipulation is done

    cout << "Your file has been created at ";
    cout << outlocation;
    cout << "\n \n";

    system("pause");

    return 0;
}
如果有可能的话,是否可以在Xcode中执行此操作?我需要什么图书馆?我知道这不是一件简单的事情,所以任何帮助都将不胜感激

谢谢你的帮助和时间


James

以下是我的wav2pcm和pcm2wav utils的相对便携的来源:

如果您知道RIFF文件结构,您可能已经知道PCM音频是如何存储在其中的

常见的格式是16位立体声pcm。在这种情况下,每个样本是2个字节,两个样本一起属于左+右。但是您需要检查格式块的确切格式。但我知道现在你正在处理一个16位立体声pcm wav文件

您可以使用16位整数类型short、\u int16、int16\t来处理样本。例如,为了减小体积,可以将每个样本除以某个数字。但是如果你把它除以2,并不意味着它会自动变为原来的一半。看

如果只是操纵样本,RIFF头不会更改,因此可以从源代码复制它们

如果要删除或添加示例,数据块的大小将发生更改,riff头中整个文件的大小也将发生更改。 例如,您可以简单地删除每10个样本,然后从数据块中复制9*4=36字节,跳过4字节,复制36字节,依此类推。但是如果你这样做,听起来会很糟糕。听到结果的最好方法是操纵正弦波。如果正弦信号不完全正确,很容易听到。要以正确的方式进行采样,可能需要使用快速傅里叶变换FFT

根据您的评论,我添加以下内容:

有关文件I/O的快速说明,请参阅。您描述的RIFF格式看起来正确,但不完整。根据该描述,报头总是44字节。但是可以在标题中添加更多信息

您应该做的是跳过前12个字节,尽管您可以使用它来验证文件是否确实是wave文件。 然后在循环中读取下一个块的名称和大小。如果它是一个块,你知道“fmt”或“数据”,你可以处理它,否则跳过它

因此,它可以如下所示,例如:

ifstream myFile ("example.wav", ios::in | ios::binary);
char buffer[12];
myFile.read (buffer, 12); // skip RIFF header

char chunkName[5];
unsigned long chunksize;
while (myFile.read (chunkName, 4)) {
    chunkName[4]='\0'; // add trailing zero
    myFile.read((char*)&chunksize, 4);

    // if chunkname is 'fmt ' or 'data' process it here,
    // otherwise skip any unknown chunk:
    myFile.seekg(chunksize, ios_base::cur);
}
见libsndfile


是的-这应该很简单-您只需要一个合适的库来在WAV文件数据和内存中的原始PCM样本之间进行转换。好的,但我仍然不确定如何编写?有人建议我需要一个音频文件读取器,并将所有内容存储在缓冲区中。然后操纵样本并导出。但是,把这些代码,特别是当我还是新手的时候,是很困难的。另外,如果我只是更改示例值而没有删除任何,我认为我不需要更改RIFF标题中的任何内容?我认为您最好将其拆分为更小的任务。不要试图立即编写,而是首先解析RIFF头并在屏幕上显示有关它的信息。如果你对这一点还不熟悉,那么当你陷入困境时,最好从自己开始寻求帮助。但是如果你让别人创建所有的代码,你将一无所获。关于您的评论,如果文件不太大,您只能将所有内容存储在缓冲区中。否则您将耗尽内存。但您也可以将文件的一部分放入缓冲区,并对其进行操作。但这可能更难。好吧,我一直在使用以下网站查看WAVE和RIFF上的资源:。我在理论上知道这一点,但从未对它进行过编程之类的工作。我环顾了abit,一直在研究一段代码,这段代码引导我写下了这样一段话:我使用了一张图片,因为使用代码或pastebin会弄乱注释的格式。但这段代码还没有任何内容。如何让它读取音频以便显示此信息?弗洛德?我在上面添加了更多信息。