asterisk-logo

WiFi環境であれば、VoIP が使う帯域についてはさほど気にする必要はないのですが、3G回線経由時には VoIPパケットの優先制御が行われませんので、なるべくビットレートを下げて通信品質が音声の品質に影響が出ないようにしたいところです。

今回は Asteriskのコーデック(音声の符号化方式)について書いてみます。

VoIP機器でよく使われる G.711(μLow)はビットレートが64Kbps です。これに対して、GSM が13Kbps、G.729a ではなんと 8Kbps という低ビットレートです。ただし、この数字は実際にネットワークに流れる時のビットレートとは異なります。

ちょっと計算してみましょう。
Ethernet のパケットは、L2ヘッダ+IPヘッダ+TCP or UDPヘッダ+データ部という構造になっています。通常音声データは RTP というプロトコルで実装されることが多く、UDPパケットが使われます。以上を加味すると、全体としてのヘッダー部は以下のようになります。

L2ヘッダ14byte+IPヘッダ20byte+UDPヘッダ12byte+RTPヘッダ8byte=54byte=432bit

音声パケットの送出間隔を40m杪とすると1秒間には25個(1000÷40)となるので、ヘッダー部分の必要帯域は 432bit×25=10,800bps=10.5Kbps となります。これに音声分の 8Kbps を足すと、合計として 18.5Kbps になりますので、概算としては 20Kbps 程度見ておいた方が良いと思います。
※128Kbps 程度の帯域で G729a を使うと、計算上は6同時接続とかいけそうですが、実際には SIPのパケット等も頻繁に飛んでますので、5同時接続が限界です。
※インターネットへの接続で PPPoE を使っていると PPPoE+PPPヘッダ(8byte)とかも付加されます。
※ちなみに、SIPフォンでよく使われる G711μ の場合、音声パケットの送出間隔を20m杪とすると、432bit×50=21,600bps=21kbpsに、音声分の64Kbps を足すと、85Kbps≒100Kbps程度になります。

GSMは 無料で使えますが、G.729a は特許のからみで有料です。
実際に使ってみると、GSM を使うことで3G回線経由でソフトフォンを使っても音質劣化は許容範囲だと思います(G.711μ だとちょっと辛い)。

しかし、G.729a を使ってみると GSM との違いはよく分かります。電話がつながった最初の 1~2秒が不安定になる事(毎回ではなく、たまに)を除けば、音質は問題ないと言えます。非常に安定しており、音が途切れたり、妙なエコーが発生することもありません。


それでは、Asterisk に G.729a を導入する方法です。

まずは、Astersik の開発元でもある digium社の Webサイトへ行き、オンラインストアから G.729a の Codec(10$)を購入します。クレジットカードか Paypal で購入が可能です。
購入自体はすぐに終わり確認のメールもすぐにやってくるのですが、ライセンスキーの発行は人力らしく、時差も手伝って次の日に送られて来ると思った方が良いです。
※オンラインストアのアカウント登録は電子メールの認証があるので、単に登録しただけではサインイン出来ません。登録後すぐにメールが送られてくるので、そこに書かれている URL をクリックすることで認証が終わり、やっとサインイン出来るようになります。

さて、手元にライセンスキーが揃ったらインストール開始です。
まずは、このページを開き Installation Guides にある README をしっかり読んでください。
ステップbyステップで非常に丁寧に書かれており、その通りに操作することでさほど迷わずにインストールが完了します。

まずは、register というプログラムでユーザ登録を行い、同時に HDD上になにやらライセンス認証用のファイルができあがります。

次はバイナリーの Codec を選択する作業です。
バイナリーなので CPU 種類毎用意されていますが、その中でどれを使ったらよいか簡単なベンチマークを走らせて一番成績のよいバイナリーを選んでくれます。
※私の場合はなぜか C3_2 でしたww

あとはダウンロードサイトへ行って、このバイナリーをダウンロードしてきます。
※実際にはブラウザー上で見えるバイナリーCodec の URL をコピーして、Linux上で wget するのが楽です。

最後にダウンロードしてきたバイナリーCodec を /usr/lib/asterisk/modules へコピーし、

# asterisk -rx "module load codec_g729a.so"

で、初期化して組み込んでください。
※このコマンドは一度だけ実行すれば良いです。

ちゃんと新しい Codec が動いているかは、

# asterisk -rvv
*CLI> g729 show licenses

とコマンドを打つと、

0/0 encoders/decoders of 1 licensed channels are currently in use

Licenses Found:
File: G729-2NJDXXXXXXXX.lic -- Key: G729-2NJDXXXXXXXX
 -- Host-ID: e5:3b:4b:84:cf:45:6a:fb:9a:58:2a:6a:ec:a5:e8:5f:ae:b0:df:60
 -- Channels: 1 (Expires: 2030-07-26) (OK)

こんな感じで最後に(OK)と表示されていれば、正常に動いています。

あとは sip.conf の中で、iPhone の内線に割り当てられている部分に、

disallow=all
allow=g729
allow=g722
allow=gsm
allow=ulaw

という設定を書きます。
い ろいろ試してみましたが、Asterisk側では使うと思われる Codec を全て書いておき、アクセスするIP電話側で使うプロトコルを一つに絞った方が良いような気がします。両方で複数書いた場合、どうも実装によって並び順が優先順位だったり、そうでなかったりするので、トラブルが出たときに切り分けが ややこしくなります。

個人的には VoIP over 3G では G.729a を使い、LAN接続のように帯域に余裕があるときは G.711(μLow)、もしくは G.722 がお勧めです。音質の違いがはっきり体感できます。

 追記 2016/08/10

ライセンスについては変更があったようです。Asterisk1.8 の時代には G.729a のライセンスが一つあれば、SIP でも IAX2 どちらでも使えましたが、現在の Asterisk13 では、チャンネル毎にライセンスが必要のようです。つまり SIP と IAX2 の両方で G.729a を使いたい場合には、最低2個のライセンスが必要です。