コンテンツにスキップ

第3回 音声信号とデジタル化(サンプリング・量子化)

この回の資料


学習目標

この回を終えると、次のことができるようになる:

  1. アナログ信号とデジタル信号の違いを「連続」と「離散」という観点から説明できる
  2. サンプリング(標本化)の概念とナイキスト定理を説明できる
  3. 量子化とビット深度の関係(8bit・16bit・24bitの違い)を説明できる
  4. エイリアシングとは何かを具体例で説明できる
  5. PCM・WAVファイルフォーマットの基本構造を説明できる
  6. 代表的なサンプリングレートの用途を挙げられる
  7. PythonでWAVファイルを読み込み、波形の基本情報を表示できる
  8. 発展:標本化定理の「2倍」という条件と、量子化ビット数1ビットあたり約6 dB という関係を、自分で導ける

この回では数式と直感的な説明の両方を提供しています。数式が苦手な方は「直感的説明」の部分だけでも概念を把握できるように設計しています。図の説明は代替テキストで詳細に記載しています。動画は字幕付きで、1.0〜1.5倍速で視聴可能です。自分のペースで取り組んでください。


進化の視点:なぜ 44.1 kHz や 16 kHz なのか

サンプリング周波数の選び方には、記録したい信号の周波数帯域に加えて、聴取・分析の目的、機器やモデルの仕様、データ量が関わる。耳の可聴域だけから一意に決まるわけではない。

  • ヒトの可聴域の目安は若年の健聴者でおよそ20 Hz〜20 kHzだが、年齢や個人・測定条件で変わる。44.1 kHzのナイキスト周波数は22.05 kHzである
  • 従来の狭帯域電話はおよそ300〜3,400 Hzを利用する。音声には複数の手がかりや文脈による冗長性があり、帯域を狭めても会話は可能だが、子音の聞き分けや自然さなどは影響を受ける。すべての話者のF1・F2がこの帯域に収まるから、という説明では不十分である3
  • 動物の音響研究では、その種が聞ける範囲と、記録したい発声・環境音の帯域を区別して調べる。標本化定理自体は種によって変わらない

技術への接続:16 kHz入力を使う音声認識モデルでは、8 kHz未満の帯域を利用する。これはよく使われる設定の一つで、すべてのASRの唯一の標準ではない。入力はモデルの仕様に合わせてリサンプリングし、高いサンプリングレートの効果はモデル・課題・音源をそろえて評価する。

問い:ヒト以外の動物の声を録るとき、あなたは何 Hz で標本化するか。


講義の構成


1. タイトルと学習目標

タイトル: 第3回:音声信号とデジタル化

本日の問い:

「マイクが拾った音は、どのようにしてコンピュータが扱える数値の列になるのか?」

学習のポイント(今回のキーワード):

  • アナログ / デジタル
  • サンプリング(標本化)
  • サンプリングレート(サンプリング周波数)
  • 量子化 / ビット深度
  • ナイキスト定理
  • エイリアシング
  • PCM / WAVファイル

講師メモ: 「音をコンピュータで扱う」ためのもっとも基礎的な工程を扱う回。ここを理解せずに後のMFCCや音声認識の説明を聞いても「何を処理しているのかわからない」状態になるため、丁寧に扱う。


2. アナログ信号とデジタル信号の違い

タイトル: 音は「波」、コンピュータは「数値の列」

図解説明(2つの波形の比較図の代替テキスト):

左図「アナログ信号」:なめらかに上下するサイン波。横軸は時間(t)、縦軸は電圧・音圧(amplitude)。波は途切れなく連続している。

右図「デジタル信号」:左図と同じ波に対して、一定時間ごとにサンプルを取った結果。横軸に一定間隔の点(サンプル点)があり、各点から垂直な棒(バー)が伸びて高さ(値)を示している。棒の高さは有限の数値(整数)で表されており、元の滑らかな曲線は近似になっている。

アナログ信号:

  • 連続的(Continuous): 時間も振幅(値)も途切れなく変化する
  • 例:マイクロフォンが空気振動を電気信号に変換した直後の状態
  • 例:アナログレコードの溝、アナログテープの磁気

デジタル信号:

  • 離散的(Discrete): 「ある瞬間の値」の有限個の数値の列
  • 例:コンピュータのメモリに保存された音声データ
  • 例:CDに記録されたデータ

重要な視点:

標本化は時間を離散化し、量子化は振幅を有限段階で近似する。帯域制限などの条件を満たす理想的な標本化では、標本値から元の信号を復元できる。実際の録音には量子化誤差や機器の雑音などが加わる。1


3. デジタル化の2つのステップ

タイトル: デジタル化 = サンプリング + 量子化

図解説明(2段階フローの代替テキスト):

3つのステップが横一列に並んだフロー図。 1. 「アナログ信号(なめらかな波)」→ [サンプリング] →「振幅値の時系列(連続値)」→ [量子化] →「整数値の時系列(デジタルデータ)」

