HOME会社概況業務内容開発分野開発事例CANモジュールソフテックだよりお問い合わせ
HOME > ソフテックだより > 第77号(2008年11月5日発行) 技術レポート「組み込みソフトウェアでの音声鳴動制御」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより(技術分野別)のページへ
ソフテックだより(シーン別)のページへ


ソフテックだより 第77号(2008年11月5日発行)

技術レポート

「組み込みソフトウェアでの音声鳴動制御」

1. はじめに

当社で開発するシステムでは、音声を鳴動させる機会があります。
現在私が携わっているシステムでも音声を鳴動させますが、この音声鳴動を組み込みソフトウェアで実現しています。実現方法は、CPUとオーディオ用D/Aコンバータの組み合わせで音声鳴動しており、今回はその方法を紹介します。
なお、音声を鳴動させる際、専用のICを使用するという選択肢もありますが、今回はそれを使用せずに音声鳴動させる方法・注意点などを紹介します。

2. 音とは?

まず音声鳴動の仕組みですが、音とは空気やその他の媒体を通じて移動する波です。
この波の振幅の大きさ(高低差)や、周波数の違いから様々な音が作り出されます。
周波数については、一般的に人の耳は20Hz〜20kHzの周波数の音を聴くことが可能であり、年齢と共に低下すると言われています。また、2kHz〜4kHzの音にもっとも敏感という特性があります。この特性を参考に、システムで使用する音声の周波数(サンプリング周波数)を決定します。
ちなみに、身の回りにあるシステムでは、主に以下の周波数を使用しています。

用途 サンプリング周波数
電話 8kHz
音楽CD 44.1kHz
DVD-Video 48kHz

表1. 主な用途とサンプリング周波数

用途に応じて使用されるサンプリング周波数が異なりますが、このサンプリング周波数を高くすると音質を上げることが出来ます。(と言っても、人の耳に聞こえる以上の周波数にしてもあまり意味はありません)ただし、サンプリング周波数を上げると、その分ソフトウェアの処理負荷が上がってしまいますので、どの程度の周波数にするかは入念に検討し、決定する必要があります。

今回紹介するシステムでは、サンプリング周波数を8kHzで鳴動させています。
これは、人の耳が敏感な4kHzの周波数までをサポートするためです。(4kHzまでの音をサポートするために、8kHzという倍の周波数を使用していますが、これは標本化定理に従っているためです。標本化定理の説明は省略しますが、音を正しく鳴動させるための決まりと考えてください。)

それでは、組み込みソフトウェアで音声鳴動用の専用ICを用いずに、音声を鳴動させる方法や注意点などを紹介していきます。

3. 組み込みソフトウェアでの音声鳴動制御
(1). 音声鳴動の仕組み

まずハードウェアの基本構成は図1のようになります。

音声鳴動ハードウェア基本構成
図1. 音声鳴動ハードウェア基本構成

図1のとおり、CPUから出力するのは音声の波ではなく、デジタルデータです。そのデジタルデータをオーディオ用D/Aコンバータ(※1)がアナログ値に変換し、音声の波を作り出します。D/Aコンバータの先には、電気信号を変換するトランスデューサー(ここではスピーカ)が接続されており、このスピーカに音声の波を入力することで鳴動する、という仕組みです。
この波の元になるデジタルデータを転送することが、ソフトウェアの役割となります。
ソフトウェアから出力したデジタルデータは、D/Aコンバータにより、図2のようなアナログデータに変換されて、音声データになります。

デジタル⇒アナログ変換イメージ
図2. デジタル⇒アナログ変換イメージ

(2). 音声鳴動時の注意点

今回紹介する手法では、CPUからD/Aコンバータへの音声データの転送にシリアル通信を使用しますが、転送周期は厳密に守らなければなりません。規定したサンプリング周波数に対して転送周期が遅いと、間延びしたような音声に聞こえ、逆に転送周期が早いと詰められた(早送りのような)音声に聞こえてしまいます。また、転送周期が遅い場合や早い場合が混ざってしまうと、ノイズの乗ったような音声になってしまいます。

