void SDL_LockAudioDevice(SDL_AudioDeviceID dev)
dev | ロックするオーディオデバイスのID |
void MyAudioCallback(void *userdata, Uint8* stream, int len)
{
printf("オーディオコールバック開始!¥n");
SDL_memset(stream, 0, len); // ただ沈黙のみ
printf("オーディオコールバック終了!¥n");
}
// 実際には一度に2秒も止めないようにすること
extern SDL_AudioDeviceID devid;
SDL_Delay(2000); // コールバックは2秒間動作する
SDL_LockAudioDevice(devid);
printf("今からオーティオコールバックは動作しない!¥n");
SDL_Delay(2000); // コールバックは2秒間動作しない
printf("OK, アンロックした!¥n");
SDL_UnlockAudioDevice(devid);
SDL_Delay(2000); // コールバックは2秒間動作する
これらのロック操作関数は, SDL_OpenAudioDevice()で設定したコールバック関数を停止する. SDL_LockAudioDevice()とSDL_UnlockAudioDevice()の間は, オーディオデバイスを一時停止していなくてもコールバック関数は実行されないことが保障されている. あるオーディオデバイスがロックされている間でも, 別のロックされていないオーディオデバイスは再生が一時停止されていない限り実行される.
コールバック関数の中でこの関数を呼ぶ必要はない. SDLはコールバック関数を呼ぶ前にロックしている. そして関数を抜けるとロックを解除する.
必要以上に長くロックするべきではない. ロックが長すぎると, 再生の抜けが発生する. 理想的には, ロックした後はいくつかの変数に代入するだけにして, すぐにロック解除するべきだ. オーディオデバイスをロックしている間に重い処理をしてはならない.
オーディオデバイスを複数回ロックしても, 同じ回数ロック解除すれば安全である. この場合もコールバック関数は完全にロック解除されるまで実行されない. アプリケーションがオーディオデバイスの正常なロック解除に失敗すれば, コールバック関数は呼ばれなくなる. この場合, 同じ音が繰り返し聞こえるだろう. 恐らくSDL_CloseAudioDevice()もデッドロック状態になる.
内部的には, オーディオデバイスのロックはmutexである. 2つのスレッドで同時にロックすると, コールバック関数が停止するだけでなく, 他のスレッドも停止する.