Multi-Channel Audio

Delivering forty channel audio using QuickTime APIs to adjust movie files.

A little while ago, Oliver (Watershed's ICT Co-ordinator) , asked me to write a small command line tool to set the audio output channels of a QuickTime movie. Oliver was writing software for Dream Director, a project that plays audio to people sleeping in pods in response to rapid eye movement.

A Mac mini plays back the audio to up to twenty pods (containing sleeping people) through a collection of M-Audio Firewire410 boxes. As the audio-out hardware units have been aggregated into a single virtual device with forty available channels, it was just a case of playing back a stereo file through a selected pair of channels.

QuickTime movies will save the audio channel mapping inside the file, so the requirement was to build a tool that would set the selected channels in a movie and save the file to disk. The source listing is for a Cocoa command-line Tool, using QTKit, to open an audio file, set the track mapping and save as a QuickTime movie.

QuickTime now uses Core Audio to handle the audio channel mapping and I thought this may be of some use to people. The partial listing below shows the code needed to map audio channels using QuickTime and a link to the source file of the tool is below the listing. Sorry about the wrapped source listing.

  1. Movie qtMovie = [movie quickTimeMovie];
  2. Track audioTrack = GetMovieIndTrack(qtMovie,1);
  3. AudioChannelLayout* trackChannelLayout = NULL;
  4. OSStatus err = noErr;
  5. UInt32 trackChannelLayoutSize;
  6. // Allocate a layout of the required size
  7. trackChannelLayoutSize = fieldOffset(AudioChannelLayout, mChannelDescriptions[2]);
  8. trackChannelLayout = (AudioChannelLayout*)calloc(1, trackChannelLayoutSize);
  9. trackChannelLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
  10. trackChannelLayout->mNumberChannelDescriptions = 2;
  11. // Adjust the channel Assignment so that for an index we get a pair of channel
  12. // allocations. The index starts at 1
  13. // index channelA channelB
  14. // -----------------------------
  15. // 1 discreet0 discreet1
  16. // 2 discreet2 discreet3
  17. // 3 discreet4 discreet5
  18. // 4 discreet6 discreet7
  19. // ... and so on
  20. channelAssignment = (channelAssignment-1)*2;
  21. #warning This will break if Apple change the CoreAudio's Channel Layout internals
  22. trackChannelLayout->mChannelDescriptions[0].mChannelLabel = (1L<<16) | channelAssignment;
  23. trackChannelLayout->mChannelDescriptions[1].mChannelLabel = (1L<<16) | (channelAssignment + 1);
  24. // Set the track layout
  25. err = QTSetTrackProperty(audioTrack, kQTPropertyClass_Audio, kQTAudioPropertyID_ChannelLayout, trackChannelLayoutSize, trackChannelLayout);
  26. if (err != noErr) {
  27. NSLog(@"**Error** QuickTime SetPropertyError: %i", err);
  28. return 1;
  29. }
  30. Download the full source code.

    |

odds&ends…
Benjamin Miller