C言語による Linux サウンドプログラミング


OSSプログラミング

Linux において、サウンドカードを制御するドライバソフトウェアとして、最 も一般的なのは、Kernel に付属する OSS/Free (Open Sound System Free) で ある。このサウンドドライバソフトを C言語を用いて制御するプログラムを作 ることによって、ごく簡単な音情報処理プログラミングについて学ぶ。


参考文献

「Linuxマルチメディアガイド」、 Jeff Tranter 著 山形 浩生 訳、オライリージャパン出版

唯一の日本語で書かれたサウンドプログラミングに関する情報が載っている書 籍。これを参考にして、プログラミングを行なう。

英語でよければ、以下のリンクが有益

Programmer's Guide to OSS


必要な基礎知識

C言語でプログラムが組めることが必須。while, for などの基本的な制御文は もちろんのこと、置換マクロ、関数、配列、ポインタについて理解している必 要がある。さらに、

コンピュータで音を扱うための基礎的な知識

をよく読んで、サンプリング周波数、量子化ビット数、チャンネル数について 理解しておくこと。


サンプルプログラム

parrot.c p.212 例14-2

dsp_info.c p.234 例14-6

この2つをコンパイルし、実行してみよ。その機能と使い方は、教科書を参考 にせよ。

その他のサンプルプログラム


課題

まずは、dsp_info を実行して、自分の使用するサウンドカードが設定可能な、 サンプリング周波数、チャンネル数、量子化ビット数の範囲を調べること。

parrot.c を以下のように変更せよ。それぞれのプログラム名は、parrot_番号 とすること。

  1. 無限に録音と再生を繰り返す仕様をやめて、1回だけ録音と再生を行なうようにせよ
  2. 再生と同時にファイルにバイナリ形式にて「parrot_1.raw」というファイル名にて保存するようにせよ。
  3. バイナリ形式で保存したデータを
    sox -r 22050 -ub parrot_1.2raw parrot_12wav 
    
    として、wavファイルに変換し、WindowsNT上からCoolEditを使って読み込んでみよ
  4. 再生と同時にファイルにアスキー形式にて「parrot_4.txt」というファイル名にて保存するようにせよ。
  5. アスキー形式で保存されたデータを gnuplot を使って画面にプロットせよ
  6. 録音時のサンプリング周波数を 22050Hz にせよ
  7. 録音時間を5秒に変更にせよ
  8. 録音時間をコマンドラインから秒の単位で指定し、buf をmallocを使って動的に確保せよ
  9. 録音時にステレオ録音するように変更せよ
  10. 可能なら録音時に16bit量子化を行なうように変更せよ
  11. 再生時のサンプリング周波数を録音時の1/2にすると、どのような音が再生されるか?
  12. 録音時のサンプリング周波数を22050Hzとし、再生時のサンプリング周波数を32000Hzとすると、どのような音が再生されるか?
  13. ステレオ録音したデータを左右チャンネルを足し合わせて、1チャンネルにし、モノラルで再生するように変更せよ。また、振幅がオーバーフローしない仕組みを何か考えよ。
  14. 録音したデータを一つ置きに間引きして再生すると、どのような音が再生されるか?
  15. データの間引きを行なう次のような仕様の関数を作成し、上記プログラムを書き換えよ。
    void thin_out(unsigned char inbuf[], unsigned char outbuf[], int n, int rate)
    /*
    	inbuf[] : 入力信号	(8bit)
    	outbuf[] : 出力信号	(8bit)
    	n       : 入力信号の長さ
    	rate    : 間引き数 (2だと2つに1つを間引く)
    */
    
  16. 録音したデータにつき、同じデータを1つづつ内挿して、倍の長さにすると、どのような音が再生されるか?
  17. データの内挿を行なう次のような仕様の関数を作成し、上記プログラムを書き換えよ。
    void interp(unsigned char inbuf[], unsigned char outbuf[], int n, int rate)
    /*
    	inbuf[] : 入力信号	(8bit)
    	outbuf[] : 出力信号	(8bit)
    	n       : 入力信号の長さ
    	rate    : 内挿数 (2だと1データにつき1つ同じデータを内挿、3だと2つ同じデータを内挿)
    */
    
  18. 内挿するデータが、前後の振幅値を直線補間した値となるように上記プログラムを書き換えよ。再生される音の音質は、上記プログラムとどのように異なるか?
  19. 録音をやめて、1000Hzの純音を5秒間合成し、それを再生するようにプログラムを変更せよ。
  20. 純音の周波数と振幅値をコマンドラインより与えるようにせよ
  21. 純音を合成する関数を以下の仕様で作成し、その関数を使うようプログラムを書き換えよ
    void sine_tone(unsigned char outbuf[], float f, int amp, int n)
    /*
    	outbuf[]	: 純音出力信号	(8bit)
    	f		: 周波数 [Hz]
    	amp		: 振幅
    	n		: 出力信号の長さ
    */
    
  22. 関数 sine_tone を利用して、基本音から第10倍音までを等振幅で含む調 波複合音を合成して再生せよ。振幅がオーバーフローしない仕組みを何か考え よ

akira@rsch.tuis.ac.jp