2 音のデジタルデータ

音には、音階、音量、音色などの色々な要素がある。 また、音は複数の音が重なっている場合でも、 我々はそれを複数の音の重なりであると認識できる。

同じく波動現象である光にも、色の種類、色の明るさ、 色の鮮やかさなどの要素があるが、 色は複数の色が重なると、我々はそれを複数の色とは認識せずに、 それを合成した一つの色としか認識できない。 これは光と音の認識の違いの特徴的なところで、 音の方はそれにより和音や合奏、 そして複数の楽器編成による音楽というものが成立することになっている。

一方、音楽を記録する場合、大編成のオーケストラのスコア (総譜) のように この楽器はこの音、この楽器はこの音、のように記録する方式1では、楽器編成によりデータ量が変わり、 また、同じ曲でも演奏者毎の微妙な演奏の違いを再現することは難しい。

よって、レコードや CD も含め通常の記録方式は、実際の音の波動の 物理的な表現である空気中の波の振幅を時系列毎に保存する、 という方法を取っている。 これは、スコアを記録する方式に比べてデータ量ははるかに大きくなる。

コンピュータで使用されるデジタル音声データ (WAV, AU, AIFF などの形式) の場合もこの後者の方式で、物理的な振幅を電気信号の振幅に置き換え、 それを時間と振幅に関してデジタル化 (標本化と量子化) をしたものであり、 数千、あるいは数万分の 1 秒毎に、その音の波動の振幅を整数値 (8bit あるいは 16bit の整数) として順に保存している。

逆に言えば、$\sin x$ などの単純な振動関数を用いて このような振動のデータを作り出せば、 比較的容易にデジタル音声データを自作することができる。

例えば、

\begin{displaymath}
y=f_1(t) = A \sin 2\pi h t\hspace{1zw}(0\leq t\leq T)\end{displaymath} (1)

という関数 ($A$, $h$ は正の定数) は、周期が $1/h$、すなわち 周波数 ($=$ 1 秒間の振動数) が $h$ であるような周期関数なので、 これは周波数が $h$ Hz である音波振動に対応する。

これを、1/44100 秒毎に、-32767$\sim$32767 の範囲の整数値として出力すれば、 いわゆる linear PCM データとなる。 そのようなものを生成する C 言語で書けば、例えば以下のようになる。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void)
{
    double T=3.0;   /* 3 秒のデータ */
    double h=440.0; /* 440Hz の音 */
    double vol=0.7; /* 70% のボリューム */
    double sample=44100.0; /* 標本化周波数 44100Hz */
    double t,y;
    short int z;    /* -32767~32767 の整数 */

    for(t=0.0; t<=T; t+=1.0/sample){
        y=vol*sin(2.0*M_PI*h*t); /* M_PI=円周率 (in math.h) */
        z=32767*y;
        putchar(z&0x00ff);      /* 下位 8 bit を出力 */
        putchar((z>>8)&0x00ff); /* 上位 8 bit を出力 */
    }
    return 0;
}

竹野茂治@新潟工科大学
2007年8月7日