一
.引子
现阶段的工作涉及到了部分音频解析的内容,广义来说便是
数字信号处理(DSP),可惜本人并非专科出生,很多相关内容都是空白,从头看起也感觉颇为有些困楚,虽说时间也花了不少,不过成果还是颇不尽如人意,至今仍有不少概念还是懵懵懂懂、不知西东,不过鉴于记录目的,我于此还是尽力笔记一番,一方面算作加深自己所学之印象,另一方面也可为有这方面兴趣的朋友做些参考吧
~~~然而本人对DSP确实不是很着门道,有什么纰漏错误的在所难免,希望注意到的朋友能够不吝指出,本人在此先拜谢了 :)
二
.缘起
关于
DSP的学习需求大抵来自于近阶段音乐游戏的制作,而所谓音乐游戏,一般而言便是一类“玩家通过输入与音乐节奏进行互动”的游戏,更细致的信息可以参考这里,传统类型的音乐游戏有很多:譬如太鼓达人、吉他英雄之类,近些年亦出现了不少颇有些异质的音乐游戏,譬如:节奏天国、啪嗒砰等等,后者虽然融入了不少创新元素,使音乐游戏有了不少新鲜味道,但就本质而言,他们仍然未有脱离开音乐中的一个重要元素:节拍,或者换句话说,如果脱离开了这个元素,那可能这个游戏便不再能够称为所谓“音乐游戏”了,当然这些是题外话,现就单从这“节奏”这一元素说开去,很多音乐游戏都是以此为核心设计之处,譬如近年来在移动平台上颇为流行的TapTap,其中歌曲关卡的设计基本都以“节奏”为重要出发点,另外的一款在
PC上也有不少受众的音乐游戏OSU
!,期间的多处设计也基本基于音乐节奏。然而,这类传统的音乐游戏都有一个通病,那就是游戏本身受限的音乐。就我目前的观点,音乐游戏要做的好,至少至少要做到两点:1.
优秀的歌曲 2.优秀的关卡。可能稍有些空泛,请允许我慢慢道来:)让我们先从第二点讲起:优秀的关卡。什么是优秀的关卡?这个问题可能太过宽泛了些,很多人都发表了不少具有启发意义的观点,甚至是书籍(譬如
这本),这里我们自然也不期望仅仅通过几行文字就能将其说清道明,但如果就在“音乐游戏”这个大前提下来说的话,我私认为所谓“优秀的关卡”的定义还是颇为明确的,那就是:与音乐节奏相匹配的关卡。或者这么说,关卡匹配音乐的程度越高,其优秀程度便越高,当然,除了匹配音乐外,关卡自身还有不少其他元素:譬如渐进、层次或者亮点等等,但这种种元素都是以匹配音乐节奏为大前提的,也可以说,如果你的关卡没有很好的匹配音乐,那么即便关卡中层次再好,亮点再多,从“音乐游戏”之角度而言的话,这个关卡仍然不能算作是优秀的关卡。
OK,至此我们简单说了一下何谓音乐游戏的“优秀关卡”,自然里面还有不少细节,但是我们至少知道在给定音乐的前提下,如何评判关卡优秀程度的一个方法,或者说如何加强关卡优异程度的一个方向,那么接下来让我们来探讨音乐游戏制作的第一个要点:优秀的歌曲。什么是优秀的歌曲?这个问题恐怕也不会有什么标准答案……本人对乐理只是初通,作曲更是不会,所以对于这个问题我并没有多少“规则”可以细说,但就从普通的听者角度出发,一首歌的优秀程度可能很大程度上都取决于听者的主观感受,而这种感受在人与人之间是不相同的,可能你认为美妙绝伦的一首歌,在他的耳中就只是平凡无奇,我们姑且称这种现象为“个体差异”吧,但仅就单个个体而言,其主观感受也可能会随着所处环境不同而产生改变,譬如你高兴的时候可能会喜欢听一些曲调欢快的歌曲,而你悲伤的时候可能就会偏好一些风格幽婉的乐曲……说到这里,那么问题就来了,既然说歌曲的优秀程度大部分取决于人的主观感受,而后者又是会不断变换的,那么我们制作者似乎没有什么好办法可以保证我们提供的歌曲是优秀的……实际上,我认为在以前传统音乐游戏的制作方法之上,确实也不可能避免或者解决这个问题,我们自然可以提供尽可能的歌曲给玩家,但是无论我们提供多少歌曲,充其量仅是减轻了上述问题,并不能算作解决了上述问题,目前很多音乐游戏的流行的做法就是提供不断更新的乐库,譬如之前提到的
TapTap,做法便属前者,但同样仍有一些人在继续琢磨,还有没有更自由的方法呢?循着这条思路,有一类相对“技术向”的音乐游戏便诞生了,譬如AudioSurf,他们有一个共同的特点,便是:音乐由玩家提供,关卡由程序生成,而我们简单的
DSP之旅便由此开始了……
(上述提到的游戏,有兴趣的朋友不妨一试:))
三
. 启程
接着上面所说,既然我们想要完成音乐生成关卡的任务,那么大致的步骤可能便是如此:
1.
解析歌曲,获取原始音乐数据
2.
通过所得数据通过一定方法解析出其中的歌曲信息
3.
通过所得到的歌曲信息进行关卡生成(或者说关卡映射)
虽然以上三个步骤说的都很简单,颇有些“将大象放进冰箱”的玩笑味道,但细致讲来确实涉及到了不少
DSP的知识,而其中第一个概念让我们来看看PCM:
PCM
的英文全称为Pulse-code modulation,意为脉冲编码调制,是一种模拟信号的编码方式。有些相关了解的朋友一定听过数模转换
(模数转换)这个名词,意思便是
数字信号与
模拟信号的相互转换,而
PCM便是这众多转换方法中的一种,其大致主要分为两个方面,即编码与调制,编码,即是模拟信号转换为数字信号的过程;而调制,即是数字信号转换为模拟信号的过程。在此我们暂且不顾调制的具体流程,因为我们暂时还用其不上,而先将主要精力置于编码这个过程:
现实中的声音是模拟信号,而声音也可以理解为声波,可以认为是由多种波形叠加而成的一种波,于此我们简单考虑,就将声波看做一个正弦波,而现在,我们正好有一段
1s的“声波”(如下图),如何将其数字化呢?
其实思路很简单,大概可以分为采样和量化两大步骤:
1.采样 即每隔一段固定时间内被取一次样,或者说“读一次值”,依照上面的正弦波为例,如果我们每隔0.25s取一次样,那么所取得值便是:(0, 0),(0.25, 8),(0.5, 0),(0.75, -8)以及(1,0)。这中间有一个问题,那就是这个固定时间应该取多少才是合适的,取得越短则数据自然越细致,但是相对而言数据量则会陡升;取得教程自然可以节省数据量,但是数据可能会太过粗糙。其实对于这个问题的解答,DSP中有一个非常重要的
奈奎斯特采样定理,大意就是采样频率至少要是信号频率的两倍才能通过采样数据重建原始信号数据,否则会产生诸如信号混淆等问题,有兴趣的朋友可以参考进一步的资料进行了解(譬如
这里)。举例来说,
CD音频信号的采样频率为44100
Hz,即CD的音频信号每秒钟采样44100次,而采样的时间间隔大致便是1/44100秒,其所能记录的最高音频频率便是44100/2 = 22050Hz,而人耳所能听到的最高音频频率大概是20000Hz,呵呵,如此看来,44100的采样频率“刚好”够用 :)
2.量化 前面我们虽然解决了采样的频率问题(或者说时间间隔问题),但是还有一个问题需要考虑,那便是我们需要多大的空间来记录我们单个时间间隔内采样所得的数值呢?还是以上述正弦波为例,如果我们仅采用1位数值,那么就会遇到困境:1位二进制数只能表达两个状态,很显然不足以表示诸如8,-4之类的数值;如果我们采用32位数值,记录采样数据自然没有问题了,但是大部分数据位数都是0,没有尽其所用,并且增加了很多数据存储空间。就上面的正弦波而言,适当的量化位数可以是4位,正好可以表达各个数据整数位。
综上所述,如果采样频率取4(即采样间隔为1/4=0.25s),量化位数为4位时,所得的采样量化数据便是如此(如图所示):
(这里有个简单的相关示例,使用了
libsndfile,有兴趣的朋友可以
看看 :))
以上的讲解过于简单了些,让我们来算算实际的一段2分钟音频,如果按之前的CD采样率,以及16位的量化位数来存储的话,大抵需要多少空间:
2分钟有 2*60 = 120 秒,每秒采样44100次,那么总共便是采样 120 * 44100 = 5292000次,每次我们需要付出2Byte(16位)的代价,那么我们总共需要 5292000 * 2 = 10584000B的容量,即大概是10MB的大小,如果再考虑
声道的因素(所谓声道,可以理解为彼此独立存在的音频波形),那么总大小至少为20MB(仅以一般的左右声道为例)!
很显然,这个存储代价太高了一些,大家平时所见的WAV格式音频,其实存储的数据便是类似上面所述的非压缩格式,保真度最高,但是体积确实骇人……那么有没有办法将这些采样量化所得的音频数据进一步压缩呢?呵呵,想必现在大家都想到了,那便是我们现在司空见惯的MP3格式,其综合运用了诸如
哈夫曼编码等技术,虽然损失了一些音频信息,但是却达到了很高的压缩比率,有兴趣的朋友可以仔细看看 :)只是MP3格式本身存在比较大的版权问题(自然这在天朝是不存在的),所以近年来很多志士仁人都开始转向了开放的
OGG格式,有兴趣的朋友也可以了解了解 :)
OK,至此,我们取得了音频数据,并且也一定程度上解决了存储容量问题,那么我们就该试着解决第二个问题了:
“
2. 通过所得数据通过一定方法解析出其中的歌曲信息”
很可惜,仅仅通过我们获取的
PCM音频数据,我们还不足以直接获取我们想要的一些音频信息,或者说音乐信息,我们还需要借助一些特定的方法加以处理才能如愿,那么到底是什么方法呢?呵呵,姑且让我们在此打住,稍稍休息一番,留待下篇在论吧 :)