SDL_OpenAudio

Name

SDL_OpenAudio -- 指定された条件でオーディオデバイスを開きます。

Synopsis

#include "SDL.h"

int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained);

Description

desired パラメータにしたがって、 オーディオデバイスを開きます。 成功すると0を返し、obtained に 実際にハードウエアに設定されたパラメータが格納されます。 obtained がNULLの場合、 コールバック関数に渡されるオーディオデータは 呼び出し時に指定されたフォーマットであることが保証されます。このとき、 必要であればハードウエアのオーディオフォーマットに変換が行われます。 オーディオデバイスを開くことに失敗した場合、または オーディオスレッドの起動に失敗した場合は-1が返されます。

オーディオデバイスを開くためには、 SDL_AudioSpec構造体 desired を作らなければいけません。

SDL_AudioSpec *desired;
.
.
desired = malloc(sizeof(SDL_AudioSpec));
続いて、望みのオーディオの設定を構造体に格納します。

desired->freq

周波数 (1秒間のサンプル数)

desired->format

フォーマット (SDL_AudioSpec参照)

desired->samples

オーディオバッファのサイズ(サンプル単位)。この値は2の羃乗にすることが 薦められています。また、この値はドライバによってハードウエアに最適な値に 調整されることがあります。 アプリケーションやCPUの速度によって512から8192あたりまでの値を使うと よい結果が得られるようです。 この値を小さくするとレスポンスが向上しますが、 バッファアンダーフローをひきおこしやすくなります。 つまり、他のアプリケーションが重い処理をしたときに、時間内にバッファを 満たすことができなくなってしまう可能性が高くなります。 ステレオのデータは、左右のチャンネルが、左、右という順番で 1サンプルを構成します。 サンプル数は次の式で時間に変換することができます: ms = (samples*1000)/freq

desired->callback

オーディオデバイスがデータを準備できたときに呼ばれる関数を指定します。 この関数には、オーディオバッファへのポインタ、オーディオバッファのサイズ(バイト単位)が渡されます。 この関数は通常、別のスレッドで走りますので、 SDL_LockAudioSDL_UnlockAudioを 使ってこの関数がアクセスするデータを保護するべきです。 callbackのプロトタイプは以下の通りです:

void callback(void *userdata, Uint8 *stream, int len);
userdataは、SDL_AudioSpec構造体の中のuserdataフィールドへのポインタです。 streamは、データを格納することができる オーディオバッファへのポインタで、lenはそのバッファの 長さです(バイト単位)。

desired->userdata

関数callbackの第一引数として渡されるポインタです。

SDL_OpenAudioは、これらのフィールドを、 引数で与えられたSDL_AudioSpec構造体desiredから読み込み、 desired に合ったオーディオの設定を探そうとします。 既に述べた通り、パラメータobtainedNULLのとき、 SDLはパラメータdesiredの設定を、 ハードウエアの設定に合うように変換します。

もしパラメータobtainedNULLのときは、SDL_AudioSpec構造体desiredは 実際に有効な設定となります、 そうでない場合は、SDL_AudioSpec構造体obtainedが実際に有効な設定となりdesirecは 不要となります。 実際に有効になった設定は、読み込んだデータをハードウエアの フォーマットに変換するためのSDL_AudioCVT構造体を作成 するときに使用することができます。

SDL_OpenAudiodesiredobtained内の、 sizesilenceの 2つのフィールドを自動的に設定します。 sizeフィールドはオーディオバッファのサイズが バイト単位で格納されます。 一方、 silenceフィールドは、オーディオバッファ内で 「無音」をあらわす値が格納されます。

オーディオデバイスは、デバイスが開かれたときにまずsilenceデータを演奏しつづけます。 その後、callback 関数を呼ぶ準備が出来た 段階で、SDL_PauseAudio(0)を呼びだすことで動作を開始します。 オーディオドライバは、要求されたオーディオバッファの sizeの値を変更する可能性があるため、 オーディオデバイスを開いた後に、ローカルのミキシング用バッファを確保した 方がよいでしょう。

Examples


/* コールバック関数のプロトタイプ宣言 */
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);

See Also

SDL_AudioSpec, SDL_LockAudio, SDL_UnlockAudio, SDL_PauseAudio