今回の場合には、サンプリング周波数を8kHzと決めていますので、1秒間に8000回、つまり125μ秒毎に1回分の音声データを転送する必要があります。また、この1回分の音声データを、ビット数16、チャンネル数2(L(左)チャンネルとR(右)チャンネル)としていますので、1秒間に16000ワード(32000バイト)のデータを、均等な間隔で転送する必要があります。

1回分のデータ転送は図3のようになります。

シリアル通信イメージ(1回分)
図3. シリアル通信イメージ(1回分)

今回はこの転送周期を守るために、125μ秒毎にタイマ割り込みを発生させ、その割り込み処理の中で、音声データの転送を開始するようにしました。しかし、その方法だけでは「ある程度」時間を守ることは出来ますが、厳密に転送周期を守るためには、さらに次のようなことに注意する必要がありました。

  1. 割り込み処理実行のタイミングを確実に125μ秒周期とする
  2. 割り込み処理が実行されてから音声データの転送開始までの時間を均等にする
  3. 音声データの転送時間を均等にする

1〜3は図4のようになります。

割り込み処理とデータ出力のタイミング
図4. 割り込み処理とデータ出力のタイミング

<1.割り込み処理実行のタイミングを確実に125μ秒周期とする>

複数の割り込み機能を使用する場合、125μ秒周期のタイミングで音声用の処理を実行しようとしても、既に別の割り込み処理が実行されている場合があります。既に実行されている割り込み処理が終わるのを待っていたのでは、とても125μ秒周期を守る事は出来ません。この場合、多重割り込みの使用と割り込み優先度の調整により解決できます。
(図5のようなイメージになります。)

他の割り込みと重なった場合
図5. 他の割り込みと重なった場合

<2.割り込み処理が実行されてから音声データの転送開始までの時間を均等にする>

1の対策で125μ秒毎に確実に割り込み処理を開始できるようになりました。
しかし、その処理の中で転送開始までの時間にばらつきがあっては、意味がありません。
転送開始までの時間を均等にするためには、あらかじめ転送用の音声データを用意しておき、割り込み処理実行直後に音声データの転送を開始し、その後で、次に転送する音声データを生成するなどの方法で解決できます。また、転送開始までの処理時間が均等になるように、ソフトウェアを調整するという対策もあります。

<3.音声データの転送時間を均等にする>

これまでの対策で、125μ秒周期で音声データの転送を開始できましたが、実際の転送周期が乱れては元も子もありません。
転送周期に関しては、CPUに用意されているシリアル通信用機能を使用することで、容易に周期を守る事が出来ますので、意識することはあまりないかもしれません。

このように、割り込みで1回分毎にデータを転送する場合にはいろいろと注意することがありますが、DMA(Direct Memory Access)という機能を使用して、1回分毎ではなく、ある程度まとまった単位でデータ転送する方法もあります。
DMAを使用してデータ転送する場合、ソフトウェアの介在を必要最小限に抑えられるため、比較的容易に転送周期を守ることが出来ます。
これらの転送方法には、それぞれメリットとデメリットが存在します。

<割り込みで1回分毎にデータ転送する場合>

メリット

  • 転送用メモリ領域を少量で済ませられる
  • 1回分毎にデータを転送するため、柔軟な音声変更が可能(※2)
  • ソフトウェア処理負荷を均一化できる
デメリット
  • 割り込み処理のオーバーヘッドが大きい
  • 転送周期が乱れやすいため、(DMA使用時に比べ)割り込み処理などの入念なソフトウェア設計が必要
<DMAを用いてデータ転送する場合>

メリット

  • ある程度まとまった周期でのみソフトウェアが介在すれば良いため、ソフトウェア負荷を軽減できる
  • ソフトウェアの介在は必要最低限ですむため、転送周期が乱れにくい
デメリット
  • 転送用メモリ領域を(1回分毎に転送する方法に比べ)多く必要とする
  • 複数の音声を連続で鳴動させる場合、ソフトウェア設計に工夫が必要(※2)

