我正在寻找帮助开始以编程方式使用音频.
具体来说,我正在使用的平台公开API以从资源(如MP3)中提取音频数据,或者将任意数据作为音频播放.在这两种情况下,实际数据是32位浮点数的字节数组,代表44.1 KHz立体声.我正在寻找的是帮助理解那些花车代表什么,以及用它们可以做些什么来动态分析或修改它们代表的声音.
我需要学习哪种概念才能以这种方式处理音频?
正如一些人在评论中指出的那样,你想要研究的是PCM音频.
简而言之,声音是一种穿过空气的波浪.为了捕获那个声音,我们使用一个麦克风,它包含一个膜,当声波击中它时它会振动.这种振动转化为电信号,电压上升和下降.然后,这种电压变化由模数转换器(ADC)通过每秒采样一定次数(" 采样率 " - 44 KHz,或每秒44100个采样)变为数字信号,并且当前情况,存储为脉冲编码调制(PCM)音频数据.
一个扬声器在对面工作; PCM信号通过数模转换器(DAC)转换为模拟信号,然后模拟信号进入扬声器,在那里振动膜,在空气中产生振动,从而产生声音.
操纵音频
有许多图书馆可供你操作音频,但你已经将这个问题标记为"语言无关",我会提到一些简单的方法(就像我所知道的那样!)你会能够用您首选的语言操纵音频.
我将以伪代码的形式呈现代码示例.
伪代码将使每个音频样本的幅度在-1到1的范围内.这取决于您用于存储每个样本的数据类型.(我以前没有处理过32位float
,所以这可能会有所不同.)
放大
为了放大音频(因此,增加声音的音量),您需要使扬声器的振动更大,从而增加声波的幅度.
为了使扬声器移动更多,您必须增加每个样本的值:
original_samples = [0, 0.5, 0, -0.5, 0] def amplify(samples): foreach s in samples: s = s * 2 amplified_samples = amplify(original_samples) // result: amplified_samples == [0, 1, 0, -1, 0]
结果样本现在放大2倍,播放时声音应该比以前大得多.
安静
没有振动时,没有声音.沉默可以通过将每个样本降至0或任何特定值来实现,但样本之间的振幅没有任何变化:
original_samples = [0, 0.5, 0, -0.5, 0] def silence(samples): foreach s in samples: s = 0 silent_samples = silence(original_samples) // result: silent_samples == [0, 0, 0, 0, 0]
由于样品中振幅的变化不大,播放上述内容应该不会发出声音,因为扬声器上的膜根本不会移动.
加速和减速
可以通过两种方式实现上下加速:(1)改变回放采样率或(2)改变样本本身.
将播放采样率从44100 Hz更改为22050 Hz会使播放速度降低2.这将使声音变慢和降低.从22 KHz音源开始播放,播放频率为44 KHz,声音非常快,声音很高,像鸟儿一样啁啾.
更改样本本身(并保持恒定的回放采样率)意味着样本(a)被抛出或(b)被添加.
要加快播放音频,请丢弃样本:
original_samples = [0, 0.1, 0.2, 0.3, 0.4, 0.5] def faster(samples): new_samples = [] for i = 0 to samples.length: if i is even: new_samples.add(samples[i]) return new_samples faster_samples = faster(original_samples) // result: silent_samples == [0, 0.2, 0.4]
上述程序的结果是音频将加速2倍,类似于播放以22 KHz在44 KHz采样的音频.
要减慢音频的播放速度,请输入一些示例:
original_samples = [0, 0.1, 0.2, 0.3] def slower(samples): new_samples = [] for i = 0 to samples.length: new_samples.add(samples[i]) new_samples.add(interpolate(s[i], s[i + 1])) return new_samples slower_samples = slower(original_samples) // result: silent_samples == [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3]
这里添加了额外的样本,从而减慢了播放速度.在这里,我们有一个interpolation
函数可以"猜测"如何填充那些额外的空间.
FFT的频谱分析和声音修改
使用称为快速傅立叶变换(FFT)的技术,可以将幅度 - 时间域中的声音数据映射到频率 - 时间域以找出音频的频率分量.这可用于生成您最喜欢的音频播放器上可能会看到的频谱分析仪.
不仅如此,因为现在您拥有音频的频率成分,如果您更改了音量
如果要切断某些频率,可以使用FFT将声音数据转换为频率 - 时间域,并将不需要的频率分量清零.这称为过滤.
制作允许高于特定频率的频率的高通滤波器可以这样执行:
data = fft(orignal_samples) for i = (data.length / 2) to data.length: data[i] = 0 new_samples = inverse_fft(data)
在上面的例子中,中途标记上的所有频率都是截止的.因此,如果音频可以产生22 KHz作为最大频率,则将切断高于11 KHz的任何频率.(对于以44 KHz回放的音频,可产生的最大理论频率为22 KHz.参见Nyquist-Shannon采样定理.)
如果你想做一些像增加低频范围(类似于低音增强效果)的事情,那么采用FFT变换数据的低端并增加其幅度:
data = fft(orignal_samples) for i = 0 to (data.length / 4): increase(data[i]) new_samples = inverse_fft(data)
此示例增加了音频频率分量的下四分之一,导致低频变得更响.
可以对样本进行很多操作来处理音频.继续尝试吧!这是最令人兴奋的学习方式.
祝好运!