int | freq | DSP周波数 (1秒あたりのサンプル数) (詳細を参照すること) |
SDL_AudioFormat | format | 音声データ形式 (詳細を参照すること) |
Uint8 | channels | 分けられた音声チャネルの数 (1秒あたりのサンプル数) |
Uint8 | silence | 無音の値 (計算される) |
Uint16 | samples | 音声バッファの長さ (2のベキ乗) (詳細を参照すること) |
Uint32 | size | 音声バッファのバイト数 (計算される) |
SDL_AudioCallback | callback | オーディオデバイスが更なるデータを要求した場合に呼ぶ関数 (詳細を参照すること) |
void* | userdata | callbackに渡されるポインタ (SDLはそれ以外は無視する) |
SDL_AudioSpec want, have;
SDL_AudioDeviceID dev;
extern void SDLCALL MyAudioCallback(void *userdata, Uint8 *stream, int len);
SDL_memset(&want, 0, sizeof(want)); /* または SDL_zero(want); */
want.freq = 48000;
want.format = AUDIO_F32;
want.channels = 2;
want.samples = 4096;
want.callback = MyAudioCallback; // 別の場所で関数を書く必要がある
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
この構造体はSDL_OpenAudioDevice()とSDL_LoadWAV()で使われる. SDL_OpenAudioDevice()は全てのフィールドを使う. SDL_LoadWAV()はfreq, format, channels, samplesを使う.
freqは1秒間にオーディオデバイスに送信するサンプルフレームの数である. ナイキストのサンプリング定理では, 音声のサンプリング周期は最も高い音の2倍以上である必要がある. 人は20kHzよりやや低い音を聞くことができるが, 加齢とともに16kHz程度までに低下する. 通常のCDは44100, DVDとOpus audio codecは48000を採用している. 48000はメモリとCPUパワーを多く消費するだけでなく, このXiphのChris Montgomeryによるblogの記事の問題あるため, BGM再生では使うべきではない.
formatは1サンプルのサイズと型を決める. SDL_AudioFormatの値の1つである.
channelsは出力するチャネルの数を決める. SDL2.0では, 1(モノラル), 2(ステレオ), 4(クアッド), 6(5.1)に対応している.
samplesは一度に出力する音声の長さを決める. SDL_OpenAudioDevice()で使う場合, この値は音声バッファのサンプルフレーム単位の長さになる. 1サンプルフレームは, formatで決まるサイズの音声データを, チャネル数だけ集めたものである. SDL_AudioSpecをSDL_LoadWAV()で使われる場合, samplesは4096に設定される. このフィールドの値は2のベキ乗の必要がある.
silenceの値はSDL_OpenAudioDevice()によって計算される.
マルチチャネルの場合, SDLのデフォルトのデータ格納順は次の通りである: 2: FL FR (ステレオ) 3: FL FR LFE (2.1 サラウンド) 4: FL FR BL BR (クアッド) 5: FL FR LFE BL BR (4.1 サラウンド) 6: FL FR FC LFE SL SR (5.1 サラウンド - 最後の2つは BL BR もありうる) 7: FL FR FC LFE BC SL SR (6.1 サラウンド) 8: FL FR FC LFE BL BR SL SR (7.1 サラウンド)
callbackの関数プロトタイプは
void SDL_AudioCallback(void* userdata, Uint8* stream, int len)
パラメータは
userdata | アプリケーション固有のSDL_AudioSpecのuserdataフィールドに保存したパラメータ |
stream | SDL_AudioCallback()が設定する音声データバッファのポインタ |
len | バッファのバイト長 |
コールバック関数はバッファを必ず完全に初期化しなければならない. SDL2.0では, コールバック関数が呼ばれる前にバッファは初期化されない. もし再生する音声がない場合は, コールバック関数はバッファをsilenceで満たさなければならない.