ステップ1:サンプリング(標本化):

  • アナログ信号を「一定の時間間隔」で値を取り出す
  • 1秒間に何回サンプルを取るかを「サンプリングレート(Fs)」という
  • 単位:Hz(ヘルツ)。例:44100 Hz = 1秒間に44100回サンプルを取る

ステップ2:量子化(Quantization):

  • 各サンプルの振幅値を「有限個の整数値」に丸める
  • 各サンプルの値を表すビット数を「ビット深度(量子化ビット数)」という。整数PCMでは、bビットで2^b段階を表す
  • 例:16bit → 2^16 = 65536段階の数値で振幅を表す

4. サンプリング(標本化)とは何か

タイトル: サンプリング ― 時間を「飛び石」にする

図解説明(サンプリングの視覚化の代替テキスト):

上段:連続したサイン波(アナログ)。 中段:同じ波の上に、等間隔の垂直な破線(サンプリングタイミング)が引かれている。 下段:各破線の位置での波の値のみが点(●)として残り、それ以外の部分は消えている。点の間は何もない。

定義:

サンプリングレート(Fs)= 1秒あたりのサンプル数(Hz)

具体例:

  • Fs = 8000 Hz なら、1秒間に8000点のサンプルを取る
  • 1サンプル間の時間間隔(サンプリング周期)= 1 / Fs 秒
  • Fs = 44100 Hz の場合:1 / 44100 ≒ 0.0000227秒(22.7マイクロ秒)ごとにサンプル

重要な問い:

サンプリングレートが低すぎると何が起きるか? → 次節のナイキスト定理で答える


5. ナイキスト定理

タイトル: ナイキスト定理 ― 「何Hzまでサンプリングできるか」の限界

数式:

\[F_s > 2 f_{\max}\]

言葉で言うと:

帯域制限した信号を一意に復元するため、この授業ではサンプリングレートを最高周波数の2倍より大きく取る。

直感的な説明: 高い周波数ほど周期が短い。最高周波数の1周期あたり2点を超える標本が必要になるが、「山と谷を取ればよい」という意味ではない。ちょうど2倍では位相によって情報を失う。例えば \(f=F_s/2\) の正弦波は、\(x[n]=\sin(\pi n)=0\) となり、振幅を読み取れない。実機ではフィルタの遷移帯域にも余裕を持たせる。1

図解説明(サンプリングと再現の比較の代替テキスト):

2行の対比図。 上行「十分なサンプリングレート(Fs > 2×f_max)」:1周期あたり2点を超える標本があり、帯域制限と理想的な補間を仮定すれば元の波を復元できる。 下行「不十分なサンプリングレート(Fs < 2×f_max)」:最高周波数の1周期あたりの標本が2点未満となり、低い周波数の波と区別できなくなる(エイリアシング発生)。

具体例(人の声への適用):

  • 基本周波数F0は話者・発声条件で変わり、音声はその倍音や摩擦成分も含む
  • F0だけから必要なサンプリングレートを決めることはできない
  • 電話品質の音声(8kHz サンプリング)のナイキスト周波数:4000Hz
  • → 利用する信号帯域を4,000 Hz未満に制限する。事前に除去しなかった高域成分は、単に消えるのでなく折り返す
導出①:なぜ「2倍」なのか、そして超えると何が起きるか

周波数 \( f \) の正弦波 \( x(t)=\sin(2\pi f t) \) を、間隔 \( T_s = 1/F_s \) で標本化する。得られるのは

\[ x[n] \;=\; \sin(2\pi f \, n T_s) \;=\; \sin\!\left(2\pi \frac{f}{F_s} n\right) \]

正弦波の位相は \( 2\pi \) 周期なので、\( f/F_s \) が整数だけずれても標本の列は同じになる。つまり

\[ \sin\!\left(2\pi \frac{f + kF_s}{F_s} n\right) \;=\; \sin\!\left(2\pi \frac{f}{F_s} n + 2\pi k n\right) \;=\; \sin\!\left(2\pi \frac{f}{F_s} n\right) \qquad (k \text{ は整数}) \]

標本の列だけを見ても、\( f \) と \( f + kF_s \) を区別できない。 また \(F_s-f\) の正弦波は \(f\) の正弦波の符号を反転した列になる。実数信号の帯域を \(0 \le f < F_s/2\) に制限するのは、この曖昧さを避けるためである。境界の正弦波も考慮し、ここでは \(F_s > 2f_{\max}\) とする。

見かけの周波数は、\( f \) に最も近い \( F_s \) の整数倍との差になる。

\[ f_{\text{alias}} \;=\; \left| f - \mathrm{round}\!\left(\frac{f}{F_s}\right) \times F_s \right| \]

