C ++中的音频处理

时间:2011-03-21 14:51:09

标签: c++ audio signal-processing

我希望这是发布此内容的合适地点,有人可以提供帮助。

我是一名音乐技术专业的学生,​​我最近学习了C ++,因为这对我的职业生涯有很大的帮助,因为它可以用于视频游戏行业,尤其​​是这种语言。

无论如何进入主题。我想要创建的是一个程序(在C ++中),它允许用户加载一个16位线性PCM WAVE文件。然后我想操纵该波形文件中的音频样本数据。我想要删除每个第n个样本,或者在某个参数内随机化它们(±10%)。然后将其写为新的WAVE文件。

我对WAVE文件和RIFF标头的结构比较熟悉。我现在也使用Xcode作为我的IDE(因为我的macbook pro是我的工作计算机),但如果需要,我可以使用代码块在我的PC上编码。

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

#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中执行此操作,如果有的话?我需要哪些图书馆?我知道这不是简单的事情,所以任何帮助都将不胜感激。

谢谢你的帮助和时间。

詹姆斯

3 个答案:

答案 0 :(得分:5)

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

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

您可以使用16位整数类型(short,_int16,int16_t)操作样本。例如,要减小音量,您可以将每个样本除以某个数字。但是,如果将它除以2,它并不会自动意味着它会变得大一半。请参阅this post

如果你只是操作样本,RIFF标题不会改变,所以你可以从源代码中复制它们。

如果要删除或添加样本,数据块的大小将会改变,并且riff-header中的整个文件的大小也会改变。 例如,您可以删除每10个样本,然后从数据块中复制9 * 4 = 36个字节,跳过4个字节,复制36个字节,依此类推。但如果你这样做,那听起来会非常糟糕。听到结果的最好方法是操纵正弦波。如果正弦不完全正确,则很容易听到。要以正确的方式丢弃样本,您可能需要使用快速傅里叶变换(FFT)。

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

有关文件I / O的快速操作方法,请参阅C++ Binary File I/O。您描述RIFF格式的link看起来正确但不完整。根据该描述,报头总是44个字节。但是可以向标题添加更多信息。

您应该做的是跳过前12个字节(尽管您可以使用它来验证文件是否真的是波形文件)。 然后在循环中读取下一个块的名称和大小。如果它是一个你知道的块('fmt'或'data')你可以处理它,否则跳过它。

所以它看起来像这样:

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);
}

答案 1 :(得分:0)

以下是我的wav2pcm和pcm2wav utils的(相对)便携源: http://nishi.dreamhosters.com/u/wav2pcm_v0.rar

答案 2 :(得分:0)

相关问题