当前位置:  开发笔记 > 编程语言 > 正文

开始使用程序化音频

如何解决《开始使用程序化音频》经验,为你挑选了1个好方法。

我正在寻找帮助开始以编程方式使用音频.

具体来说,我正在使用的平台公开API以从资源(如MP3)中提取音频数据,或者将任意数据作为音频播放.在这两种情况下,实际数据是32位浮点数的字节数组,代表44.1 KHz立体声.我正在寻找的是帮助理解那些花车代表什么,以及用它们可以做些什么来动态分析或修改它们代表的声音.

我需要学习哪种概念才能以这种方式处理音频?



1> coobird..:

正如一些人在评论中指出的那样,你想要研究的是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)

此示例增加了音频频率分量的下四分之一,导致低频变得更响.


可以对样本进行很多操作来处理音频.继续尝试吧!这是最令人兴奋的学习方式.

祝好运!


哇...如果我能得到最喜欢的答案;)
推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有