音频处理在C ++ [英] Audio Manipulation In C++

查看:139
本文介绍了音频处理在C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望这是张贴此,有人可以帮助正确的地方。

I hope this is the right place to post this and somebody can help.

我是一个音乐技术的学生,最近我拿起学习C ++,因为这将极大地帮助我的职业生涯了解一门编程语言,尤其是这种之一,因为它是在视频游戏行业。

I am a music technology student and I've recently picked up learning C++ as it would greatly help my career knowing a programming language, especially this one since it is used in the video games industry.

不管怎么说上的主要议题。我想创建一个程序(用C ++),让用户加载16位线性PCM WAVE文件。然后我想那波文件中操纵音频样本数据。我想要么除去每隔n个样本或特定参数(±10%)内随机化它们。然后把它写成一个新的WAVE文件。

Anyways onto the main topic. What I want to create is a program (in C++) that lets the user load a 16bit linear PCM WAVE file. Then I want to manipulate the audio sample data within that wave file. I want to either remove every nth sample or randomise them within a certain parameter (±10%). Then write it as a new WAVE file.

我熟悉并且具有WAVE文件的结构和RIFF标题。我此刻也使用X code作为我的IDE(因为我的MacBook Pro是我的工作电脑),但我可以用$ C $个cblocks如有必要,code我的电脑上。

I am familier with the structure of WAVE files and the RIFF header. I also at the moment use Xcode as my IDE (since my macbook pro is my work computer), but I can code on my PC if necessary using codeblocks.

所以,简单来说它应该显示类似于这样的东西吗?我知道有这个错误,只是让你得到什么,我以后是一个想法:

So in simple terms it should display something similar to this? I know there are errors in this, just so you get an idea of what I'm after:

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

是否有可能,如果在所有,为此在X code吗?我需要什么库?我明白这不是简单的东西,所以任何帮助将大大AP preciated。

Is it possible to do this in Xcode, if at all? What libraries would I need? I understand this is not simple stuff, so any help will be greatly appreciated.

谢谢你们的帮助和时间。

Thankyou for your help and time.

詹姆斯

推荐答案

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

If you know the RIFF file structure, you might also already know how PCM audio is stored in it.

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

A common format is 16-bit stereo pcm. In that case each sample is 2 bytes, and two samples belong together (left+right). But you need to check the format chunk for the exact format. But I asume for now you are manipulating a 16-bit stereo pcm wav file.

您可以使用16位整型(短,_int16,int16_t)操作样本。例如,要降低音量,可以将某些号码每个样本。但是,如果你除以2,这并不意味着它会成为一半响亮。请参见这个帖子

You can manipulate the samples using a 16 bit integer type (short, _int16, int16_t). For example to decrease the volume, you can divide every sample by some number. But if you divide it by 2, it does not automatically mean it will become half as loud. See this post.

如果你只是操纵的样本,RIFF头不改变,这样就可以从源头上复制它们。

If you just manipulate samples, the RIFF headers do not change, so you can copy them from the source.

如果你想删除或添加的样品,数据块的大小会发生变化,而且整个文件的大小,在流氓头。
你可以简单地例如降每10个样本,那么你会从数据块复制9 * 4 = 36字节,跳过4个字节,复制36字节等。但是,如果你做这样的事情,它会发出非常糟糕。听到结果,最好的办法是操纵正弦波。如果正弦是不完全正确,这将是很容易听到它。要删除样品的正确方法,你可能需要使用快速傅立叶变换(FFT)。

If you want to remove or add samples, the size of the data chunk will change, and also the size of the whole file in the riff-header. You could simply for example drop every 10th sample, then you would copy 9*4=36 bytes from the data chunk, skip 4 bytes, copy 36 bytes and so on. But if you do something like that, it will sound very bad. The best way to hear the result is to manipulate a sine wave. If the sine is not fully correct, it will be easy to hear it. To drop samples the right way, you probably need to use a Fast Fourier Transform (FFT).

作为基于你的意见,我添加一个附加以下内容:

请参阅 C ++二进制文件I / O 一个快速HOWTO上文件I / O。 描述RIFF格式的链接看起来是正确的,但不完整。根据该描述的报头总是44个字节。但有可能的更多信息添加到报头。

See C++ Binary File I/O for a quick howto on file I/O. Your link describing the RIFF format looks correct but is not complete. According to that description the header is always 44 bytes. But it is possible to add more information to the header.

你应该做的是跳过前12个字节(虽然你可以用它来验证,如果一个文件实际上是波形文件)。
和然后,在循环读出的名称与下一个块的大小。如果你知道('FMT或数据),您可以处理它一大块,否则跳过它。

What you should do is skip the first 12 bytes (although you can use it to verify if a file is really a wave file). And then in a loop read the name and size of the next chunk. If it is a chunk you know ('fmt ' or 'data') you can process it, otherwise skip it.

因此​​,它可以是这样的,例如:

So it can look like this for example:

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

这篇关于音频处理在C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