Re: raw data extraction
Re: raw data extraction
- Subject: Re: raw data extraction
- From: Brad Ford <email@hidden>
- Date: Thu, 9 Oct 2008 15:23:01 -0700
On Oct 1, 2008, at 1:46 PM, Judith Suttrup wrote:
I am trying to get the raw audio data out of a two-channel quicktime
movie. These are the movie audio extraction properties.
format flags = 41
sample rate = 48000.000000
bytes/packet = 4
frames/packe = 1
bytes/frame = 4
channels/frame = 2
bits/channel = 32
Could someone please specify this format (float, int (signed,
unsigned)?)
See <CoreAudio/CoreAudioTypes.h>
format flags = 41 = 0x00000029 =
kAudioFormatFlagIsFloat |
kAudioFormatFlagIsPacked |
kAudioFormatFlagIsNonInterleaved;
So it's canonical.
Is the extraction below correct? When I am displaying the data in a
graph there seem to be lots of interferences.
error = MovieAudioExtractionBegin(soundToPlay, 0,
&extractionSessionRef);
error = MovieAudioExtractionGetProperty(extractionSessionRef,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof (asbd), &asbd, nil);
Why are you getting the extraction session's asbd property only to
whack it with your own values below?
Boolean allChannelsDicrete = TRUE;
error = MovieAudioExtractionSetProperty(extractionSessionRef,
kQTPropertyClass_MovieAudioExtraction_Movie,
kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete,
sizeof (Boolean), &allChannelsDicrete);
A word about the AllChannelsDiscrete property. MovieAudioExtraction's
default behavior is to produce a summary mix of the movie. E.g., if
you've got multiple stereo tracks in the movie, all the lefts will mix
together into one left channel, and all the rights will mix into one
right channel. When you set the AllChannelsDiscrete property to true,
you're telling movie audio extraction to do NO mixing. In other
words, if there are two stereo tracks in the source movie, setting
this property will give you 4 output channels (L,R,L,R).
asbd.mSampleRate = 48000;
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kLinearPCMFormatFlagIsNonInterleaved |
kLinearPCMFormatFlagIsPacked |
kLinearPCMFormatFlagIsFloat;
asbd.mBytesPerPacket = 4;
asbd.mFramesPerPacket = 1;
asbd.mBytesPerFrame = 4;
asbd.mChannelsPerFrame = 2;
asbd.mBitsPerChannel = 32;
error = MovieAudioExtractionSetProperty(extractionSessionRef,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof (asbd), &asbd);
If you're going to set AllChannelsDiscrete, you should not be setting
the output asbd. You should be GETTING the asbd, so you know what
movie audio extraction will produce. You can still ask mae to format
convert the audio for you, for instance, sample rate convert, or
convert from float to int, but you shouldn't change the number of
channels if you're using AllChannelsDiscrete mode.
float numFramesF = asbd.mSampleRate * ((float)
GetMovieDuration(soundToPlay) / (float)
GetMovieTimeScale(soundToPlay));
UInt32 numFrames = (UInt32) numFramesF;
UInt32 extractionFlags = 0;
This malloc you're doing is very specific to stereo. You can make it
more general by using the mChannelsPerFrame field.
AudioBufferList* abl = (AudioBufferList
*)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer));
abl->mNumberBuffers = asbd.mChannelsPerFrame;
unsigned i;
for(i = 0; i < abl->mNumberBuffers; i++) {
abl->mBuffers[i].mNumberChannels = 1;
You're making your mDataByteSize too big. It would only need to be
asbd.mBytesPerFrame * numFrames;
But what you're doing is allocating a buffer big enough to extract the
ENTIRE source movie in one go. That's extremely inefficient.
Depending how big the source is, your malloc might fail. The typical
use of movie audio extraction is to extract small bits at a time, say
a few seconds worth, not the whole source.
-Brad Ford
QuickTime Engineering
abl->mBuffers[i].mDataByteSize = sizeof(Float32) * abl-
>mBuffers[0].mNumberChannels * numFrames;
abl->mBuffers[i].mData = malloc(abl->mBuffers[i].mDataByteSize);
}
[self setSampleCount: numFrames / 2];
[self setSamples:calloc(abl->mBuffers[0].mDataByteSize, 1)];
abl->mBuffers[0].mData =
samples; /
samples is a *Byte (wont display any data when set up as a *Float)
[self setSecSampleCount: numFrames / 2];
[self setSecSamples:calloc(abl->mBuffers[1].mDataByteSize, 1)];
abl->mBuffers[1].mData =
secSamples; /
secSamples is a *Byte
error = MovieAudioExtractionFillBuffer(extractionSessionRef,
&numFrames, abl, &extractionFlags);
error = MovieAudioExtractionEnd(extractionSessionRef);
Thanks,
Judith Suttrup
____________________________________________________________________
Psssst! Schon vom neuen WEB.DE MultiMessenger gehört?
Der kann`s mit allen: http://www.produkte.web.de/messenger/?did=3123
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden