Esempio n. 1
0
static int 
process_callback(jack_nframes_t nframes, void *notused)
{
#ifdef MEASURE_TIME
	if (get_delta_time() > MAX_TIME_BETWEEN_CALLBACKS) {
		warn_from_jack_thread_context("Had to wait too long for JACK callback; scheduling problem?");
	}
#endif

	/* Check for impossible condition that actually happened to me, caused by some problem between jackd and OSS4. */
	if (nframes <= 0) {
		warn_from_jack_thread_context("Process callback called with nframes = 0; bug in JACK?");
		return 0;
	}


	if (pthread_mutex_trylock(&mutex) == 0) {
		if ((smf = smf_vol) != NULL) {
			process_midi_output(nframes);
		}
		pthread_mutex_unlock(&mutex);
	}

#ifdef MEASURE_TIME
	if (get_delta_time() > MAX_PROCESSING_TIME) {
		warn_from_jack_thread_context("Processing took too long; scheduling problem?");
	}
#endif

	return 0;
}
Esempio n. 2
0
static void
send_all_sound_off(void *port_buffers[MAX_NUMBER_OF_TRACKS], jack_nframes_t nframes)
{
	int i, channel;
	unsigned char *buffer;

	for (i = 0; i <= smf->number_of_tracks; i++) {
		for (channel = 0; channel < 16; channel++) {
#ifdef JACK_MIDI_NEEDS_NFRAMES
			buffer = jack_midi_event_reserve(port_buffers[i], 0, 3, nframes);
#else
			buffer = jack_midi_event_reserve(port_buffers[i], 0, 3);
#endif
			if (buffer == NULL) {
				warn_from_jack_thread_context("jack_midi_event_reserve failed, cannot send All Sound Off.");
				break;
			}

			buffer[0] = MIDI_CONTROLLER | channel;
			buffer[1] = MIDI_ALL_SOUND_OFF;
			buffer[2] = 0;
		}

		if (just_one_output)
			break;
	}
}
Esempio n. 3
0
void
process_midi_input (jack_nframes_t nframes)
{
   static int time_of_first_event = -1;
   int /*read,*/ events, i, channel;
   jack_midi_event_t event;
   int last_frame_time = jack_last_frame_time(jack_client);
   void * port_buffer = jack_port_get_buffer(input_port, nframes);
   if (port_buffer == NULL)
   {
      warn_from_jack_thread_context
      (
         "jack_port_get_buffer failed, cannot receive anything."
      );
      return;
   }

#ifdef JACK_MIDI_NEEDS_NFRAMES
   events = jack_midi_get_event_count(port_buffer, nframes);
#else
   events = jack_midi_get_event_count(port_buffer);
#endif

   for (i = 0; i < events; ++i)
   {
      smf_event_t * smf_event;

#ifdef JACK_MIDI_NEEDS_NFRAMES
      int read = jack_midi_event_get(&event, port_buffer, i, nframes);
#else
      int read = jack_midi_event_get(&event, port_buffer, i);
#endif
      if (read) {
         warn_from_jack_thread_context("jack_midi_event_get failed, RECEIVED NOTE LOST.");
         continue;
      }
      if (event.buffer[0] >= 0xF8)              /* Ignore realtime messages. */
         continue;

      if (time_of_first_event == -1)            /* First event received? */
         time_of_first_event = last_frame_time + event.time;

      smf_event = smf_event_new_from_pointer(event.buffer, event.size);
      if (smf_event == NULL)
      {
         warn_from_jack_thread_context
         (
            "smf_event_from_pointer failed, RECEIVED NOTE LOST."
         );
         continue;
      }
//    assert(smf_event->midi_buffer_length >= 1);
      channel = smf_event->midi_buffer[0] & 0x0F;
      smf_track_add_event_seconds
      (
         tracks[channel], smf_event,
         nframes_to_seconds
         (
            jack_last_frame_time(jack_client) + event.time - time_of_first_event
         )
      );
   }
}
Esempio n. 4
0
static void
process_midi_output(jack_nframes_t nframes)
{
	int		i, t, bytes_remaining, track_number;
	unsigned char  *buffer, tmp_status;
	void		*port_buffers[MAX_NUMBER_OF_TRACKS];
	jack_nframes_t	last_frame_time;
	jack_transport_state_t transport_state;
	static jack_transport_state_t previous_transport_state = JackTransportStopped;
	static int previous_playback_started = -1;
	static int previous_playback_paused = 0;

	for (i = 0; i <= smf->number_of_tracks; i++) {
		port_buffers[i] = jack_port_get_buffer(output_ports[i], nframes);

		if (port_buffers[i] == NULL) {
			warn_from_jack_thread_context("jack_port_get_buffer failed, cannot send anything.");
			return;
		}

#ifdef JACK_MIDI_NEEDS_NFRAMES
		jack_midi_clear_buffer(port_buffers[i], nframes);
#else
		jack_midi_clear_buffer(port_buffers[i]);
#endif

		if (just_one_output)
			break;
	}

	if (ctrl_c_pressed) {
		send_all_sound_off(port_buffers, nframes);
		
		/* The idea here is to exit at the second time process_midi_output gets called.
		   Otherwise, All Sound Off won't be delivered. */
		ctrl_c_pressed++;
		if (ctrl_c_pressed >= 3)
			exit(0);

		return;
	}

	// g_debug("PROCESS CALLBACK!!!");

	if (playback_paused) {
		if (!previous_playback_paused) {
			send_all_sound_off(port_buffers, nframes);
		}
		previous_playback_paused = playback_paused;
		return;
	}
	previous_playback_paused = playback_paused;

	if (use_transport) {

		// if (!ready_to_roll) return;

		transport_state = jack_transport_query(jack_client, NULL);

		if (transport_state == JackTransportStopped) {
			if (previous_transport_state == JackTransportRolling) {
				send_all_sound_off(port_buffers, nframes);
			}
			playback_started = -1;
		}

		if (transport_state == JackTransportStarting) {
			playback_started = -1;
		}

		if (transport_state == JackTransportRolling) {
			if (previous_transport_state != JackTransportRolling) {
				jack_position_t position;
				jack_transport_query(jack_client, &position);
				song_position = position.frame;
				playback_started = jack_last_frame_time(jack_client);
			}
		}

		previous_transport_state = transport_state;
	}
	else {
		if (playback_started == -1) {
			if (previous_playback_started >= 0) {
				send_all_sound_off(port_buffers, nframes);
				send_sond_end();
			}
		}
		previous_playback_started = playback_started;
	}


	/* End of song already? */
	if (playback_started < 0)
		return;

	last_frame_time = jack_last_frame_time(jack_client);

	/* We may push at most one byte per 0.32ms to stay below 31.25 Kbaud limit. */
	bytes_remaining = nframes_to_ms(nframes) * rate_limit;

	double loop_offset = loop_song(smf);

	for (;;) {

		smf_event_t *event = smf_peek_next_event(smf);

		int end_of_song = 0;
		int is_meta_event = 0;

		if (event == NULL) {
			end_of_song = 1;
		}
		else if (smf_event_is_metadata(event)) {
			is_meta_event = 1;
			char *decoded = smf_event_decode(event);
			if (decoded) {
				if (!be_quiet)
					g_debug("Metadata: %s", decoded);
				end_of_song = process_meta_event(decoded);
				free(decoded);
			}
		}

		if (end_of_song) {
			if (!be_quiet)
				g_debug("End of song.");
			playback_started = -1;

			if (!use_transport)
				ctrl_c_pressed = 1;
			break;
		}

		if (is_meta_event) {
			smf_event_t *ret = smf_get_next_event(smf);
			assert(ret != 0);
			continue;
		}

		bytes_remaining -= event->midi_buffer_length;

		if (rate_limit > 0.0 && bytes_remaining <= 0) {
			warn_from_jack_thread_context("Rate limiting in effect.");
			break;
		}

		// t = seconds_to_nframes(event->time_seconds) + playback_started - song_position + nframes - last_frame_time;
		t = seconds_to_nframes(event->time_seconds + loop_offset) + playback_started - song_position - last_frame_time;

		/* If computed time is too much into the future, we'll need
		   to send it later. */
		if (t >= (int)nframes)
			break;

		/* If computed time is < 0, we missed a cycle because of xrun. */
		if (t < 0)
			t = 0;

		assert(event->track->track_number >= 0 && event->track->track_number <= MAX_NUMBER_OF_TRACKS);

		/* We will send this event; remove it from the queue. */
		smf_event_t *ret = smf_get_next_event(smf);
		assert(ret != 0);

		/* First, send it via midi_out. */
		track_number = 0;

#ifdef JACK_MIDI_NEEDS_NFRAMES
		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes);
#else
		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length);
#endif

		if (buffer == NULL) {
			warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST.");
			break;
		}

		memcpy(buffer, event->midi_buffer, event->midi_buffer_length);

		/* Ignore per-track outputs? */
		if (just_one_output)
			continue;

		/* Send it via proper output port. */
		track_number = event->track->track_number;

#ifdef JACK_MIDI_NEEDS_NFRAMES
		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes);
#else
		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length);
#endif

		if (buffer == NULL) {
			warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST.");
			break;
		}

		/* Before sending, reset channel to 0. XXX: Not very pretty. */
		assert(event->midi_buffer_length >= 1);

		tmp_status = event->midi_buffer[0];

		if (event->midi_buffer[0] >= 0x80 && event->midi_buffer[0] <= 0xEF)
			event->midi_buffer[0] &= 0xF0;

		memcpy(buffer, event->midi_buffer, event->midi_buffer_length);

		event->midi_buffer[0] = tmp_status;
	}
}