文書の表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。 ====== QA1394: Mac OS X v10.3.xでCoreAudioと共にNSSoundを使う ====== 原文 //Technical Q&A QA1394: Using NSSound with CoreAudio on Mac OS 10.3.x [[http://developer.apple.com/qa/qa2005/qa1394.html]] // ===== Mac OS X v10.3.xでCoreAudioと共にNSSoundを使う場合、なぜIOProcコールバックで得られるデータがNULLになるのでしょうか? ===== 回答: アプリケーションによっては、Application Kitフレームワークの''NSSound''とCore Audioを同一アプリケーション内で一緒に使った方が便利なことがあります。 開発者は''NSSound''がCore AudioのHAL(ハードウェア抽象化層)のIOProcとやり取りしている可能性を考慮しなければなりません。 MacOS 10.3.xシステムでは、Core AudioフレームワークのIOProcコールバックと同じプロセスの中で''NSSound''クラスを使うと、IOProcコールバックの入力バッファがNULLになる可能性があります。 このバグは、''NSSound''が音声出力に使う装置、つまりデフォルト音声出力装置にCore AudioのIOProcを追加するアプリケーションに影響を及ぼします。 Core AudioのIOProcを音声装置に追加する前に''NSSound''を呼ぶと、アプリケーションはIOProc内でNULL入力バッファを受け取る事になるでしょう。 この問題を回避するには、あらゆる''NSSound''呼び出しの前に''AudioDeviceAddIOProc''を呼ぶ必要があります。 **Listing 1:** 問題有りのサンプル <code c_mac> #import <Cocoa/Cocoa.h> #import <CoreAudio/CoreAudio.h> OSStatus recordIOProc ( AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData ) { if ( inInputData ) { if ( inInputData->mBuffers[0].mData == NULL ) NSLog (@"CoreAudio IOProcの入力バッファはNULL"); } return noErr; } int main() { NSAutoreleasePool * pool = [NSAutoreleasePool new]; AudioDeviceID device; UInt32 theSize = sizeof(AudioDeviceID); verify_noerr( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice, &theSize, & device ) ); NSSound *sound = [[NSSound alloc] initWithContentsOfFile: @"/System/Library/Sounds/Submarine.aiff" byReference:NO]; [sound play]; verify_noerr( AudioDeviceAddIOProc ( device, recordIOProc, NULL ) ); verify_noerr( AudioDeviceStart ( device, recordIOProc ) ); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; verify_noerr( AudioDeviceStop ( device, recordIOProc ) ); verify_noerr( AudioDeviceRemoveIOProc ( device, recordIOProc ) ); [sound release]; [pool release]; return 0; } </code> 上のサンプルコードを実行すると、標準出力(stdout)に何回も"CoreAudio IOProcの入力バッファはNULL"と表示される事がわかります。 この問題を回避するには、<html><code>NSSound</code></html>呼び出しの前に、<html><code>AudioDeviceAddIOProc</code></html>を呼び出します。 上記サンプルの問題修正版を以下に掲載します: **Listing 2:** 問題を修正したサンプル <code c_mac> #import <Cocoa/Cocoa.h> #import <CoreAudio/CoreAudio.h> OSStatus recordIOProc ( AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData ) { if ( inInputData ) { if ( inInputData->mBuffers[0].mData == NULL ) NSLog (@"CoreAudio IOProcの入力バッファはNULL"); } return noErr; } int main() { NSAutoreleasePool * pool = [NSAutoreleasePool new]; AudioDeviceID device; UInt32 theSize = sizeof(AudioDeviceID); verify_noerr( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice, &theSize, & device ) ); // NSSoundを使う「前」に呼ぶ verify_noerr( AudioDeviceAddIOProc ( device, recordIOProc, NULL ) ); NSSound *sound = [[NSSound alloc] initWithContentsOfFile: @"/System/Library/Sounds/Submarine.aiff" byReference:NO]; [sound play]; verify_noerr( AudioDeviceStart ( device, recordIOProc ) ); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; verify_noerr( AudioDeviceStop ( device, recordIOProc ) ); verify_noerr( AudioDeviceRemoveIOProc ( device, recordIOProc ) ); [sound release]; [pool release]; return 0; } </code> ここでの変更は、<html><code>AudioDeviceAddIOProc</code></html>呼び出しを<html><code>NSSound</code></html>呼び出しの前に移動しただけだという点に注目して下さい。 このサンプルコードを実行しても、recordIOProcが"CoreAudio IOProcの入力バッファはNULL"と表示することはありません。つまりこれは、正しい入力バッファを受け取っている事を示しています。 ''NSSound''呼び出し前に''AudioDeviceStart''を呼ぶ必要は無い事に注意してください。 ''AudioDeviceAddIOProc''だけでいいのです。 ===== 更新履歴 ===== ^日付^内容| |2005-06-30|NSString使用時のAudioDeviceAddIOProc使用によるCore Audio IOProcの入力バッファがNULLになる問題の対処に関する新規ドキュメント| translation/adc/audio/technical_qa/qa1394_using_nssound_with_coreaudio_on_mac_os_10.3.x.txt 最終更新: 2015-01-06 11:51(外部編集)