数値で確かめる:\( F_s = 8{,}000 \) Hz のとき、5,000 Hz は \( |5{,}000-8{,}000| = 3{,}000 \) Hz に、9,000 Hz は \( |9{,}000-8{,}000| = 1{,}000 \) Hz になる。「エイリアシング」節の具体例と図解は、どちらもこの式が出した値である。

数学上の境界と、記録したい帯域を区別する

ナイキスト周波数は定義により \(F_s/2\) である。どの \(F_s\) を選ぶかは、信号の帯域、聴取・分析目的、フィルタ、モデルの仕様などで決める。8 kHz、16 kHz、44.1 kHzに対する境界は、それぞれ4,000 Hz、8,000 Hz、22,050 Hzで、実際の通過帯域には余裕を設ける。

ここで示したのは「区別できなくなる」ことまでで、条件を満たせば元の波形を完全に復元できるという定理の後半(標本化定理の証明)は扱わない。復元公式とその収束の議論が必要で、この授業で扱う数理の範囲外である。

使った数学:正弦関数の周期性(数I・数II)。絶対値と整数への丸め。


6. 量子化とビット深度

タイトル: 量子化 ― 振幅を「段階」に変換する

図解説明(量子化の視覚化の代替テキスト):

上段:連続した正弦波(縦軸が連続値)。 下段:同じ波に対して、縦軸が段階的な「階段」になっている。波の値が各段階のいずれかに丸められている。段階数が少ない(例:8段階 = 3bit)と、階段の「段差」が大きく、元の波から離れてしまう箇所がある。

ビット深度と段階数の対応:

ビット深度 段階数(量子化レベル) 用途
8 bit 2^8 = 256 段階 一部のレトロゲームのサンプル音源など
16 bit 2^16 = 65,536 段階 CD・多くの整数PCM音声ファイル
24 bit 2^24 = 16,777,216 段階 スタジオ録音・高品質音声
32 bit(float) 浮動小数点数 音声処理計算の内部表現(Pythonでよく使う)

量子化誤差(Quantization Error): 丸めによるずれのこと。同じ振幅範囲の一様量子化なら、ビット深度が低いほど量子化幅が大きい。誤差は雑音のように聞こえる場合も、信号と相関した歪みになる場合もある。32 bit floatは指数部と仮数部を持つため、32 bit整数PCMと同じ等間隔の量子化ではない。2

直感的な例:

8bitの256段階は「色の段階数」に例えると、白〜黒の中間が256色しか使えないようなもの。16bitなら65,536色。同じ振幅範囲では16bitの方が量子化幅は細かい。音の違いを聞き分けられるかは、信号レベルや再生条件による。

導出②:1ビット増やすと、なぜ約6 dB よくなるのか

ビット深度 \( b \) のとき、段階数は \( 2^b \) である(上の表のとおり)。信号の振幅の全幅を \( A \) とすると、1段階の幅は

\[ \Delta \;=\; \frac{A}{2^{b}} \]

量子化誤差は、最も近い段階に丸めたときのずれなので \( -\Delta/2 \) から \( +\Delta/2 \) の間に入る。この誤差がその範囲に一様に散らばると見なすと、誤差の大きさの二乗平均(誤差電力)は

\[ \mathbb{E}[e^2] \;=\; \frac{1}{\Delta}\int_{-\Delta/2}^{\Delta/2} e^2 \, de \;=\; \frac{\Delta^2}{12} \]

信号電力を \( P \) とすると、信号対雑音比は \( P / (\Delta^2/12) \) である。\( \Delta \) は \( 2^b \) に反比例するから、\( b \) を1増やすと \( \Delta \) は半分、誤差電力は4分の1になる。デシベルで測ると

\[ 20\log_{10}\left(2^{b}\right) \;=\; b \times 20\log_{10} 2 \;=\; 6.02\,b \ \text{dB} \]

同じ信号電力・振幅範囲と上の誤差モデルの下では、1ビットあたり約6.02 dB改善する。 これは絶対的なSNRそのものではなく、ビット数による変化の部分である。

数値で確かめる:\( 20\log_{10}(2^{16}) = 96.33 \) dB、\( 20\log_{10}(2^{8}) = 48.16 \) dB、\( 20\log_{10}(2^{24}) = 144.49 \) dB。16ビットと8ビットの差は 48.16 dB で、ちょうど8ビット分(\( 6.02 \times 8 \))にあたる。

「16ビットで約98 dB」という数字を見たときは

全幅を \(A\) としたフルスケール正弦波では、振幅は \(A/2\)、電力は \(P=A^2/8\) である。したがって \(10\log_{10}\{(A^2/8)/(A^2/(12\cdot2^{2b}))\}=6.02b+10\log_{10}(3/2)\simeq6.02b+1.76\) dBとなり、16ビットで約98.08 dBになる。上の96.33 dBはビット数に依存する項だけで、信号電力を定めずにSNRと呼ぶことはできない。実際の録音機器のSNRは回路雑音などにも制限される。2

