2016-06-12 18 views
0

私はkAudioUnitProperty_ScheduledFileIDsと私のアプリでのオーディオ再生のためのリモート012オーディオユニットを使用しています。 オーディオファイルはPCM形式です。この場合、どのようにレンダリングコールバック関数を実装すればよいので、バッファサンプルを手動で変更できますか?ここで
が私のコードです:
コアオーディオ:ファイル再生レンダリングコールバック関数

static AudioComponentInstance audioUnit; 

AudioComponentDescription desc; 

desc.componentType = kAudioUnitType_Output; 
desc.componentSubType = kAudioUnitSubType_RemoteIO; 
desc.componentManufacturer = kAudioUnitManufacturer_Apple; 
desc.componentFlags = 0; 
desc.componentFlagsMask = 0; 

AudioComponent comp = AudioComponentFindNext(NULL, &desc); 

CheckError(AudioComponentInstanceNew(comp, &audioUnit), "error AudioComponentInstanceNew"); 


NSURL *playerFile = [[NSBundle mainBundle] URLForResource:@"short" withExtension:@"wav"]; 

AudioFileID audioFileID; 

CheckError(AudioFileOpenURL((__bridge CFURLRef)playerFile, kAudioFileReadPermission, 0, &audioFileID), "error AudioFileOpenURL"); 

// Determine file properties 
UInt64 packetCount; 
UInt32 size = sizeof(packetCount); 
CheckError(AudioFileGetProperty(audioFileID, kAudioFilePropertyAudioDataPacketCount, &size, &packetCount), 
       "AudioFileGetProperty(kAudioFilePropertyAudioDataPacketCount)"); 

AudioStreamBasicDescription dataFormat; 
size = sizeof(dataFormat); 
CheckError(AudioFileGetProperty(audioFileID, kAudioFilePropertyDataFormat, &size, &dataFormat), 
       "AudioFileGetProperty(kAudioFilePropertyDataFormat)"); 

// Assign the region to play 
ScheduledAudioFileRegion region; 
memset (&region.mTimeStamp, 0, sizeof(region.mTimeStamp)); 
region.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid; 
region.mTimeStamp.mSampleTime = 0; 
region.mCompletionProc = NULL; 
region.mCompletionProcUserData = NULL; 
region.mAudioFile = audioFileID; 
region.mLoopCount = 0; 
region.mStartFrame = 0; 
region.mFramesToPlay = (UInt32)packetCount * dataFormat.mFramesPerPacket; 
CheckError(AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ScheduledFileRegion, kAudioUnitScope_Global, 0, &region, sizeof(region)), 
       "AudioUnitSetProperty(kAudioUnitProperty_ScheduledFileRegion)"); 

// Prime the player by reading some frames from disk 
UInt32 defaultNumberOfFrames = 0; 
CheckError(AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ScheduledFilePrime, kAudioUnitScope_Global, 0, &defaultNumberOfFrames, sizeof(defaultNumberOfFrames)), 
       "AudioUnitSetProperty(kAudioUnitProperty_ScheduledFilePrime)"); 

AURenderCallbackStruct callbackStruct; 
callbackStruct.inputProc = MyCallback; 
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self); 

CheckError(AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callbackStruct, sizeof(callbackStruct)), "error AudioUnitSetProperty[kAudioUnitProperty_setRenderCallback]"); 

CheckError(AudioUnitInitialize(audioUnit), "error AudioUnitInitialize"); 

コールバック関数:

static OSStatus MyCallback(void *inRefCon, 
          AudioUnitRenderActionFlags *ioFlags, 
          const AudioTimeStamp *inTimeStamp, 
          UInt32 inBusNumber, 
          UInt32 inNumberFrames, 
          AudioBufferList *ioData){ 

    printf("my callback"); 
    return noErr; 
} 

オーディオユニットのボタンを押し上で再生を開始:

- (IBAction)playSound:(id)sender { 

CheckError(AudioOutputUnitStart(audioUnit), "error AudioOutputUnitStart"); 

} 

このkAudioUnitErr_InvalidProperty(-10879)エラーでコンパイル中にコードが失敗します。目的は、AudioFileIDから読み取られたバッファーサンプルを変更し、その結果をスピーカーに送信することです。

+0

「MyCallback()」はどこですか? – user3078414

+0

@ user3078414、 'UPD:'セクションに追加されました – jangofett

+0

'kAudioUnitErr_InvalidElement'別名' -10877'は初期化エラーです。ランタイムエラーAFAIKはありません。私は、「コードの残りの部分はうまくいく」と言ってどういう意味なのか分かりません。あなたのプログラムの "構造"は何ですか?あなたは「AudioUnitsの使用」について述べています。これは単一のAUプログラムですか、または複数のAUs_を使用していますか?何のために?もしそうなら、それらを明示的に接続するのか、 'AUGraph' APIを使って接続しますか? – user3078414

答えて

1

コアオーディオにどのように慣れ親しんでいるかを見ると、ファイルプレーヤーとは独立してリモートIOコールバックを取得することをお勧めします。ファイルプレーヤに関連するコードをすべて削除して、まずそれを動作させてみてください。

次に、作業が完了したら、ファイルプレーヤーを組み込むことに進みます。

私が間違っていることが分かる限り、Audio File Services APIをオーディオユニットと混同していると思います。このAPIはリモートIOに手動でフィードするバッファにファイルを読み込むために使用されます。このルートを使用する場合は、Extended Audio File Services APIを使用してください。 kAudioUnitProperty_ScheduledFileRegionプロパティは、ファイルプレーヤーのオーディオユニットで呼び出されるはずです。その1つを取得するには、AudioComponentDescriptionのcomponentSubTypeとcomponentTypeがそれぞれkAudioUnitSubType_AudioFilePlayerkAudioUnitType_Generatorであることを除いて、remmoteIOと同じ方法で作成する必要があります。その後、ユニットを取得したら、kAudioUnitProperty_MakeConnectionプロパティを使用してremoteIOに接続する必要があります。

しかし、真剣に、あなたのremoteIOコールバックの作業を開始してから、ファイルプレーヤのオーディオユニットを作成して(コールバックなしで)接続してそこから行ってみてください。

これらの各ステップについては、個別に非常に具体的な質問をしてください。あなたが試したことがあるコードを投稿すると、多大な助けになります。

+0

ありがとう、正しい方向を指しています。この質問を見ていただけますか? http://stackoverflow.com/questions/37870051/ios-core-audio-audiofileplayer-unit-render-callback File playerとRemoteIO Unitsが接続されていて、スピーカーからの音が聞こえますが、コールバック機能で再び立ち往生します。前もって感謝します。 – jangofett

関連する問題