precise timing control of double-buffering flip
- From: Fabrice Pardo <Fabrice Pardo Lpn cnrs fr>
- To: gtk-list gnome org
- Subject: precise timing control of double-buffering flip
- Date: Mon, 11 Dec 2006 12:22:16 +0100
Hello,
I'm searching a way to ask the time of double-buffering flip.
In order to make a kind of oscilloscope.
At any time t_now, I can access data corresponding to time values before
t_last, where (t_now - t_last) is always < tau_delay_1
I want to draw points using gdk_draw_points
and I know that I can compute them in a time less than tau_delay_2.
Then at time t_now, I want to:
1) compute and draw points using data at time (t_now - tau_delay_1). I
know to do that
2) see the resulting image at time t_now + tau_delay_2. I don't know
to do that. Please can you help me.
The following program should show a sinusoidal line slowly scrolling to
the left.
It works, but it suffer a small jitter due to the lack of timing control
around
gdk_window_process_updates i think.
Also, if the system becomes heavy loaded, the image freeze (this is normal
if tau_delay_2 has a too small value),
and then all the successive images are shown in an accelerated way
I would prefer that out of time images will be not shown.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gtk/gtk.h>
#define NPOINTS 800
#define NSAMP 2000 /* > NPOINTS + tau_sync/tau_samp */
GTimer *timer;
GdkPoint points[NPOINTS];
struct meas {
double samp[NSAMP];
double t_samp;
} data;
double tau_samp = 1.0/44100.0;
double f_sound = 440.1;
double tau_sync = 1.0/440.0;
double min_samp_delay = 1e99;
double max_samp_delay = 0.0;
double max_draw_delay = 0.0;
double timer_elapsed () {
ulong dummy;
return g_timer_elapsed (timer, &dummy);
}
gboolean sample_generator () {
int i;
data.t_samp = timer_elapsed ();
double delay;
for (i=0; i<NSAMP; i++) {
data.samp[i] = 50.0 * sin (2.0 * M_PI * fmod (f_sound * (data.t_samp
- (NSAMP - 1 - i)*tau_samp), 1.0));
}
delay = timer_elapsed () - data.t_samp;
if (delay > max_samp_delay) max_samp_delay = delay;
if (delay < min_samp_delay) min_samp_delay = delay;
return TRUE;
}
double compute_points () {
double t = timer_elapsed ();
double dt;
int i, ishift;
dt = data.t_samp - tau_sync * floor (t / tau_sync);
while (dt < 0.0) dt += tau_sync;
ishift = NSAMP - NPOINTS - (int) (dt / tau_samp);
if (NPOINTS + ishift > NSAMP) {
fprintf (stderr, "NSAMP too low\n");
abort ();
}
for (i = 0; i < NPOINTS; i++) {
points[i].x = i;
points[i].y = 75 + (int) data.samp[i + ishift];
}
return t;
}
gboolean draw_callback (GtkWidget *widget, GdkEventExpose *event,
gpointer data) {
gdk_draw_points(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
points, NPOINTS);
return TRUE;
}
gboolean recompute_points(gpointer pDrawingArea) {
GtkWidget *widget;
GdkRegion *region;
double t, delay;
widget = GTK_WIDGET (pDrawingArea);
if (!widget->window) return;
region = gdk_drawable_get_clip_region (widget->window);
gdk_window_invalidate_region (widget->window, region, TRUE);
t = compute_points ();
gdk_window_process_updates (widget->window, TRUE);
delay = timer_elapsed () - t;
if (delay > max_draw_delay) max_draw_delay = delay;
return TRUE;
}
gboolean bye () {
fprintf (stderr, "Min. samp delay = %.6lf\n", min_samp_delay);
fprintf (stderr, "Max. samp delay = %.6lf\n", max_samp_delay);
fprintf (stderr, "Max. draw delay = %.6lf\n", max_draw_delay);
gtk_main_quit ();
return TRUE;
}
int main(int argc, char **argv) {
GtkWidget *pWindow;
GtkWidget *pDrawingArea;
gtk_init(&argc,&argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(pWindow), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
pDrawingArea = gtk_drawing_area_new();
gtk_widget_set_size_request(pDrawingArea, 800,150);
g_signal_connect (G_OBJECT (pDrawingArea), "expose_event",
G_CALLBACK (draw_callback), NULL);
gtk_container_add(GTK_CONTAINER(pWindow), pDrawingArea);
timer = g_timer_new ();
sample_generator ();
compute_points ();
gtk_widget_show_all(pWindow);
g_timeout_add(50, recompute_points, (gpointer) pDrawingArea);
g_timeout_add(31, sample_generator, NULL);
g_timeout_add(10000, bye, NULL);
gtk_main();
return EXIT_SUCCESS;
}
--
FP
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]