オーディオファイル コーデックまとめ

この記事は [NTTコミュニケーションズ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nttcom)の3日目の記事です。昨日は @iwashi86 さん の[記事](https://qiita.com/iwashi86/items/126b6a7b0ae5ccf6f43e)でした。


## はじめに

今年4月に入社して音声認識サービスに関わっているものです。音声データを扱うにあたり、こんな資料があったらいいなと思ったため、音声ファイルのフォーマット・コーデックについてまとめてみました。
わかりやすさのために音声と表現していますが、声に限らず音響信号を「音声」とまとめて表現しています。
出典が明らかな情報を極力記載するようにしておりますが、誤りや不正確な表現等がありましたら申し訳ありません。

# 音声データの基本

音源が振動すると空気を媒体として粗密波が発生し、それが聴覚器官を通して脳に伝わることで人間は音を認識すると考えられます。音声データはこの粗密波をマイクロフォンを用いてアナログな電気信号として検出したうえでデジタルなデータに変換することで得られます。一般にアナログ信号からデジタル信号に変換するときに、情報の損失が発生します。しかし、標本化定理によって、元のアナログ信号に含まれる波が X Hz 以下であることを仮定すると、2X Hz 以上のサンプリングレートでデジタル変換することで情報は完全に保存されます。[^yaruo]（アナログ信号は三角関数の線形和で表せるので）
この時、各サンプルにはある時刻の音声の振幅情報が入っていますが、こちらもアナログ信号では連続値であるため、デジタル信号に変換するときに量子化処理が行われ、量子化誤差が発生することには注意する必要があります。

人間の可聴域は 10 Hz ~ 20 kHz 程度といわれており、理論上は、20 KHz の2倍の40 kHz でサンプリングを行えば人間が聞く分には違いがわからない形で音声信号を得ることができます。実際にはデジタル処理を理想的に行うことは不可能なので、もっと高い周波数でサンプリングを行う場合も多々あります。

CDに収録される音声のサンプリング周波数は 44100 Hzで、量子化ビットは16bitです。
近年登場した、ハイレゾ音声は、24 bit / 96 kHz などが使用されています。
音声認識では、16 bit / 16 kHz が使用されることが多く、
電話音声では、8 or 16 bit / 8 kHz が使用されることが多いです。

## 音声ファイルの種類

16bit / 44100 Hz でサンプリングされた5分のステレオ音声ファイルは非圧縮で保存するとどれくらいの容量になるでしょうか？

$$ 16 \times 44100 \times 5 \times 60 \times 2 = 423360000 $$ 

上式の単位はbitなので、約 53 MB になります。非圧縮だとデータ量が膨大になってしまうので、圧縮をするわけです。[^2gb]
圧縮にも可逆圧縮と非可逆圧縮の2種類があり、前者はデータを完全に復元できるが圧縮率が悪い方式で、後者は圧縮率が高い代わりに元のデータに復元することが不可能な方式です。

人間が音楽鑑賞をしたり、発話内容を聞き取るだけなら、非可逆圧縮をしてもほとんど問題がありませんが、音質にこだわる場合や、音声認識に使用する場合など、非可逆圧縮が適さないケースもあります。
圧縮・復元には計算コストが発生するため、非圧縮・可逆圧縮・非可逆圧縮のどれを採用するかを用途によって使い分ける必要があります。

## 非圧縮
非圧縮な音声ファイルとは、中に音声波形の振幅の情報がただ並んでいる形です。
取り扱いが簡単なので、容量を気にしない場合はこの形式が一番だと思われます。
デジタル音声データを再生する際には、サンプリング周波数や量子化ビット数、チャンネル数（モノラルかステレオか）などの情報が必要ですし、楽曲が入った音声データには、楽曲情報が含まれていると嬉しいかも知れません。このようなメタデータをどのように格納するかで、非圧縮の中でも何種類かのファイルフォーマットが存在します。

### PCM

音声認識の基本で説明したデジタル-アナログ変換は、パルス符号変調（Pulse Code Modulation）と呼び、波形の振幅を量子化した値の系列データとして表現されます。音声データに限らず、一次元の系列データの保存形式として用いられますが、音声データの場合はサンプリング周波数などのメタデータを外部で保持しておく必要があります。

ステレオ音声の場合は、左、右、左、右、・・・ のように交互に値を並べることが一般的ですが、読み取るツールに依存すると思われます。

### WAV（線形PCM, 浮動小数点）

RIFF（Resource Interchange File Format [^RIFF] というファイル形式の一種で、「チャンク」という単位で情報を格納することができます。チャンクは自由に設定が可能ですが、フォーマットチャンクとデータチャンクが必須になっており、フォーマットチャンクにサンプリング周波数などのメタデータが格納され、データチャンクに実際の音声データ本体が格納されます[^chunk]。

データチャンクに格納されるデータは、PCM（正確には線形PCM）が広く使用されてますが、実は他のコーデックも使用可能です[^wav_format]。その中には後述する μ-law や a-law 等の圧縮形式のコーデックも存在するため、WAVファイルフォーマットならば非圧縮であるとは限りません。

WAV は、元々はMicrosoft と IBM が開発したものらしく、1991 年に Multimedia Programming Interface and Data Specifications 1.0 という資料が発表されたのが最初だと思われます[^wikipedia]。

[こちらのページ](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html)（カナダのマギル大学の研究室のようです）がWAVについてとてもよくまとまっており、かつ元の設計書のアーカイブも置いてあるので、WAV に詳しくなりたい方はこちらを参照するのが良いと思います[^macgill]。

- LPCM

そのまま線形PCMをWAVのデータチャンクに格納したもの。

- IEEE float

振幅値を整数値で量子化するのではなく、浮動小数点で表現したもの。振幅のクリッピングなどが起きないという話を聞いたことがあるが詳細は未確認。

### [AIFF](https://en.wikipedia.org/wiki/Audio_Interchange_File_Format)

アップル。WAVと同様にいろんなコーデックが使えます。

### [AU](https://en.wikipedia.org/wiki/Au_file_format)

サン・マイクロシステムズ。WAVと同様にいろんなコーデックが使えます。

## 可逆圧縮

可逆圧縮の例としてはハフマン符号がよく用いられますが、テキストファイルをzipに圧縮する場合のように、何らかの規則性などを利用してより少ないデータ量で元のデータを表現しようとするものです。テキストファイルはzip化することで容量を大きく削減することができますが、音声データをzipで圧縮してもあまり効果はありません。音声データに適した圧縮方法を使用する必要があり、様々な技術が駆使されているようです。

### [FLAC](https://xiph.org/flac/)

Free Lossless Audio Codec。 オープンソースソフトウェアです。
非圧縮音声データから、Flac 形式に変換する際に level を選択可能で、レベルによって圧縮率と変換にかかる時間が変わります[^flac_alac]。Flac 形式から非圧縮に復元する際にはあまり時間がかからないことが特徴だと言われています。時間があれば、圧縮アルゴリズムについても触れたかったです。

### [ALAC](https://macosforge.github.io/alac/)

Apple Lossless Audio Codec。アップル社が開発したコーデックで今はオープンソースです。

## 非可逆圧縮

人間には聞き取れない周波数帯の情報を削減したり、他の音と重なって聞き取られない音の情報を削減したりして、用途に支障が出ない範囲で情報量を抑えた形での圧縮方式のことです。
ストリーミングなどのデータ容量が問題となる場合などにこちらの形式で圧縮した音声データが用いられます。

### MP3

言わずと知れた音声コーデック。
アルゴリズムについては、[こちらのスライド資料](https://www.slideshare.net/akinoriito549/slides-43584939)がとても参考になります。（すごいことをやっているんだなぁ。。。）

### WAV (μ-law, a-law)

- μ-law
 
[G.711](https://en.wikipedia.org/wiki/G.711)という音声符号化の規格で定められているコーデックの一つです。
非線形PCM で、14 bit 線形PCM を対数的に8ビットに符号化したものです。8 bitで単純に線形PCMにするよりも量子化の際の情報ロスを抑えられるように設計されています。人間の耳が、音量がが大きい場合と比較して音量が小さい場合の違いに敏感であることを利用しています。

- a-law

μ-law とほぼ同様ですが、符号化方式が異なります。


## おわりに

途中で力尽きた感がありますが、音声データについて全体をざっくり把握できる資料になっていればうれしいです。

[COTOHA API](https://api.ce-cotoha.com) では、（有料枠になりますが）自然言語処理だけでなく音声認識や音声合成機能も提供しています。ご興味があればぜひお試しください。
API以外にも、コールセンター向け音声認識や会議支援、チャット応対等のサービスを提供しております。（[こちら](https://www.ntt.com/business/services/application.html#ai)）


明日は @TAR_O_RIN さんの[TektonでCI/CDパイプラインを手の内化しよう](https://qiita.com/TAR_O_RIN/items/81a6abf947aea0a8deee)です！お楽しみに！


[^yaruo]: やる夫で学ぶシリーズは個人的には参考になって好きです。http://www.ic.is.tohoku.ac.jp/~swk/lecture/yaruodsp/sampling.html

[^2gb]: OSのファイルシステムによっては、一つのファイルで扱えるサイズ上限が2GBだったりするので、同じ条件の非圧縮音声は3時間ちょっとしか入らないことになります。

[^wav_format]: こちらのページにて、フォーマットについて細かく書いてありますが真義は不明です。http://www.web-sky.org/program/other/wave.php

[^RIFF]: https://ja.wikipedia.org/wiki/Resource_Interchange_File_Format

[^chunk]: チャンクを任意で追加できるうえに、チャンクの順番も自由なので、再生ソフトによってはWAVがうまく読み取れないといった問題が起こるようです。また、メタデータ内にデータサイズを定義する項目があり、これが符号なしint32 であるため、2GB程度しか扱えないという問題があります。（int64に拡張したW64というフォーマットがあります）

[^wikipedia]: https://en.wikipedia.org/wiki/WAV 参考文献のリンクが切れており、現在一次情報が消失しているのではないかと思われます。本質情報をお待ちしています。

[^flac]: https://xiph.org/flac/

[^alac]: https://macosforge.github.io/alac/

[^flac_alac]: こちらでいろいろ比較を行っていて興味深いです。https://av.watch.impress.co.jp/docs/series/dal/650133.html （最終アクセス:2019/12/03 15:46）

[^macgill]: マギル大学がなくなってしまったら、WAVの正確な仕様を知るすべがなくなってしまうんじゃないでしょうか。

[^aiff]: https://en.wikipedia.org/wiki/Audio_Interchange_File_Format

[^au]: https://en.wikipedia.org/wiki/Au_file_format