誤差を一様分布と見なした点は近似である。段階の幅に対して信号の動きが小さいときはこの見方が成り立たず、誤差が信号と相関を持って耳につく歪みになる。この扱い(ディザなど)は、この授業で扱う数理の範囲外である。

使った数学:一様分布の二乗平均(積分)、対数の性質 \( \log a^b = b\log a \)(数II)。


7. エイリアシング(Aliasing)とは何か

タイトル: エイリアシング ― 再現できない周波数が「偽物の波」になる

定義: ナイキスト周波数(= Fs / 2)よりも高い周波数成分が含まれる信号をサンプリングすると、その成分が「折り返して」低い周波数の信号として誤って現れる現象。

図解説明(エイリアシングの例の代替テキスト):

横軸:時間(t)。縦軸:振幅(amplitude)。 実線(青):高い周波数の元信号(例:9000 Hzの正弦波)。波が細かく上下している。 点(●):Fs = 8000 Hz でサンプリングした点。点の数が少なく、波の形を追えていない。 破線(赤):標本に一致する、ナイキスト周波数未満の1000 Hz(= 9000 - 8000)の波。帯域制限された補間ではこの低い周波数として復元される。単に標本点を直線で結ぶ操作とは区別する。

具体例:

  • サンプリングレート Fs = 8000 Hz(ナイキスト周波数 = 4000 Hz)
  • 5000 Hz の信号を録音しようとする
  • 5000 Hz > 4000 Hz(ナイキスト超え)
  • → 折り返し: 8000 - 5000 = 3000 Hz の偽の信号として現れる

対策:アンチエイリアシングフィルタ: A/D変換前にローパスフィルタで帯域外成分を十分に減衰させる。これがアンチエイリアシング処理である。デジタル信号のダウンサンプリングでも、新しいナイキスト周波数に合わせたフィルタが必要になる。実際のフィルタには遷移帯域がある。

日常の例:

  • 映画で車輪が逆回転して見える現象も時間方向のエイリアシングの例。回転速度だけでなく、同じ形のスポークが繰り返す頻度とフレームレートの関係が効く

8. PCMとは何か

タイトル: PCM ― デジタル音声の最も基本的な形式

PCM(Pulse Code Modulation:パルス符号変調)の説明(ここでは線形PCM):

  • サンプリングと量子化を行って得られたデジタル音声データの表現形式
  • 「生の(圧縮なしの)デジタル音声」の基本形式
  • 各サンプルを固定長のバイナリ(0と1の列)として記録する

図解説明(PCMデータの表現の代替テキスト):

横軸に時間(サンプル番号)、縦軸に振幅値(整数)を取ったバーグラフ。各バーの高さが1サンプルの量子化値を表している。下には「0000 0000 0110 1011」のような16桁の2進数が並んでいる。

PCMの特徴:

  • 量子化済みのサンプル値を非圧縮で保存する。量子化前のアナログ信号を無損失で保存するという意味ではない
  • ファイルサイズが大きい
  • MP3・AACなどは PCM データを圧縮したもの

データサイズの計算:

\[\text{データレート(byte/秒)} = \frac{F_s \times \text{ビット深度} \times \text{チャンネル数}}{8}\]

例:CD音質(44100 Hz × 16 bit × 2ch)の場合: $\(= \frac{44100 \times 16 \times 2}{8} = 176,400 \text{ byte/秒}\)$

1分の音声データは10,584,000 byte=10.584 MB(約10.09 MiB)。ファイル全体にはヘッダなどの容量が加わる。


9. WAVファイルフォーマット

タイトル: WAVファイルの中身を覗いてみる

WAVファイルとは:

  • RIFFのチャンク構造を使う音声ファイル形式(WAVE)
  • PCMがよく使われるが、浮動小数点音声や圧縮音声を格納するWAVもある
  • 拡張子:.wav
  • 読める符号化方式はアプリやライブラリに依存する。「.wav」だけでは内部形式は決まらない4

WAVファイルの構造(チャンク構造):

[RIFFヘッダ] (12 byte)
  ├── "RIFF" という4文字のマジックナンバー
  ├── ファイル全体のサイズ − 8(4 byteのサイズ欄)
  └── "WAVE" という4文字

[fmtチャンク] (基本的なPCMでは 8 byteのチャンクヘッダ+16 byteの形式情報)
  ├── 音声フォーマット(PCM = 1)
  ├── チャンネル数(1=モノラル, 2=ステレオ)
  ├── サンプリングレート(Hz)
  ├── データレート(byte/秒)
  ├── ブロックアライメント
  └── ビット深度(8, 16, 24, 32)

[dataチャンク] (8 byteのチャンクヘッダ+可変長データ)
  └── PCMサンプルデータ(実際の音声波形データ)

講師メモ: ヘッダを「ファイルの身分証明書」と例える。「このファイルは何 Hz で録音された、何 bit の、何チャンネルの音声です」という情報が先頭に書いてある。

図解説明(WAVファイル構造の代替テキスト):