※2 これはソフトウェアの設計によるところですが、1回分毎にデータ転送をする場合には、途中で別の音声を鳴動させたい時に、比較的容易に変更可能ですが、DMAではまとまった単位で転送するため、工夫が必要になる場合があります。

音声データの転送方法は、システムの要求やハードウェアの制約により決定します。

ちなみに現在開発中のシステムではDMAを使用して音声データを転送していますが、やはり転送周期の乱れを(1回分毎に転送する場合に比べ)意識しなくて良い点が便利です。転送用の音声データを生成する際に、一時的に処理負荷が上がってしまうという点は調整が必要でしたが、それを考慮してもDMAを使用したほうが便利と感じています。

(3). 音声データの圧縮・伸張

組み込みソフトウェアで音声を鳴動する場合、もうひとつ工夫する点として、メモリ使用量の節約があります。
近年メモリ容量が大容量化してきたとはいえ、無限に存在するわけではありません。さらに、メモリ容量を小さくできれば、ハードコストを抑えることが可能なため、できるだけメモリ使用量を節約することが望まれます。
しかしもともと音声データは大量のメモリ容量を必要とします。データビット数16ビット、サンプリング周波数8kHzとした場合、1秒間あたり16000バイトのメモリ容量が必要になります。

このメモリ容量の問題は、音声データを圧縮することで、ある程度解決できます。
現在のシステムでは、音声信号をパルス符号変調(PCM:pulse code modulation)方式を用いてデジタルデータに変換します。しかしこの方式では、前述の通り1秒間のデータだけで16000バイトものデータ量になってしまうため、非効率です。そこで、音質を出来るだけ維持しながらデータ圧縮を可能にする、適応的差分パルス符号変調(ADPCM:Adaptive Differential Pulse Code Modulation)方式と呼ばれる圧縮方式を使用します。
この方式で、1データあたりに必要なビット数を、4ビットまで減らすことが出来ます。(1秒間あたり16000バイトあったデータは、4000バイトまで減ります。)

この圧縮方式は、自然界の音は連続的に変化するという性質に注目し、過去のデータから予測値を算出し、それとの差分をデータとして保持するため、音質の低下を最小限にとどめながらデータ量を大幅に減らすことができます。この圧縮方式を使えば、音声データのメモリ使用量は当初の25%にまで節約することができますので、非常に魅力的です。

ただし、ここで注意しなければならないのは、圧縮されたデータを転送する前に、伸張する必要があるという点です。伸張するための復調アルゴリズムは多少複雑になっているため、そこそこのCPUパワーを必要とします。
もともと音声データ転送では高速な処理を行う必要がありますが、この復調処理で音声データ転送が間に合わなくなってしまっては、元も子もありません。この点もソフトウェア設計時に注意すべき内容です。

4. おわりに

今回は、組み込みソフトウェアで、専用ICを使用せずに音声を鳴動させる基本的な方法と注意点、ほんの一部のアルゴリズムの紹介をさせていただきました。
今回紹介したこと以外にも、音声鳴動には様々な手法、アルゴリズムが存在します。
また、音声鳴動用の専用ICを用いることで、ソフトウェア負荷を軽減させることも可能ですので、検討の価値は十分にあると思います。
音声鳴動の仕組みに興味のある方、組み込みソフトウェアで音声鳴動をご検討中の方の、参考になれば幸いです。

(T.O.)

[参考文献]

「組込みメディアプロセッシング」

編著者:
David J.Katz
編著者:
Rick Gentile
出版年:
2007/11/19
出版社:
株式会社 翔泳社
[注釈]
※1
オーディオ用D/Aコンバータは、NEC製のμPD6379を使用
※2
これはソフトウェアの設計によるところですが、1回分毎にデータ転送をする場合には、途中で別の音声を鳴動させたい時に、比較的容易に変更可能ですが、DMAではまとまった単位で転送するため、工夫が必要になる場合があります。

関連ページへのリンク

関連するソフテックだより