如何将iPod库资源连接到音频队列服务并使用音频单元进行处理?

我需要处理来自iPod库的音频。 读取iPod库资产的唯一方法是AVAssetReader。 要使用音频单元处理音频,它需要采用立体声格式,因此我有左右声道的值。 但是,当我使用AVAssetReader从iPod库中读取资产时,它不允许我以立体声格式获取它。 它以交错格式出现,我不知道如何打入左右音频通道。

为了到达我需要去的地方,我需要做以下其中一项:

  1. 获取AVAssetReader给我一个立体声格式的AudioBufferList
  2. 将交错数据转换为非交错数据以获得我需要的立体声输出
  3. 通过音频队列服务发送它以获得我需要的自动缓冲

我似乎受限于现有公共API可以做什么以及AVAssetReader在读取iPod库资产时支持的内容。 你会怎么做? 如何获得我需要使用音频单元处理的内容?

我的另一个限制是我不能一次读完整首歌,因为它会填满内存并使应用程序崩溃。 这就是我想使用音频队列服务的原因。 如果我可以将iPod库中的资源视为立体声格式的流,那么我的所有要求都将得到解决。

甚至可以这样做吗? 是否有任何文档,博客或文章可以解释如何做到这一点?

听起来你有几个问题堆积在那里。

设置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 

现在我假设你需要这个来处理。 但是以交错格式存储数据真的很不错。 您通常可以采用直接交错格式并将其直接传递回AudioQueue或Remote I / O回调,它将正常播放。

为了使用AudioQueue框架播放音频,数据应遵循以下流程:

AVAssetReader - > NSData Buffer - > 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*/); }