基本的なPCMの例として、RIFFヘッダ12 byte、fmtチャンク24 byte、dataチャンクの8 byteヘッダと音声データを示す。拡張形式ではfmtの大きさが変わり、別のチャンクやパディングが入ることもある。dataが必ず「残り全部」とは限らない。4


10. 代表的なサンプリングレートと用途

タイトル: サンプリングレートごとの用途と特性

一覧表:

サンプリングレート ナイキスト周波数(上限) 用途・特性
8,000 Hz (8 kHz) 4,000 Hz 従来の狭帯域電話・G.711など。VoIP全般が8 kHzという意味ではない
16,000 Hz (16 kHz) 8,000 Hz 多くの音声認識モデルで使われる入力設定の一つ
22,050 Hz (22.05 kHz) 11,025 Hz librosa.loadの既定値。用途・音質は音源や符号化方式にもよる
44,100 Hz (44.1 kHz) 22,050 Hz CD(オーディオCD規格)。人間の可聴域(〜20,000 Hz)を十分カバー
48,000 Hz (48 kHz) 24,000 Hz 動画・放送・Blu-ray・YouTube。映像制作の標準
96,000 Hz (96 kHz) 48,000 Hz ハイレゾ音楽・スタジオ録音。超高周波域を含む

44.1 kHzと可聴帯域の関係:

  • 人間の可聴域は約 20 Hz〜20,000 Hz(加齢で高音域は低下)
  • 20 kHzまでを対象にすると、標本化周波数は40 kHzを超える必要がある
  • 44.1 kHzならナイキスト周波数は22.05 kHzで、20 kHzとの間にフィルタの遷移帯域を設けられる
  • この帯域条件だけで「44.1」という規格値が一意に導かれるわけではない

音声認識モデルの入力レートに合わせる:

  • 16 kHzは、利用帯域とデータ量のバランスを取る設定の一つ
  • 学習時の設定と違うレートの配列を、そのまま同じ入力として渡さない

11. Pythonでwavファイルを読む ― 環境準備

タイトル: Google Colab で音声処理の第一歩

使用するライブラリ:

# 標準ライブラリ(インストール不要)
import wave          # WAVファイルの読み書き

# 数値計算・可視化(Colabには最初から入っている)
import numpy as np
import matplotlib.pyplot as plt

# 音声処理ライブラリ(ImportErrorなら別セルで %pip install librosa soundfile)
import librosa
import librosa.display
import soundfile as sf

# Colab上で音声を再生するには
from IPython.display import Audio

Google Colab でのファイルアップロード:

# Colabにローカルファイルをアップロードする方法
from google.colab import files
uploaded = files.upload()   # ダイアログが開くのでWAVファイルを選ぶ

# アップロードされたファイル名の確認
print(list(uploaded.keys()))

講師メモ: 次節のコード例は、学生がColab上でそのまま実行できるものを提供する。第6回の演習で詳しくやるため、ここでは「動かしてみる」体験が主目的。


12. Pythonでwavファイルを読む ― コード例①(wave モジュール)

タイトル: wave モジュールでヘッダ情報を読む

コード例:

import wave
import numpy as np

# WAVファイルを開く
filename = "sample.wav"   # 読み込むファイル名(Colabにアップロードしたもの)

with wave.open(filename, 'r') as wf:
    # ヘッダ情報を取得
    n_channels = wf.getnchannels()     # チャンネル数(1=モノラル, 2=ステレオ)
    sample_width = wf.getsampwidth()   # サンプルごとのバイト数(2 = 16bit)
    frame_rate = wf.getframerate()     # サンプリングレート(Hz)
    n_frames = wf.getnframes()         # フレーム数=1チャンネルあたりのサンプル数
    duration = n_frames / frame_rate   # 音声の長さ(秒)

    print(f"チャンネル数: {n_channels}")
    print(f"ビット深度: {sample_width * 8} bit")
    print(f"サンプリングレート: {frame_rate} Hz")
    print(f"フレーム数(各チャンネルのサンプル数): {n_frames}")
    print(f"音声の長さ: {duration:.3f} 秒")

    # この例は16 bit整数PCM専用。別のビット深度をint16として読まない
    if sample_width != 2:
        raise ValueError("この例では16 bit整数PCMのWAVを選んでください")

    # 波形データを読み込む
    raw_data = wf.readframes(n_frames)    # バイト列として取得

# バイト列を数値配列(numpy array)に変換
audio_data = np.frombuffer(raw_data, dtype="<i2").reshape(-1, n_channels)
# little-endian int16。形状は(フレーム数, チャンネル数)

print(f"\n波形データの形状: {audio_data.shape}")
print(f"最小値: {audio_data.min()}, 最大値: {audio_data.max()}")

出力例:

チャンネル数: 1
ビット深度: 16 bit
サンプリングレート: 16000 Hz
フレーム数(各チャンネルのサンプル数): 32000
音声の長さ: 2.000 秒

