2011-06-07 41 views
4

我需要處理來自iPod庫的音頻。讀取iPod資源的唯一方法是AVAssetReader。要使用音頻單元處理音頻,它需要採用立體聲格式,因此我有左右聲道的值。但是,當我使用AVAssetReader從iPod庫中讀取資源時,它不允許我以立體聲格式將其取出。它以交織格式出現,我不知道如何分解成左右聲道。如何將iPod庫資源連接到音頻隊列服務並使用音頻單元進行處理?

去的地步,我需要去我需要做以下之一:

  1. 獲取AVAssetReader給我立體聲格式
  2. 的AudioBufferList交織的數據轉換成非交錯到獲得立體聲輸出,我需要
  3. 發送它通過音頻隊列服務來獲得我所需要的具有自動緩衝

我似乎被什麼現有的公共API C是有限的一個do和AVAssetReader在讀取iPod資源時支持的內容。你會怎麼做?如何獲得我需要使用音頻單元進行處理的內容?

我的另一個限制是我無法一次讀完整首歌曲,因爲它會填滿內存並使應用程序崩潰。這就是我想要使用音頻隊列服務的原因。如果我可以將來自iPod庫的資產視爲立體聲格式的流,那麼我的所有要求都將得到解決。

這可以完成嗎?是否有任何文檔,博客或文章解釋如何完成這項工作?

+1

我不關注「立體聲」和「交錯」之間的區別。我認爲你要處理的是有兩個雙聲道音頻流(交錯,其中L和R是交替的),而不是兩聲道單聲道聲音。單位可以處理,但一個隊列將會與一個交錯流更快樂。 – invalidname 2011-06-15 21:06:56

回答

3

聽起來像你有幾個問題堆積在那裏。

當您設置AVAssetReader時,您可以傳入設置字典。這裏是我創造我AVAssetReaders ...

AVAssetReader* CreateAssetReaderFromSong(AVURLAsset* songURL) { 

    if([songURL.tracks count] <= 0) 
     return NULL; 


    AVAssetTrack* songTrack = [songURL.tracks objectAtIndex:0]; 

    NSDictionary* outputSettingsDict = [[NSDictionary alloc] initWithObjectsAndKeys: 

             [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey, 
             //  [NSNumber numberWithInt:AUDIO_SAMPLE_RATE],AVSampleRateKey, /*Not Supported*/ 
             //  [NSNumber numberWithInt: 2],AVNumberOfChannelsKey, /*Not Supported*/ 

             [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey, 
             [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey, 
             [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey, 
             [NSNumber numberWithBool:NO],AVLinearPCMIsNonInterleaved, 

             nil]; 

    NSError* error = nil; 
    AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:songURL error:&error]; 

    { 
     AVAssetReaderTrackOutput* output = [[AVAssetReaderTrackOutput alloc] initWithTrack:songTrack outputSettings:outputSettingsDict]; 
     [reader addOutput:output]; 
     [output release]; 
    } 

    return reader; 
} 

至於象分裂左,右聲道,你可以遍歷根據您的「AVLinearPCMBitDepthKey」的數據。

因此,像這樣的16位...

for (j=0; j<tBufCopy; j++, pAD+=2) {   // Fill the buffers... 
    mProcessingBuffer.Left[(tBlockUsed+j)] = ((sint32)pAD[0]); 
    mProcessingBuffer.Right[(tBlockUsed+j)] = ((sint32)pAD[1]); 
} 

現在假設你需要這個爲你處理。但交錯格式的數據真的很不錯。您通常可以採用直接交錯格式並將其傳遞迴AudioQueue或遠程I/O回調,並且它將正確播放。

爲了讓音頻使用AudioQueue框架播放數據應遵循這一流程:

AVAssetReader - > NSData的緩衝 - > AudioQueueBuffer

然後在AudioQueue回調在那裏,它要求只是更多的數據傳遞AudioQueueBuffer。就像...

- (void) audioQueueCallback:(AudioQueueRef)aq buffer:(AudioQueueBufferRef)buffer { 

    memcpy(buffer->mAudioData, srcData, mBufferByteSize); 
    //Setup buffer->mAudioDataSize 

    //... 

    AudioQueueEnqueueBuffer(mQueue, buffer, 0 /*CBR*/, 0 /*non compressed*/); 
} 
相關問題