[ardour-dev] smpte drop patch

nick mainsbridge beatroot at optushome.com.au
Mon Mar 1 05:53:50 PST 2004


i hope this is ok..
should speed up the smpte calculations, and adds drop frames if its set.
-- 
nick mainsbridge <beatroot at optushome.com.au>
-------------- next part --------------
--- ../../../Desktop/ardour-0.9beta11.2/libs/ardour/session_time.cc	Mon Mar  1 10:33:56 2004
+++ libs/ardour/session_time.cc	Tue Mar  2 00:39:04 2004
@@ -69,6 +69,9 @@
         long mins;
         long secs;
         long frames;
+	long fps_int;
+                                                                                                                   
+        fps_int = (int)rint(smpte_frames_per_second);
                                                                                                                    
         if (when < _smpte_offset) {
                 offset_sample = (_smpte_offset - when);
@@ -79,14 +82,62 @@
         }
 
 	left = offset_sample;
-        hrs = (int) floor (left / (frame_rate() * 60.0f * 60.0f));
-        left -= (jack_nframes_t) floor (hrs * frame_rate() * 60.0f * 60.0f);
-        mins = (int) floor (left / (frame_rate() * 60.0f));
-        left -= (jack_nframes_t) floor (mins * frame_rate() * 60.0f);
-        secs = (int) floor (left / frame_rate() * 1.0f);
-        left -= (jack_nframes_t) floor (secs * frame_rate() * 1.0f);
-        frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
-                                                                                                                   
+        hrs = left / (frame_rate() * 60 * 60);
+        left -= hrs * frame_rate() * 60 * 60;
+        mins = left / (frame_rate() * 60);
+        left -= mins * frame_rate() * 60;
+        secs = left / frame_rate();
+        left -= secs * frame_rate();
+	/* if we're using an integral smpte frame rate */
+	if (fps_int == smpte_frames_per_second) {
+		frames = (left / (frame_rate() / fps_int));
+	} else {
+
+	/* we're now using the NTSC frame rate.
+	From AES11-2003 section 4.5 video referencing (on page 6);
+		48 kHz   NTSC 5 frames = 8008 samples,
+		44.1 kHz NTSC 100 frames = 147147 samples
+	..so NTSC has a frame rate of 29.97002997 exactly.
+	anyway, because of this, some NTSC frames will have a different number of samples in them to
+	others. this is a real bummer as far as the SMPTE ruler is concerned.	*/
+
+		if (frame_rate() % 48000 == 0) {
+			frames = (left * 5) / 8008;
+		} else if (frame_rate() % 44100 == 0) {
+			frames = (left * 100) / 147147;
+		} else {
+			frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
+		}
+	} 
+	if (smpte_drop_frames) {
+
+		long extra_frames = 0;
+		long i;
+		long total_minutes = 0;
+
+		total_minutes = mins + (hrs * 60);
+		extra_frames = (2 * total_minutes) - (2 * (total_minutes / 10));
+		for (i = 1; i <= extra_frames; i++ ) {
+			frames += 1;
+			if (frames > (fps_int - 1)) {
+                        	secs += frames / fps_int;
+                        	frames -= (fps_int * (frames / fps_int));
+                	}
+	                if (secs > 59) {
+	                        mins += 1;
+	                        secs -= 60;
+				if (!(mins % 10) == 0) {
+					extra_frames += 2; // dropped frames from our extra frames
+				}
+	                }
+	                if (mins > 59) {
+	                        hrs += 1;
+	                        mins -= 60;
+	                }
+		}		
+	}
+		
+			
         smpte.frames = frames;
         smpte.seconds = secs;
         smpte.minutes = mins;
@@ -112,6 +163,9 @@
         long secs;
         long frames;
 	long subframes;
+	long fps_int;
+                                                                                                                   
+        fps_int = (int)rint(smpte_frames_per_second);
                                                                                                                    
         if (when < _smpte_offset) {
                 offset_sample = (_smpte_offset - when);
@@ -122,16 +176,60 @@
         }
                                                                                                                    
         left = offset_sample;
