Apple Developer Connection
高度な検索
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1459
QuickTime Audio - Easy Frequency Level Metering with MovieAudio APIs

Q:オーディオファイルやQuickTimeムービーの周波数レベルを取得し、iTunesやQuickTime Playerのように表示するにはどうしたらよいでしょうか?

A:QuickTime 7では、いくつかの“MovieAudio API”が追加され、音量と周波数の測定、ゲイン調節、オーディオバランスやミュートの設定などがごく簡単に行えるようになりました。APIのいくつかは既存の機能と重複していますが、“MovieAudio API”のほうがシンプルで一貫したプログラムインターフェイスを提供し、これらのタスクを実行するのに望ましい方法になっています。

たとえば、周波数レベルを監視するには、メディアハンドラのレベルに下がってMediaSetSoundEqualizerBandsMediaGetSoundEqualizerBandLevelsを使う必要はもうありません。

QuickTimeムービーを渡すことで、2つの“MovieAudio API”を使って簡単に周波数を測定できます。まずSetMovieAudioFrequencyMeteringNumBandsを呼び出して特定のオーディオミックスの周波数測定を設定します(利用できるミックスの詳細については「参考資料」のセクションを参照してください)。次に、必要に応じてGetMovieAudioFrequencyLevelsを呼び出して現在の周波数測定レベルを取得します。値は、監視するバンドの数に従って割り当てるQTAudioFrequencyLevels構造体に返されます。

注意:これらの測定用APIは、オーディオデータを再生チェーンから取得するため、ムービーの再生中にのみ機能します。

GetMovieAudioFrequencyLevelsはFFT処理(Fast Fourier Transform)を実行し測定レベルを計算します。FFTウインドウは、表示の対象となるスペクトルバンド数に比例します。

  • 1-4 バンド -> 256-pt FFT

  • 5-15 バンド -> 512-pt FFT

  • 16-128 バンド -> 1024-pt FFT

注意:FFTは測定レベルを要求するたびに実行されるため、生じるオーバーヘッドの量は呼び出しの頻度に比例します。さらに、要求するチャンネルごとにFFTがあります。これはつまり、プレミックス(たとえばkQTAudioMeter_DeviceMixを使用)をせずにN個のチャンネルのサラウンドサウンドのデータを測定しようとすると、呼び出しのたびにN個のFFTが実行されるということです。

リスト1:周波数測定の設定

UInt32 numberOfBandLevels = 7;   // もっと高い周波数バンドにはこの数を増やす
UInt32 numberOfChannels = 2;     // DeviceMixを使っている場合はStereoMix用
                                 // デバイスのチャンネル数を取得する必要がある

QTAudioFrequencyLevels *freqResults = NULL;

...

// ムービーごとにこれを呼び出し、測定を実行する
err = SetMovieAudioFrequencyMeteringNumBands(myMovie,
                                             kQTAudioMeter_StereoMix,
                                             &numberOfBandLevels);
if (err) goto bail;

freqResults = malloc(offsetof(QTAudioFrequencyLevels,
                              level[numberOfBandLevels * numberOfChannels]));
if (freqResults == NULL) {
    err = memFullErr;
    goto bail:
}

freqResults->numChannels = numberOfChannels;
freqResults->numFrequencyBands = numberOfBandLevels;

...

リスト2:測定されたレベルの取得

...

// 測定レベルを表示する準備が整うたびに呼び出す
if (freqResults != NULL) {
    err = GetMovieAudioFrequencyLevels(myMovie, kQTAudioMeter_StereoMix, freqResults);
    if (err) goto bail;

    for (i = 0; i < freqResults->numChannels; i++) {
        for (j = 0; j < freqResults->numFrequencyBands; j++) {
            // 周波数レベルは0. から1. のFloat32型の値
            Float32 value = freqResults->levels[(i *
                                                freqResults->numFrequencyBands) + j];

            // 値を使って何か処理をする
            ...
        }
    }
}

...

リスト3:kQTAudioMeter_DeviceMix使用時のチャンネル数の取得

    AudioChannelLayout *layout = NULL;
    UInt32 size = 0;
    UInt32 numChannels = 0;
    OSStatus err;

...

    // デバイスレイアウトのサイズを取得する
    err = QTGetMoviePropertyInfo(theMovie, kQTPropertyClass_Audio,
                                 kQTAudioPropertyID_DeviceChannelLayout,
                                 NULL, &size, NULL);

    if (err || (0 == size)) goto bail;

    // デバイスレイアウトにメモリを割り当てる
    layout = (AudioChannelLayout*)calloc(1, size);
    if (NULL == layout) {
        err = memFullErr;
        goto bail;
    }

    // ムービーからデバイスレイアウトを取得する
    err = QTGetMovieProperty(theMovie, kQTPropertyClass_Audio,
                             kQTAudioPropertyID_DeviceChannelLayout,
                             size,
                             layout,
                             NULL);
    if (err) goto bail;

    // ここでチャンネル数を取得する
    numChannels = (layout->mChannelLayoutTag ==
                   kAudioChannelLayoutTag_UseChannelDescriptions) ?
                   layout->mNumberChannelDescriptions :
                   AudioChannelLayoutTag_GetNumberOfChannels(layout->mChannelLayoutTag);

    free(layout);

...

参考資料

ムービー、オーディオ、ミックス

3つの定数が、周波数測定のオーディオチャンネルのミックスを定義します。

kQTAudioMeter_StereoMix - ムービー内の有効なサウンドトラックのステレオ(2チャンネル)ミックスを測定します。

kQTAudioMeter_MonoMix - モノラルへミックスされたムービーとして測定します。

kQTAudioMeter_DeviceMix - ムービーを再生するデバイスのAudioChannelLayoutへの
ムービーのミックスを測定します。

先頭に戻る 

ドキュメント改訂履歴

日付メモ
2006-01-26初版

掲載日: 2006-01-26




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.