static void animate_square(Square *sq)
{
   sq->cx += sq->dx;
   sq->cy += sq->dy;
   sq->size += sq->dsize;
   sq->rot += sq->drot;
   sq->life += sq->dlife;

   if (sq->size < 1.0 || sq->life > ALLEGRO_PI) {
      ALLEGRO_BITMAP *bmp = al_get_target_bitmap();
      gen_square(sq, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp));
   }
}
int process(unsigned nframes, void *v)
{
    (void) v;
    float seq_sqr[nframes];
    float seq_noise[nframes];
    float sqr[nframes];
    float noise[nframes];
    float lfo_f_out[nframes];
    float filter_in[nframes];
    float *output = (float*) jack_port_get_buffer(port, nframes);
	
    void *josc_buf = jack_port_get_buffer(josc, nframes);
    jack_midi_event_t in_event;
	jack_nframes_t event_count = jack_midi_get_event_count(josc_buf);
    // tag::buf-read[]
	if(event_count)
	{
		for(unsigned i=0; i<event_count; i++)
		{
			jack_midi_event_get(&in_event, josc_buf, i);
            assert(*in_event.buffer == '/');
            RtDataImpl d;
            ports.dispatch((char*)in_event.buffer+1, d);
		}
	}

    while(uToB.hasNext())
    {
        RtDataImpl d;
        d.matches = 0;
        ports.dispatch(uToB.read()+1, d);
        if(d.matches == 0)
            fprintf(stderr, "Unknown Port '%s'\n", uToB.peak());
    }
    // end::buf-read


    gen_seq(seq_sqr, seq_noise, &seq, nframes);
    gen_noise(noise, seq_noise, nframes);
    gen_square(sqr, seq_sqr, &osc, nframes);
    gen_lfo(lfo_f_out, &lfo, nframes);
    do_sum(filter_in, noise, sqr, nframes);
    do_filter(output, filter_in, lfo_f_out, &filter, nframes);
    return 0;
}
static void *thread_func(ALLEGRO_THREAD *thr, void *arg)
{
   const int INITIAL_WIDTH = 300;
   const int INITIAL_HEIGHT = 300;
   const Background *background = (Background *) arg;
   ALLEGRO_DISPLAY *display;
   ALLEGRO_EVENT_QUEUE *queue = NULL;
   ALLEGRO_TIMER *timer = NULL;
   ALLEGRO_EVENT event;
   ALLEGRO_STATE state;
   Square squares[MAX_SQUARES];
   double theta = 0.0;
   bool redraw = true;
   int i;

   (void)thr;

   al_set_new_display_flags(ALLEGRO_RESIZABLE);

   display = al_create_display(INITIAL_WIDTH, INITIAL_HEIGHT);
   if (!display) {
      goto Quit;
   }
   queue = al_create_event_queue();
   if (!queue) {
      goto Quit;
   }
   timer = al_create_timer(0.1);
   if (!timer) {
      goto Quit;
   }

   al_register_event_source(queue, al_get_display_event_source(display));
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_timer_event_source(timer));

   for (i = 0; i < MAX_SQUARES; i++) {
      gen_square(&squares[i], INITIAL_WIDTH, INITIAL_HEIGHT);
   }

   al_start_timer(timer);

   while (true) {
      if (al_is_event_queue_empty(queue) && redraw) {
         double r = 0.7 + 0.3 * (sin(theta) + 1.0) / 2.0;
         ALLEGRO_COLOR c = al_map_rgb_f(
            background->rmax * r,
            background->gmax * r,
            background->bmax * r
         );
         al_clear_to_color(c);

         al_store_state(&state, ALLEGRO_STATE_BLENDER | ALLEGRO_STATE_TRANSFORM);
         for (i = 0; i < MAX_SQUARES; i++) {
            draw_square(&squares[i]);
         }
         al_restore_state(&state);

         al_flip_display();
         redraw = false;
      }

      al_wait_for_event(queue, &event);
      if (event.type == ALLEGRO_EVENT_TIMER) {
         for (i = 0; i < MAX_SQUARES; i++) {
            animate_square(&squares[i]);
         }
         theta += 0.1;
         redraw = true;
      }
      else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }
      else if (event.type == ALLEGRO_EVENT_KEY_DOWN
            && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
         break;
      }
      else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
         al_acknowledge_resize(event.display.source);
      }
   }

Quit:

   if (timer) {
      al_destroy_timer(timer);
   }
   if (queue) {
      al_destroy_event_queue(queue);
   }
   if (display) {
      al_destroy_display(display);
   }

   return NULL;
}