波形データの形状: (32000, 1)
最小値: -18432, 最大値: 21056

講師メモ: この例は16 bit整数PCM専用で、形状は(フレーム数, チャンネル数)。ステレオでも2秒×16,000 Hz=32,000フレームで、サンプル値の総数は64,000個になる。waveの対応形式はPythonの版にも依存する。ここではPython 3.12の仕様で検証し、ほかの形式にはlibrosa/soundfileを使う。5


13. Pythonでwavファイルを読む ― コード例②(librosa)

タイトル: librosa で波形を読んで可視化する

コード例:

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Audio

# --- librosaでWAVファイルを読み込む ---
filename = "sample.wav"

# y: 浮動小数点の波形。整数PCMは通常-1〜1程度にスケーリングされる
# ピークを1にそろえる正規化ではない。float WAVなどでは範囲外もあり得る
# sr: サンプリングレート
y, sr = librosa.load(filename, sr=None, mono=True)  # 元レートを保持し、モノラル化

print(f"サンプリングレート: {sr} Hz")
print(f"波形データの長さ: {len(y)} サンプル")
print(f"音声の長さ: {len(y) / sr:.3f} 秒")
print(f"データ型: {y.dtype}")  # float32 のはず

# --- 波形を可視化する ---
fig, ax = plt.subplots(figsize=(12, 4))

# 横軸を「秒」にするために時間軸を作る
time_axis = np.arange(len(y)) / sr

ax.plot(time_axis, y, color='steelblue', linewidth=0.5, alpha=0.8)
ax.set_xlabel("時間 (秒)")
ax.set_ylabel("振幅")
ax.set_title(f"音声波形 ({filename})")
ax.set_xlim([0, len(y) / sr])
ax.axhline(y=0, color='gray', linewidth=0.5)
plt.tight_layout()
plt.show()

# --- Colab上で音声を再生する ---
Audio(y, rate=sr)

図解説明(出力される波形グラフの代替テキスト):

横軸「時間(秒)」・縦軸「振幅(-1.0〜1.0)」の折れ線グラフ。会話音声の場合、発話区間では波形の振れが大きく(±0.5程度の上下)、無音区間では波形がほぼゼロに近い水平線になっている。

sr=None のポイント: デフォルトではlibrosaは22,050 Hzにリサンプリングする。sr=Noneは元のレートを保つ指定で、チャンネル数を保つ指定ではない。既定のmono=Trueではモノラル化される。6


14. Pythonでwavファイルを読む ― コード例③(ステレオ処理)

タイトル: ステレオファイルと正規化

コード例:

import librosa
import numpy as np

filename = "stereo_sample.wav"   # ステレオファイルの例

# ステレオの場合: mono=False で2チャンネルを保持
y_stereo, sr = librosa.load(filename, sr=None, mono=False)

print(f"ステレオデータの形状: {y_stereo.shape}")
# → (2, n_samples) : 2行がL/Rチャンネル

# この例は2チャンネルのファイルを対象とする
if y_stereo.ndim != 2 or y_stereo.shape[0] != 2:
    raise ValueError("この例では2チャンネルの音声ファイルを選んでください")

# 左右チャンネルを分離
y_left = y_stereo[0]    # Lチャンネル
y_right = y_stereo[1]   # Rチャンネル

# モノラルに変換(L+Rの平均)
y_mono = np.mean(y_stereo, axis=0)
print(f"モノラル変換後の形状: {y_mono.shape}")

# --- データの正規化 ---
# int16 の波形を [-1.0, 1.0) にスケーリングする(ピーク正規化ではない)
def normalize_int16(audio_int16):
    """int16の全符号範囲を約-1〜1のfloat32に対応させる"""
    return audio_int16.astype(np.float32) / 32768.0

# 使い方(wave モジュールで取得した audio_data に適用)
# audio_normalized = normalize_int16(audio_data)

15. サンプリングレートと音質の比較

タイトル: サンプリングレートを変えると音はどう変わるか

コード例(Colab演習):

import librosa
import numpy as np
from IPython.display import Audio, display

# 元ファイルを読み込む(元のサンプリングレートを保持)
y_original, sr_original = librosa.load("sample.wav", sr=None)

print(f"元のサンプリングレート: {sr_original} Hz")

# 異なるサンプリングレートにリサンプリングして比較
for target_sr in [8000, 16000, 22050, 44100]:
    y_resampled = librosa.resample(y_original, orig_sr=sr_original, target_sr=target_sr)
    print(f"\n--- {target_sr} Hz ---")
    display(Audio(y_resampled, rate=target_sr))

体験の目的: 同じ音源の利用帯域がどう変わるかを聴き比べる。聞こえ方は元音源と聴取条件に依存する。アップサンプリングしても、元音源にない高域成分は戻らない。再生ウィジェットの既定の音量正規化があるため、この例では音量差を評価しない。


