我需要处理来自iPod库的音频。读取iPod库资产的唯一方法是AVAssetReader。要使用音频单元处理音频,它需要采用立体声格式,因此我有左右声道的值。但是,当我使用AVAssetReader从iPod库中读取资产时,它不允许我以立体声格式将其取出。它以交错格式出现,我不知道如何分成左右音频通道。
要到达我需要去的地方,我需要做以下其中一项:
我似乎受到现有公共API可以执行的操作以及AVAssetReader在读取iPod库资产时支持的内容的限制。你会怎么做?如何获得使用音频单元处理的内容?
我的另一个限制是我无法一次阅读整首歌曲,因为它会填满内存并使应用程序崩溃。这就是我想使用音频队列服务的原因。如果我可以将iPod资源中的资产视为立体声格式的流,那么我的所有要求都将得到解决。
甚至可以这样做吗?是否有任何文档,博客或文章可以解释如何做到这一点?
答案 0 :(得分: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或Remote I / O回调,它将正常播放。
为了使用AudioQueue框架播放音频,数据应遵循以下流程:
AVAssetReader - &gt; NSData缓冲区 - &gt; 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*/);
}