首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编程音频入门

编程音频入门
EN

Stack Overflow用户
提问于 2008-12-14 04:50:03
回答 4查看 9.9K关注 0票数 35

我正在寻找帮助开始编程与音频工作。

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

要以这种方式使用音频,我需要学习哪些概念?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-12-14 06:57:19

正如一些人在评论中指出的那样,你想要研究的是PCM audio

简而言之,sound是一种在空气中传播的波。为了捕捉这种声音,我们使用了一个microphone,它包含一个薄膜,当声波击中它时,它会振动。这种振动被转换成电信号,在那里电压上升和下降。然后,通过每秒采样一定次数("sampling rate“- 44 KHz,或每秒44,100个采样),通过模数转换器( analog-to-digital converter )将电压的这种变化改变为数字信号,并且在当前情况下,将其存储为脉冲编码调制(PCM)音频数据。

speaker的工作原理与之相反;digital-to-analog converter (数模转换器)将PCM信号转换为模拟信号,然后模拟信号到达扬声器,在扬声器上振动薄膜,薄膜在空气中产生振动,从而产生声音。

操纵音频的

有许多针对多种语言的库,您可以使用这些库来操作音频,但是您将这个问题标记为“语言不可知”,我将提到一些简单的方法(因为这就是我所知道的全部!)你将能够以你喜欢的语言操作音频。

我将以伪代码的形式呈现代码示例。

伪码将使每个音频样本的幅度在-1到1的范围内。这将取决于您用于存储每个样本的数据类型。(我以前没有接触过32位float,所以这次可能会有所不同。)

Amplification

为了放大音频,(因此,增加声音的音量)你需要使扬声器的振动更大,这样声波的幅度就会增加。

为了使扬声器移动得更多,您必须增加每个样本的值:

代码语言:javascript
复制
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或任何特定值来实现,但样本之间的幅度没有任何变化:

代码语言:javascript
复制
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)被加入。

若要加快音频播放速度,请抛出示例:

代码语言:javascript
复制
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倍,类似于播放在44 KHz下以22 KHz采样的音频。

若要放慢音频的播放速度,请抛出几个示例:

代码语言:javascript
复制
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函数,它“猜测”如何填充要添加的额外空格。

基于快速傅立叶变换频谱分析与声音修正

利用一种称为快速傅立叶变换( Fast Fourier transform )的技术,可以将幅度-时间域中的声音数据映射到频率-时间域,以找出音频的频率分量。这可以用来产生你可能会在你最喜欢的音频播放器上看到的spectrum analyzers

不仅如此,因为现在你有了音频的频率分量,如果你改变

如果您想要截断某些频率,可以使用FFT将声音数据转换到频率-时域,并将不需要的频率分量置零。这称为filtering

制作一个允许频率高于某个特定频率的,可以像这样执行:

代码语言:javascript
复制
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 sampling theorem。)

如果你想做一些事情,比如增加低频范围(类似于低音增强效果),取FFT变换数据的较低端并增加其幅度:

代码语言:javascript
复制
data = fft(orignal_samples)

for i = 0 to (data.length / 4):
    increase(data[i])

new_samples = inverse_fft(data)

这个例子增加了音频频率分量的低四分之一,导致低频变得更大。

有相当多的事情可以做的样本,以操纵音频。尽管去做实验吧!这是最令人兴奋的学习方式。

祝好运!

票数 104
EN

Stack Overflow用户

发布于 2008-12-14 06:15:05

看起来您想了解更多关于PCM audio的信息

基本上,每个32位值代表指定时间的电压电平。由于采样频率为44100 the,因此每个通道每秒可获得441000个32位值(*2,因为您有立体声)

对于立体声,左声道和右声道通常是交错的,因此第一个采样表示左声道,第二个采样表示右声道,依此类推。

票数 5
EN

Stack Overflow用户

发布于 2008-12-22 09:42:53

要理解这些32位浮点数组所代表的内容,您需要阅读一篇很好的数字音频简介。

如果你在图书馆附近,Curtis Roads的“电脑音乐教程”可能会很有用。具体来说,第一章“数字音频概念”。(我已经很久没有读过这本书了)。

一旦你对数字音频有了理解,就有很多方法来操纵它。当你准备好了,这些链接可能会有所帮助。

Dsp + Plugin Development forum at KVR Audio是一个可以提问的地方。这里的帖子通常分为通用音频DSP和VST插件主题。

MusicDsp有很多代码片段。

The Scientist and Engineer's Guide to Digital Signal Processing是一个免费的在线教科书,深入了解标准的数字信号处理器主题。其中大部分也适用于数字音频。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/366187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档