|
Q: How can I retrieve the frequency levels of an audio file or a QuickTime Movie and display them like iTunes or QuickTime Player does?A: QuickTime 7 introduced a number of 'MovieAudio' APIs that now make performing tasks such as volume and frequency metering, adjusting gain, setting audio balance and mute very easy. While some of these APIs may duplicate existing functionality, the 'MovieAudio' APIs present a simpler, more consistent programmer interface and are now the preferred way to perform these tasks. For example, to monitor frequency levels it is no longer necessary to drop down to the media handler level and use Given a QuickTime Movie, it's easy to perform frequency metering using two 'MovieAudio' APIs. First call Note: These Metering APIs will only function during Movie playback since they get their audio data from the playback chain.
Note: The FFT is performed each time you request meter levels so the amount of overhead incurred is proportional to the frequency of the call. Additionally there is an FFT for each channel you request, this means that if you're trying to meter N-channel surround sound data without a pre-mix (for example, using UInt32 numberOfBandLevels = 7; // increase this number for more frequency bands UInt32 numberOfChannels = 2; // for StereoMix - if using DeviceMix, // you need to get the channel count of the device QTAudioFrequencyLevels *freqResults = NULL; ... // call this once per movie to establish metering err = SetMovieAudioFrequencyMeteringNumBands(myMovie, kQTAudioMeter_StereoMix, &numberOfBandLevels); if (err) goto bail; freqResults = malloc(offsetof(QTAudioFrequencyLevels, level[numberOfBandLevels * numberOfChannels])); if (freqResults == NULL) { err = memFullErr; goto bail: } freqResults->numChannels = numberOfChannels; freqResults->numFrequencyBands = numberOfBandLevels; ... ... // call each time you are ready to display meter levels if (freqResults != NULL) { err = GetMovieAudioFrequencyLevels(myMovie, kQTAudioMeter_StereoMix, freqResults); if (err) goto bail; for (i = 0; i < freqResults->numChannels; i++) { for (j = 0; j < freqResults->numFrequencyBands; j++) { // the frequency levels are Float32 values between 0. and 1. Float32 value = freqResults->level[(i * freqResults->numFrequencyBands) + j]; // do something with the value ... } } } ... AudioChannelLayout *layout = NULL; UInt32 size = 0; UInt32 numChannels = 0; OSStatus err; ... // get the size of the device layout err = QTGetMoviePropertyInfo(theMovie, kQTPropertyClass_Audio, kQTAudioPropertyID_DeviceChannelLayout, NULL, &size, NULL); if (err || (0 == size)) goto bail; // allocate memory for the device layout layout = (AudioChannelLayout*)calloc(1, size); if (NULL == layout) { err = memFullErr; goto bail; } // get the device layout from the movie err = QTGetMovieProperty(theMovie, kQTPropertyClass_Audio, kQTAudioPropertyID_DeviceChannelLayout, size, layout, NULL); if (err) goto bail; // now get the number of channels numChannels = (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) ? layout->mNumberChannelDescriptions : AudioChannelLayoutTag_GetNumberOfChannels(layout->mChannelLayoutTag); free(layout); ... ReferencesMovie Audio Mixes Three constants define the mix of audio channels for frequency metering: kQTAudioMeter_StereoMix - Meter a stereo (two-channel) mix of the enabled sound tracks in the movie. kQTAudioMeter_MonoMix - Meter the movie as if it had been mixed to monaural. kQTAudioMeter_DeviceMix - Meter the movie’s mix to the AudioChannelLayout of the device the movie is playing to. Document Revision History
Posted: 2009-01-29 |
|