16. デジタル化のまとめと音声処理パイプラインへの位置づけ

タイトル: 今回学んだことと全体パイプラインの中の位置

図解説明(パイプライン図の代替テキスト):

第1回で扱ったパイプライン図。今回学んだ「デジタル化(ステップ2)」のボックスが太枠・濃い色でハイライトされており、他のステップは薄い色で表示されている。「ステップ2:デジタル化」のボックスの下に「サンプリング・量子化・PCM・WAVファイル」というキーワードが付記されている。

今回のまとめ:

概念 要点
アナログ vs デジタル 連続値 vs 離散値の数値列
サンプリング 一定時間ごとに値を取り出す。単位は Hz
ナイキスト定理 帯域制限し、ここではFs > 2 × f_maxとする。境界上の正弦波に注意
量子化 振幅を有限段階の整数に丸める。ビット深度が精度を決める
エイリアシング ナイキスト超えの周波数が「偽物の低周波」として現れる現象
PCM 非圧縮のデジタル音声データの基本表現
WAVファイル 音声形式やデータをチャンクに格納する形式。PCM以外もある
16 kHz / 44.1 kHz 16 kHzは多くのASRモデルの入力設定の一つ、44.1 kHzはCDの設定

17. よくある誤解と注意点

タイトル: 気をつけよう ― よくある誤解

誤解1:「サンプリングレートが高ければ何でもよい」 説明: 同じ時間・ビット深度・チャンネル数のPCMなら、高いほどデータ量が増える。利用したい帯域とモデルの入力仕様に合わせ、精度への効果は条件をそろえて評価する。

誤解2:「ナイキスト定理は理論上の話で実際には関係ない」 説明: 標本化やダウンサンプリングの設計に直接関わる。帯域外成分が折り返すと、後から元の成分と区別して取り除くことが難しくなる。

誤解3:「librosa.load は wav しか読めない」 説明: librosaはsoundfileなどのバックエンドが対応する形式を読める。内部で常にffmpegを使うわけではなく、対応形式は環境にも依存する。6

誤解4:「16bit と 32bit(float) は同じデータ」 説明: int16は−32,768〜32,767の整数、float32はそれより広い範囲を表す浮動小数点形式。音声処理では約−1〜1にスケーリングしたfloatをよく使うが、floatの表現範囲が−1〜1という意味ではない。整数からfloatへの変換だけで失われた精度が戻るわけでもない。librosa.loadの既定のdtypeはfloat32。6


18. 次回(第4回)の予告

タイトル: 次回は「スペクトログラム・周波数分析」

  • 形式: オンライン同期回(Zoom)
  • テーマ: 音声の「周波数の時間変化」を可視化する
  • 内容: フーリエ変換の直感的理解・短時間フーリエ変換(STFT)・スペクトログラムの読み方

事前学習(次回のオンライン同期回まで):

  1. Google Colabでコードを実行してみる 本文のコード例(12〜13節)を Colab に貼り付けて、自分の声やお気に入りの音楽ファイルで動かしてみる。
  2. 試した内容と、気づいたこと・つまずいたことをメモしておく(第4回で共有する)

  3. 「フーリエ変換」を検索してイメージをつかむ 「フーリエ変換 直感的 わかりやすい」などで検索し、動画や図解記事を1つ読む・視聴する。 数式は理解しなくてよい。「音を周波数に分解する」という直感だけ持っておく。

  4. 任意:以下の問いを考えておく

  5. 人間の話し声の「ド・レ・ミ」はスペクトログラムでどう見えると思うか?
  6. 男性の声と女性の声をスペクトログラムで比べると、どんな違いがあると思うか?

19. まとめとテストの案内

タイトル: 第3回のまとめ

学習の振り返り:

  1. 音声のデジタル化は「サンプリング(時間の離散化)」と「量子化(振幅の離散化)」の2ステップで行われる
  2. 標本化定理:信号を帯域制限し、この授業では最高周波数の2倍より大きいサンプリングレートを取る
  3. ナイキスト条件を破るとエイリアシングが発生し、誤った周波数成分が現れる
  4. 同じ振幅範囲の一様量子化では、ビット深度を増やすと量子化幅が小さくなる。実際の音質は機器や音源にも依存する
  5. WAVはチャンク構造のファイル形式であり、PCM以外の音声も格納できる
  6. Python(librosa / wave モジュール)でWAVファイルを読み、波形を可視化できる

次のステップ:

  • テスト5問を解く(本文末に掲載、Google Forms)
  • 事前学習(18節)に取り組む
  • 余力があればColabでコード例を動かしてみる

テスト問題(5問・4択・解答解説付き、Google Formsで回答)

問1

サンプリングレートが8,000 Hzのとき、ナイキスト周波数(サンプリングレートの半分)はいくつか。

A) 2,000 Hz
B) 4,000 Hz
C) 8,000 Hz
D) 16,000 Hz

正解: B