-        hrs = (int) floor (left / (frame_rate() * 60.0f * 60.0f));
-        left -= (jack_nframes_t) floor (hrs * frame_rate() * 60.0f * 60.0f);
-        mins = (int) floor (left / (frame_rate() * 60.0f));
-        left -= (jack_nframes_t) floor (mins * frame_rate() * 60.0f);
-        secs = (int) floor (left / frame_rate() * 1.0f);
-        left -= (jack_nframes_t) floor (secs * frame_rate() * 1.0f);
-        frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
-	left -= (jack_nframes_t) floor (frames * frame_rate() / smpte_frames_per_second);
-	/* eighty bits in a SMPTE frame */
-	subframes = (int) floor (left / (frame_rate() / (smpte_frames_per_second * 80)));
+        hrs = left / (frame_rate() * 60 * 60);
+        left -= hrs * frame_rate() * 60 * 60;
+        mins = left / (frame_rate() * 60);
+        left -= mins * frame_rate() * 60;
+        secs = left / frame_rate();
+        left -= secs * frame_rate();
+         /* if we're using an integral smpte frame rate */
+        if (fps_int == smpte_frames_per_second) {
+                frames = (left / (frame_rate() / fps_int));
+		left -= frames * (frame_rate() / fps_int); // half sample error @ 44100 24 fps
+		subframes = left / (frame_rate() / (fps_int * 80));
+        } else {
+
+                /* NTSC */                                                                                                   
+                if (frame_rate() % 48000 == 0) {
+                        frames = (left * 5) / 8008;
+			left -= (frames * 8008) / 5;
+                } else if (frame_rate() % 44100 == 0) {
+                        frames = (left * 100) / 147147;
+			left -= (frames * 147147) / 100;
+                } else {
+                        frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
+			left -= (jack_nframes_t) floor (frames * frame_rate() / smpte_frames_per_second);
+                }
+		 /* eighty bits in a SMPTE frame */
+        	subframes = (int) floor (left / (frame_rate() / (smpte_frames_per_second * 80)));
+        }
+	if (smpte_drop_frames) {
+                                                                                                                   
+                long extra_frames = 0;
+                long i;
+                long total_minutes = 0;
+                                                                                                                   
+                total_minutes = mins + (hrs * 60);
+                extra_frames = (2 * total_minutes) - (2 * (total_minutes / 10));
+                for (i = 1; i <= extra_frames; i++ ) {
+                        frames += 1;
+                        if (frames > (fps_int - 1)) {
+                                secs += frames / fps_int;
+                                frames -= (fps_int * (frames / fps_int));
+                        }
+                        if (secs > 59) {
+                                mins += 1;
+                                secs -= 60;
+                                if (!(mins % 10) == 0) {
+                                        extra_frames += 2; //add drop frames to our extra frames
+                                }
+                        }
+                        if (mins > 59) {
+                                hrs += 1;
+                                mins -= 60;
+                        }
+                }
+        }
 	
         smpte.subframes = subframes;
         smpte.frames = frames;
@@ -154,18 +252,66 @@
         long secs;
         long frames;
         long subframes;
+	long fps_int;
+                                                                                                                   
+        fps_int = (int)rint(smpte_frames_per_second);
 
 	left = when;
-        hrs = (int) floor (left / (frame_rate() * 60.0f * 60.0f));
-        left -= (jack_nframes_t) floor (hrs * frame_rate() * 60.0f * 60.0f);
-        mins = (int) floor (left / (frame_rate() * 60.0f));
-        left -= (jack_nframes_t) floor (mins * frame_rate() * 60.0f);
-        secs = (int) floor (left / frame_rate() * 1.0f);
-        left -= (jack_nframes_t) floor (secs * frame_rate() * 1.0f);
-        frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
-        left -= (jack_nframes_t) floor (frames * frame_rate() / smpte_frames_per_second);
-        /* eighty bits in a SMPTE frame */
-        subframes = (int) floor (left / (frame_rate() / (smpte_frames_per_second * 80)));
+        hrs = left / (frame_rate() * 60 * 60);
+        left -= hrs * frame_rate() * 60 * 60;
+        mins = left / (frame_rate() * 60);
+        left -= mins * frame_rate() * 60;
+        secs = left / frame_rate();
+        left -= secs * frame_rate();
+	 /* if we're using an integral smpte frame rate */
+        if (fps_int == smpte_frames_per_second) {
+                frames = (left / (frame_rate() / fps_int));
+		left -= frames * (frame_rate() / fps_int);
+		subframes = left / (frame_rate() / (fps_int * 80));
+        } else {
+                                                                                                                   
+        /* Never Twice the Same Colour */
+                                                                                                                   
+                if (frame_rate() % 48000 == 0) {
+                        frames = (left * 5) / 8008;
+                        left -= (frames * 8008) / 5;
+                } else if (frame_rate() % 44100 == 0) {
+                        frames = (left * 100) / 147147;
+                        left -= (frames * 147147) / 100;
+                } else {
+                        frames = (int) floor (left / (frame_rate() / smpte_frames_per_second));
+                        left -= (jack_nframes_t) floor (frames * frame_rate() / smpte_frames_per_second);
+                }
+                 /* eighty bits in a SMPTE frame */
+                subframes = (int) floor (left / (frame_rate() / (smpte_frames_per_second * 80)));
+        }
+	if (smpte_drop_frames) {
+                                                                                                                   
+                long extra_frames = 0;
+                long i;
+                long total_minutes = 0;
+                                                                                                                   
+                total_minutes = mins + (hrs * 60);
+                extra_frames = (2 * total_minutes) - (2 * (total_minutes / 10));
+                for (i = 1; i <= extra_frames; i++ ) {
+                        frames += 1;
+                        if (frames > (fps_int - 1)) {
+                                secs += frames / fps_int;
+                                frames -= (fps_int * (frames / fps_int));
+                        }
+                        if (secs > 59) {
+                                mins += 1;
+                                secs -= 60;
+                                if (!(mins % 10) == 0) {
+                                        extra_frames += 2; //add drop frames to our extra frames
+                                }
+                        }
+                        if (mins > 59) {
+                                hrs += 1;
+                                mins -= 60;
+                        }
+                }
+        }
                                                                                                                    
         smpte.subframes = subframes;
         smpte.frames = frames;


More information about the Ardour-Dev mailing list