サウンド再生について

サウンド再生について調べてみました.
複数音同時再生させたいんだけれども、CPUでミキシングをしているからなのか、いまいち非力な感じです.

そんなわけで、とりあえずのメモを...

再生の方法

サウンドを鳴らす場合には、いくつかの選択肢がある.

どれも一長一短あるようだが、実装が平易なのは、 SystemSoundService もしくは、AVFoundation だと
思われる.

System Sound Service

  • ごく短い(30秒未満)のサウンドファイルを、レベル制御/再生位置設定などの制御を行わずに再生する.
  • 再生が遅延する.(ゲームなどのリアルタイム処理にはむかない)
  • 利用するのは楽
  • リニア PCM
  • IMA/ADPCM(IMA4)
  • *.caf / *.aif / *.wav のいずれか
  • サンプルの Metronome についている SoundEffect クラスがそのままサウンドのサンプルになっている

AVAudioPlayer

iPhone OS 2.2 以降では、 AVAudioPlayer を利用することができる.

利用方法も簡単だし十分な機能が実装されているので、単純なサウンド再生を行うのには便利だと思う.
(ただし、一応複数音の同時発音が行えるが、ミキシングをCPUで行っているようなので結構遅い.単音を利用する程度か?)

AVAuioPlayer でできることを以下に挙げる.

  • 再生位置の変更
  • 回数を指定したループ(無限ループ含む)
  • 再生音量の指定
  • ボリュームの調節
  • 開始/終了の取得(Delegate)
  • 複数音の同時再生
  • ファイルからのインスタンス生成
  • バイト列からのインスタンス生成


初期化の例を次に記す.

#include <UIKit/UIKit.h>
#include <AVFoundation/AVFoundation.h>

@interface SoundTestView : UIView
{
    AVAudioPlayer*    m_sound;
}

-(void) initSound;
@end
- (void) initSound
{
    NSString* a_file_path = [a_bundle pathForResource:@"test" ofType:@"wav"];
    NSURL* a_file_url = [NSURL fileURLWithPath:a_file_path];

    if( a_file_url ){
        NSError* a_error = nil;
        m_sound = [[AVAudioPlayer alloc] initWithContentsOfURL:a_file_url error:&a_error];
    }
}

正常にファイルが読み込めていれば、 play メッセージを送信するだけで音が鳴る.

[m_sound play];

再生位置の設定には、プロパティ currentTime を用いればよい.
dultion プロパティを用いると、サウンド全体の長さが取得できるので、そこから再生位置を設定すればよい.

    m_soundd.currentTime = m_sound.duration / 2.0f;
    [m_sound play];

ループの指定には、numberOfLoops プロパティを用いる.
2回再生を行いたい場合には、次のように再生することになる.

    m_sound.numberOfLoops = 2;
    [m_sound play];

無限ループを行いたい場合には、-1 を設定すればよい.


注意点

AVAudioPlayer を利用する場合には、AVFoundation.framework の追加と AVFoundation/AVFoundation.h もしくは、 AVFoundation/AVAudioPlayer.h のインクルードが必要.

また、AVAudioPlayer は、 iPhone OS 2.2 以降に追加されている API なので、 アクティブな SDK を選択する場合に、「Device - iPhone OS 2.2」もしくは、「Simlator - iPhone OS 2.2」を選択している必要がある.

間違えて、 iPhone OS 2.1 等を選択してしまうと、ヘッダが見つからない旨を告げるエラーが発生する点に注意.

error: AVFoundation/AVAudioPlayer.h: No such file or directory

おまけ

フレームワークの追加は、Xcode 上の "Frameworks" フォルダを右クリックし、[追加] - [既存のフレームワーク]から行うことができる.

対応するフレームワークの一覧から選択が行えるが、AVFoundation.frameworkd が一覧に出ていない場合には、プロジェクトの設定にあるベース SDKの設定が 2.1(or 2.0)になっている可能性が考えられる.

[プロジェクト設定を編集]から、プロジェクト設定ダイアログを開き、[一般]タブから、"すべての構成のベースSDK"の項目を、「Device - iPhone OS 2.2」もしくは、「Simlator - iPhone OS 2.2」に選択しておくと、iPhone OS 2.2 に対応するフレームワークの一覧から選択することができる.

(私は、これがよく分からずに、長いパスをたどっていた...)

まとめ

AVFoundation は便利だけれども、私が望む利用用途としては少し非力に感じた.