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

2024-04-17

我需要处理来自 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<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 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*/);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