簡體   English   中英

核心音頻:文件播放渲染回調函數

[英]Core audio: file playback render callback function

我使用RemoteIO音頻單元 ,用於我的應用程序的音頻播放kAudioUnitProperty_ScheduledFileIDs 音頻文件為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讀取的緩沖區樣本,並將結果發送給揚聲器。

就像您剛剛熟悉核心音頻一樣,我建議您首先使remoteIO回調獨立於文件播放器運行。 只需刪除所有與文件播放器相關的代碼,然后嘗試使其首先運行即可。

然后,一旦完成工作,請繼續合並文件播放器。

據我所知這是錯誤的,我認為您正在將音頻文件服務API與音頻單元混淆。 該API用於將文件讀取到緩沖區中,然后您可以手動將其饋送到remoteIO,如果您確實想走這條路,請使用擴展音頻文件服務API,這很容易。 應該在文件播放器音頻單元上調用kAudioUnitProperty_ScheduledFileRegion屬性。 要獲得其中之一,除了AudioComponentDescription的componentSubType和componentType分別是kAudioUnitSubType_AudioFilePlayerkAudioUnitType_Generator之外,您需要使用與remmoteIO相同的方法來創建它。 然后,一旦有了該單元,就需要使用kAudioUnitProperty_MakeConnection屬性將其連接到kAudioUnitProperty_MakeConnection

但認真的說,首先要使remoteIO回調起作用,然后嘗試制作一個文件播放器音頻單元並連接它(不使用回調),然后從那里開始。

獨立地針對每個步驟提出非常具體的問題,發布您嘗試過的無效代碼,您將獲得大量幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM