Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Solution to MovieAudioExtractionFillBuffer omits samples at end (QT 7)



The Problem:

At 3:39 PM -0700 6/21/06, Jim Prouty wrote:
>MovieAudioExtractionFillBuffer (QT 7.1 Mac and Win) is dropping a small
>number of audio samples from the ends of various files, including this one:
>
>ftp://ftp.wavemetrics.net/IgorPro/FilesUpdate/WMDevelopment/Mac/sound1024.aiff
>
>The file has exactly 1024 samples (mono, 16 bit, 8000 Hz sampling rate).
>
>MovieAudioExtractionFillBuffer extracts 1014 of them and sets
>kQTMovieAudioExtractionComplete. The last 10 samples are dropped.

My Solution:

Thanks to Daniel Steinberg and Edward Agabeg at Apple, I've written this
FixMovieDuration routine which works with simple audio files, and with
multi-track QuickTime movies like those from http://mixflix.com (which have
tracks with different media start times).

Usage:

Movie movie;
NewMovieFileFromPath(fullPathTofile, &movie);

FixMovieDuration(theMovie); // <<<<=== The Solution

MovieAudioExtractionRef extractionSessionRef;
MovieAudioExtractionBegin(movie, 0, &extractionSessionRef);

The code:

// QuickTime defaults an opened movie to 600 "movie units" per second
// and converts only the audio that fills each unit.
// (Movie units only partially filled with audio are discarded.)
//
// This routine makes the movie unit equal to the sample rate,
// so there can be no partially filled audio units.
//
// Based on correspondence with Edward Agabeg <email@hidden>
//
// NOTE: This CHANGES the movie (so it needs to be done only once).
//

struct _trackStartDuration {
	TimeValue movieTrackStart;		// in current movie time
(scale)
	TimeScale movieScale;
	TimeValue mediaDuration;
};
typedef struct _trackStartDuration TrackStartDuration, *TrackStartDurationPtr;

static double
FixMovieDuration(Movie theMovie)
{
	int i;
	TimeScale mediaScale, maxMediaScale= 0;
	SInt32 trackCount;
	Track theTrack;
	TimeValue movieDuration;
	TimeScale movieScale;
	double movieSeconds;
	TrackStartDurationPtr tsdP, tp;

	trackCount= GetMovieTrackCount(theMovie);
	tsdP=
(TrackStartDurationPtr)malloc(trackCount*sizeof(TrackStartDuration));
	if( tsdP == nil )
		return 0.0;

	// Delete all the edits in the track.
	// You can't remove the media, but you can remove the edits that
reference it.
	for (i = 1; i <= trackCount; i++) {
		theTrack= GetMovieIndTrackType(theMovie, i, SoundMediaType,
movieTrackMediaType);
		if (theTrack) {
			Media theMedia= GetTrackMedia(theTrack);

			tp= tsdP + (i-1);
			tp->movieTrackStart= GetTrackOffset(theTrack);
	// in current movie time
			tp->movieScale= GetMovieTimeScale(theMovie);
	// this is the movie time (until we change it)
			tp->mediaDuration= GetMediaDuration(theMedia);
			mediaScale= GetMediaTimeScale(theMedia);
			if( mediaScale > maxMediaScale )
				maxMediaScale= mediaScale;	// highest
sample rate becomes the movie's rate
			DeleteTrackSegment(theTrack, tp->movieTrackStart,
GetTrackDuration(theTrack));
		}
	}

	// Set the movie time scale to the highest audio rate in the movie
	SetMovieTimeScale(theMovie,maxMediaScale);

	// Insert the media into the track with the media duration
	for (i = 1; i <= trackCount; i++) {
		theTrack= GetMovieIndTrackType(theMovie, i, SoundMediaType,
movieTrackMediaType);
		if (theTrack) {
			TimeValue newTrackStart;	// in new movie time
			double startTimeSeconds;
			tp= tsdP + (i-1);
			startTimeSeconds= ((double)tp->movieTrackStart) /
(double)tp->movieScale; // samples / (samples/sec) = sec
			newTrackStart= floor(0.5 + startTimeSeconds *
(double)maxMediaScale);	// seconds * samples/sec = samples

			InsertMediaIntoTrack(theTrack, newTrackStart, 0,
tp->mediaDuration, 1<<16);
		}
	}

	// check the results
	movieDuration= GetMovieDuration(theMovie);	// samples
	movieScale= GetMovieTimeScale(theMovie);	// now set to the
audio rate (8000 Hz, for example)
	movieSeconds= ((double)movieDuration) / (double)movieScale;	//
movie units / movie units per second = seconds.

	free(tsdP);
	return movieSeconds;	// the "fixed" value.
}

-- 

Jim "How does it work?" Prouty

Voice: (503) 620-3001, FAX: (503) 620-6754
Makers of IGOR Pro, scientific data analysis and graphing for Mac and PC
http://www.wavemetrics.com
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
QuickTime-API mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quicktime-api/email@hidden

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.