8
votes

I'd like to be able to get back AudioBufferList from AVAssetReader which has 2 buffers so that I can process the left and right audio through an AudioUnit. I tried using the output settings below but it will not read as long as I specify the stereo layout set by kAudioChannelLayoutTag_Stereo.

Is it possible for AVAssetReader to return a non-interleaved result?

If not, how would I convert it to a non-interleaved AudioBufferList? I have tried to use Audio Converter Services but I cannot get it to accept either the the input or output values for the AudioStreamBasicDescription. (ASBD) If I cannot get the data in the format I want from AVAssetReader I would like to at least be able to convert it to the format I need.

Any tips are appreciated.

- (NSDictionary *) getOutputSettings {
    AudioChannelLayout channelLayout;
    memset(&channelLayout, 0, sizeof(AudioChannelLayout));
    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, 
                                    [NSNumber numberWithFloat:44100.0], AVSampleRateKey,
                                    [NSNumber numberWithInt:2], AVNumberOfChannelsKey,
                                    [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
                                    [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                                    [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
                                    nil];

    return outputSettings;
}
2
Done. I found some old ones hanging out there.Brennan

2 Answers

1
votes

I think that kAudioChannelLayoutTag_Stereo is requesting interleaved samples, so I'd lose it.

It all depends on what kind of AVAssetReaderOutput you're creating with those output settings. AVAssetReaderTrackOutput does no conversion beyond decoding to LPCM, but AVAssetReaderAudioMixOutput accepts a bunch more format keys, in fact it probably IS an AVAssetReaderTrackOutput + AudioConverter.

0
votes

I've learned that I can have AVAssetReader return results with the default output settings (nil) which will give me an interleaved result of float values. The buffer of float values alternates from Left to Right through the buffer. I am able to work with these values which are in the range of -1.0 to 1.0 but in order to play the audio it is necessary to increase the values to the range of a short signed int, so I multiply them by SHRT_MAX and ensure the values stay within the range of SHRT_MAX and SHRT_MIN so the audio plays as expected.

Since the interleaved buffer returns the L and R values on the same buffer it is considered 2 channels on the 1 buffer which is reflected in the AudioBufferList. Previously I was able to get back 2 buffers with 1 channel per buffer but that is not really necessary now that I understand the very simple interleaved format.