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