解説: ナイキスト周波数は8,000÷2=4,000 Hz。ただし4,000 Hzちょうどの正弦波を任意の位相で正確に復元できるという意味ではなく、利用帯域はこの境界より低く取る。従来の狭帯域電話の通過帯域はおよそ300〜3,400 Hzである。3


問2

16bit の量子化で音声を記録する場合、振幅を何段階の値で表すことができるか。

A) 16 段階
B) 256 段階
C) 4,096 段階
D) 65,536 段階

正解: D

解説: 量子化レベル(段階数)= 2^ビット深度。16bit の場合:2^16 = 65,536 段階。 A(16段階)は 2^4(4bit)に対応、B(256段階)は 2^8(8bit)、C(4,096段階)は 2^12(12bit)。16bit はCDにも採用されているが、量子化誤差の聞こえ方は信号レベル・録音条件・再生環境に依存する。


問3

エイリアシングが発生する条件として正しいものはどれか。

A) サンプリングレートが高すぎるとき
B) ビット深度が低いとき
C) 信号に含まれる最高周波数がサンプリングレートの半分を超えているとき
D) 録音時間が短すぎるとき

正解: C

解説: Cは、ここで扱う低域からの標本化で帯域外成分が折り返す条件。境界ちょうどにも位相による情報損失があるため、本文では \(F_s>2f_{\max}\) とした。ビット深度の低さは量子化の問題であり、録音時間の短さは周波数分析の分解能などに関わる別の問題である。


問4

以下のうち、WAVファイルのfmtチャンク(ヘッダ)に記録されている情報として誤っているものはどれか。

A) サンプリングレート(Hz)
B) 録音場所と日時
C) チャンネル数(モノラル/ステレオ)
D) ビット深度(量子化ビット数)

正解: B

解説: fmtチャンクは符号化方式・チャンネル数・サンプリングレートなどを記録する。録音場所や日時はfmtの基本フィールドではない。WAV全体では、別のメタデータ用チャンクに日時などを格納する形式もあるため、「WAVには日時を記録できない」とは言わない。4


問5

次のPythonコードを実行した際の出力として正しいものはどれか。

import librosa
y, sr = librosa.load("voice.wav", sr=None)
print(f"サンプル数: {len(y)}, サンプリングレート: {sr}")

voice.wav の実際のサンプリングレートが 16,000 Hz で、音声の長さが 3 秒だとする。

A) サンプル数: 8000, サンプリングレート: 16000
B) サンプル数: 16000, サンプリングレート: 16000
C) サンプル数: 48000, サンプリングレート: 16000
D) サンプル数: 66150, サンプリングレート: 22050

正解: C

解説: 総サンプル数 = サンプリングレート × 音声の長さ(秒) = 16,000 Hz × 3 秒 = 48,000。 sr=None を指定しているため、元のサンプリングレート 16,000 Hz が保持される。 D(66,150サンプル・22,050 Hz)は sr=None を指定せずに librosa のデフォルト(22,050 Hz)にリサンプリングされた場合の値(22,050 × 3 = 66,150)であり、sr=None がある場合は誤り。Aは長さを0.5秒と間違えた場合、Bは長さを1秒と間違えた場合の値。


事前学習(第4回「スペクトログラム・周波数分析」の準備)

第4回はオンライン同期形式で、音声の「周波数成分の時間変化」を可視化するスペクトログラムを扱います。以下の事前学習に取り組んでおくことで、授業の理解度が大きく高まります(所要時間:合計20〜30分)。

1. Google Colabでこの回のコード例を実行する(強く推奨)

12〜13節のコードをColab に貼り付け、自分の声を録音したファイルや手持ちの音楽ファイルで実行する。

気づいたこと・つまずいたことのメモ先: メールで担当教員に送る(やれる範囲で)

2. フーリエ変換のイメージをつかむ(任意だが強く推奨)

以下のいずれかの方法でフーリエ変換の「直感」をつかんでおく。数式の理解は不要。

  • 動画: YouTubeで「フーリエ変換 わかりやすく」を検索。3Blue1Brownの「But what is the Fourier Transform?」(日本語字幕あり)が特に優れている。
  • 記事: Qiitaなどで「フーリエ変換 直感」を検索し、図解が豊富な記事を1本読む。

確認したい直感: 「音を分解すると、どんな周波数の音がどれくらい含まれているかがわかる」

3. 考えておく問い(任意・次回授業の冒頭で取り上げます)

余力があれば、以下の問いに対して自分なりの予想・仮説を立てておく(正解不要)。

  1. 「ア」と「イ」の音をスペクトログラムで見ると、どんな違いがあると思うか?
  2. 音楽の「ド(約262Hz)」と「ラ(約440Hz)」の音は、スペクトログラムでどのように区別できると思うか?
  3. 話し声と歌声を比べると、スペクトログラムでどんな違いが見えると思うか?

参考資料

作成:小野原彩香 / 内容確認・修正:2026年10月20日