目次: ALSA
ALSAで音が鳴ることはわかりました。でもそれだけではつまらないですね。
次はどうすれば音を鳴らすプログラムを書けるのか?を見てみます。今回は、下記ALSAのモジュール図でいう「アプリケーション」側から見てみます。
ALSAとアプリケーションとのインタフェースをALSA APIと呼ぶことにします。ALSA APIの仕様は公式のドキュメントに詳しく書かれています(※)。
(※)今回はLPCMを扱いますのでALSA APIのなかでも PCMモジュールの仕様が参考になります。
LPCMを鳴らすために最低限必要なAPI呼び出しは下記の5つです。
もう少しコードっぽく書くと下記のようになります。
//Format: 48[kHz], Signed 16[bit], Stereo
int rate = 48000;
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
int channels = 2;
//To use snd_pcm_writei() instead of snd_pcm_writen()
snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED;
//Allow to select the 'plughw' for using sampling rate converter.
int resample = 1;
//Buffer size is 50[ms]
int latency = 50000;
snd_pcm_t *pcm = NULL;
snd_pcm_open(&pcm, "hw:0", SND_PCM_STREAM_PLAYBACK, 0);
snd_pcm_set_params(pcm, format, access, channels, rate, resample, latency);
while (1フレームでも残っていれば) {
writen = snd_pcm_writei(pcm, buf, frames);
if (writen < 0) {
snd_pcm_recover(pcm, writen, 0);
}
}
snd_pcm_close(pcm);
もし48kHz, Signed 16bits, Stereo以外のLPCMデータを再生する場合は、rate, format, channelsの部分をデータに合わせて変更します。
もしハードウェア側が48kHz, Signed 16bits, StereoのLPCM再生をサポートしていない場合は、下記のようなエラーメッセージが出ます。
ALSA lib pcm.c:7431:(snd_pcm_set_params) Rate doesn't match (requested 48000Hz, get 0Hz)
このメッセージが出ていたら、デバイス名を "hw:0" → "plughw:0" としてください。これによりサンプリングレートコンバータ(SRC)が働き、ハードウェアが受け付けられるフォーマットに自動的に変換されます。
例えば44.1kHzしか対応していないサウンドカードで24kHz, Signed 8bits, Monoの音源を鳴らしたときは、下記のような動作イメージになります。
rate = 24000;
format = SND_PCM_FORMAT_U8;
channels = 1;
(デバイス名) = "plughw:0"
24kHz, 8bits, Mono --(plug)--> 44.1kHz, 16bits, Stereo --> hw:0
先ほどの中心部分に、ファイルからのLPCMデータの読み込み部分、エラー処理などを付け加えて、簡易的なプレーヤにしました。
ソースコードはこちらから(※)どうぞ。
ライセンスは、修正BSDライセンスです。
(※)コンパイルの際は -lasoundを付けてください。もしalsa/asoundlib.hが無い場合は、ALSAの開発用パッケージ(Debian Wheezyならlibasound2-dev)をインストールしてください。
注意: 再生できるデータはLPCMデータのみです。WAVファイル(*.wav)もLPCMデータを含むため再生可能ですが、コンテナのヘッダもLPCMデータだと思って再生してしまい、最初にビッ!ビッ!というノイズが鳴ります。WAVファイル再生の際は音量にご注意ください。
警告: 入力されたデータのフォーマットチェックは行っておりません。LPCMデータではないファイルを再生させると、非常に大きい音や、ノイズが鳴り、スピーカーなどを破損する可能性があります。
どことは言いませんが、某半導体メーカーと、AV機器メーカーの関係と、
製パン(たとえば山崎パン)と、小売りPB(たとえばローソンのパン)の関係は、
片方が半製品のメーカーであり、もう片方が製品企画時点から注文を付ける顧客企業、という点で似ています。
しかし販路を顧客に全て依存する某半導体に対し、山崎パンは自社ブランドの販路があります。つまり山崎パンは顧客がトチ狂ったことを言ってきたら、その販路ごとぶった切る、という選択も可能なのです。
実際には丸く収めて、ぶった切るなんて思い切ったことはしないと思いますが、その選択もできるのだ、という事実が、価格交渉力として顕著に現れます…と思います。
メモ: 技術系?の話はFacebookから転記しておくことにした。
「何日でもいいから同じ誕生日のペアを連れてこい」と言われたら、何人に声をかけたら良いでしょうか?
慎重を期して99.9% の確率で同じ誕生日のペアが居るように、人を集めることにしましょう。
シンプルに考えると1年は365日だから365人x 99.9% = 364人…?と思いますが、実は70人で良いのです。
グラフにするとこんな感じになります。
一見、直感に反するようですが「ペアになるのは誰でも良い」という点がポイントです。
解説しようと思ったら、Wikipedia誕生日のパラドックスに既に説明があったので、こっちにお任せします…。
< | 2014 | > | ||||
<< | < | 02 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | - | 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | - |
合計:
本日: