AudioToolBoxで音声を再生(ARC対応)

Objective-c

音声を再生するアプリを作成した際に考えた事、
エラー、等をまとめました。

このブログにあるスニペットは実行可能なプロジェクトとしてgithubに置いてあります。

audio-toolbox-sample

どのFrameworkを採択するか?

cocoaは音声を再生するのに様々なFrameworkを提供してくれています。
どれを選ぶかは、以下のAppleの記事の「Choose the right technology for your needs:」
を参考にすると良いでしょう。
Audio & Video Starting Point

僕は今回AudioToolBoxを選択しました。
音声の再生、停止、曲のループをする所まで書きたいと思います。

Audio Toolbox Framework Reference

注意点としては、以下があります。

・30秒を超える音声ファイルは再生出来ない
・音量調整、再生位置指定、ループ(※1)等が出来ない
・.caf、.aiff、.wavのみ対応(mp3は不可)
※1、コールバックで制御する事で可能

実装

まず、AudioToolBox.frameworkを追加します。
(追加の方法は割愛。)

コードでの実装は以下の様になります。

SystemSoundID soundId = UINT32_MAX; // 1
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:@"fanfare" withExtension:@"wav"], &soundId); // 2
AudioServicesPlaySystemSound(soundId); // 3

1. SystemSoundID型の変数を用意する(再生する音声一つに付き一つの変数が必要です)
2. AudioServicesCreateSystemSoundIDで1で用意した変数を初期化する
3. AudioServicesPlaySystemSoundで2で初期化したSystemSoundIDの変数を指定して音声を再生
1〜3をまとめると以下の様な記述となります。

ARC対応

※2の箇所は本来であれば

AudioServicesCreateSystemSoundID([[NSBundle mainBundle] URLForResource:@"fanfare" withExtension:@"wav"], &soundId);

で良いのですが、ARCですと

Implicit conversion of Objective-C pointer type 'NSURL *' to C pointer type 'CFURLRef' (aka 'const struct __CFURL *') requires a bridged cast

と言うエラーが出るので上記の様にブリッジキャストをしています。

停止

Appleが提唱している方法ではありませんが、以下の一行で可能です。

AudioServicesDisposeSystemSoundID(soundId);

ループ

AudioServicesAddSystemSoundCompletionメソッドにより、再生完了のコールバックメソッドを指定出来ます。

soundIdの初期化をした後に指定します。

AudioServicesAddSystemSoundCompletion(soundId, NULL, NULL, completionBlock, (__bridge void *)self);

ここでもCへ渡すためにブリッジキャストを行います。
これを行う事でコールバックメソッドへ自インスタンスの情報を渡す事が出来ます。
コールバックメソッドは以下の様に実装します。

void completionBlock(SystemSoundID soundId, void *clientData) {
    
    ViewController *viewController = (__bridge ViewController *)clientData;
    if(soundId == viewController.fanfareSoundId) {
        AudioServicesPlaySystemSound(soundId);
        return;
    }
    
    return;
    
};

インターフェースで分かると思いますが、
第一引数のsoundIdには再生が終了したsoundId、
第二引数には呼び出しもとのインスタンスが入ります。

誰かのお役に立てば。

コメント

タイトルとURLをコピーしました