Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I now finally found an answer to this question - at least for deployment on iOS 6. You can easily add an <strong>MTAudioProcessingTap</strong> to your existing AVPlayer item and copy the selected channels samples to the other channel during your process callback function. Here is a great tutorial explaining the basics: <a href="http://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/" rel="nofollow">http://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/</a></p> <p>This is my code so far, mostly copied from the link above.</p> <p>During AVPlayer setup I assign callback functions for audio processing:</p> <pre><code>MTAudioProcessingTapCallbacks callbacks; callbacks.version = kMTAudioProcessingTapCallbacksVersion_0; callbacks.clientInfo = ( void *)(self); callbacks.init = init; callbacks.prepare = prepare; callbacks.process = process; callbacks.unprepare = unprepare; callbacks.finalize = finalize; MTAudioProcessingTapRef tap; // The create function makes a copy of our callbacks struct OSStatus err = MTAudioProcessingTapCreate(kCFAllocatorDefault, &amp;callbacks, kMTAudioProcessingTapCreationFlag_PostEffects, &amp;tap); if (err || !tap) { NSLog(@"Unable to create the Audio Processing Tap"); return; } assert(tap); // Assign the tap to the input parameters audioInputParam.audioTapProcessor = tap; // Create a new AVAudioMix and assign it to our AVPlayerItem AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; audioMix.inputParameters = @[audioInputParam]; playerItem.audioMix = audioMix; </code></pre> <p>Here are the audio processing functions (actually process is the only one needed):</p> <pre><code>#pragma mark Audio Processing void init(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut) { NSLog(@"Initialising the Audio Tap Processor"); *tapStorageOut = clientInfo; } void finalize(MTAudioProcessingTapRef tap) { NSLog(@"Finalizing the Audio Tap Processor"); } void prepare(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat) { NSLog(@"Preparing the Audio Tap Processor"); } void unprepare(MTAudioProcessingTapRef tap) { NSLog(@"Unpreparing the Audio Tap Processor"); } void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut, CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut) { OSStatus err = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, NULL, numberFramesOut); if (err) NSLog(@"Error from GetSourceAudio: %ld", err); SIVSViewController* self = (SIVSViewController*) MTAudioProcessingTapGetStorage(tap); if (self.selectedChannel) { int channel = self.selectedChannel; if (channel == 0) { bufferListInOut-&gt;mBuffers[1].mData = bufferListInOut-&gt;mBuffers[0].mData; } else { bufferListInOut-&gt;mBuffers[0].mData = bufferListInOut-&gt;mBuffers[1].mData; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload