desired パラメータにしたがって、 オーディオデバイスを開きます。 成功すると0を返し、obtained に 実際にハードウエアに設定されたパラメータが格納されます。 obtained がNULLの場合、 コールバック関数に渡されるオーディオデータは 呼び出し時に指定されたフォーマットであることが保証されます。このとき、 必要であればハードウエアのオーディオフォーマットに変換が行われます。 オーディオデバイスを開くことに失敗した場合、または オーディオスレッドの起動に失敗した場合は-1が返されます。
オーディオデバイスを開くためには、 SDL_AudioSpec構造体 desired を作らなければいけません。
SDL_AudioSpec *desired; . . desired = malloc(sizeof(SDL_AudioSpec));続いて、望みのオーディオの設定を構造体に格納します。
周波数 (1秒間のサンプル数)
フォーマット (SDL_AudioSpec参照)
オーディオバッファのサイズ(サンプル単位)。この値は2の羃乗にすることが 薦められています。また、この値はドライバによってハードウエアに最適な値に 調整されることがあります。 アプリケーションやCPUの速度によって512から8192あたりまでの値を使うと よい結果が得られるようです。 この値を小さくするとレスポンスが向上しますが、 バッファアンダーフローをひきおこしやすくなります。 つまり、他のアプリケーションが重い処理をしたときに、時間内にバッファを 満たすことができなくなってしまう可能性が高くなります。 ステレオのデータは、左右のチャンネルが、左、右という順番で 1サンプルを構成します。 サンプル数は次の式で時間に変換することができます: ms = (samples*1000)/freq
オーディオデバイスがデータを準備できたときに呼ばれる関数を指定します。 この関数には、オーディオバッファへのポインタ、オーディオバッファのサイズ(バイト単位)が渡されます。 この関数は通常、別のスレッドで走りますので、 SDL_LockAudioとSDL_UnlockAudioを 使ってこの関数がアクセスするデータを保護するべきです。 callbackのプロトタイプは以下の通りです:
void callback(void *userdata, Uint8 *stream, int len);userdataは、SDL_AudioSpec構造体の中のuserdataフィールドへのポインタです。 streamは、データを格納することができる オーディオバッファへのポインタで、lenはそのバッファの 長さです(バイト単位)。
関数callbackの第一引数として渡されるポインタです。
SDL_OpenAudioは、これらのフィールドを、 引数で与えられたSDL_AudioSpec構造体desiredから読み込み、 desired に合ったオーディオの設定を探そうとします。 既に述べた通り、パラメータobtainedがNULLのとき、 SDLはパラメータdesiredの設定を、 ハードウエアの設定に合うように変換します。
もしパラメータobtainedがNULLのときは、SDL_AudioSpec構造体desiredは 実際に有効な設定となります、 そうでない場合は、SDL_AudioSpec構造体obtainedが実際に有効な設定となりdesirecは 不要となります。 実際に有効になった設定は、読み込んだデータをハードウエアの フォーマットに変換するためのSDL_AudioCVT構造体を作成 するときに使用することができます。
SDL_OpenAudioは desiredとobtained内の、 sizeとsilenceの 2つのフィールドを自動的に設定します。 sizeフィールドはオーディオバッファのサイズが バイト単位で格納されます。 一方、 silenceフィールドは、オーディオバッファ内で 「無音」をあらわす値が格納されます。
オーディオデバイスは、デバイスが開かれたときにまずsilenceデータを演奏しつづけます。 その後、callback 関数を呼ぶ準備が出来た 段階で、SDL_PauseAudio(0)を呼びだすことで動作を開始します。 オーディオドライバは、要求されたオーディオバッファの sizeの値を変更する可能性があるため、 オーディオデバイスを開いた後に、ローカルのミキシング用バッファを確保した 方がよいでしょう。
/* コールバック関数のプロトタイプ宣言 */
void my_audio_callback(void *userdata, Uint8 *stream, int len);
/* オーデョデバイスを開く */
SDL_AudioSpec *desired, *obtained;
SDL_AudioSpec *hardware_spec;
/* SDL_AudioSpec構造体desiredを確保する */
desired=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
/* SDL_AudioSpec構造体obtained用のメモリを確保する */
obtained=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
/* 22050Hz - FMラジオの相当の品質 */
desired->freq=22050;
/* 16ビット符号あり */
desired->format=AUDIO_S16LSB;
/* モノラル */
desired->channels=0;
/* 大きなオーディオバッファはデータの抜けのリスクが減りますが
レスポンスの時間が増大します */
desired->samples=8192;
/* コールバック関数の指定 */
desired->callback=my_audio_callback;
desired->userdata=NULL;
/* オーディオデバイスを開く */
if ( SDL_OpenAudio(desired, obtained) < 0 ){
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
exit(-1);
}
/* desired はもう必要でないため解放 */
free(desired);
hardware_spec=obtained;
.
.
/* コールバックの準備 */
.
.
.
/* 演奏開始 */
SDL_PauseAudio(0);