示例#1
0
文件: midiseq.c 项目: Andux/jack2
static int process(jack_nframes_t nframes, void *arg)
{
	int i,j;
	void* port_buf = jack_port_get_buffer(output_port, nframes);
	unsigned char* buffer;
	jack_midi_clear_buffer(port_buf);
	/*memset(buffer, 0, nframes*sizeof(jack_default_audio_sample_t));*/

	for(i=0; i<nframes; i++)
	{
		for(j=0; j<num_notes; j++)
		{
			if(note_starts[j] == loop_index)
			{
				buffer = jack_midi_event_reserve(port_buf, i, 3);
/*				printf("wrote a note on, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer);*/
				buffer[2] = 64;		/* velocity */
				buffer[1] = note_frqs[j];
				buffer[0] = 0x90;	/* note on */
			}
			else if(note_starts[j] + note_lengths[j] == loop_index)
			{
				buffer = jack_midi_event_reserve(port_buf, i, 3);
/*				printf("wrote a note off, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer);*/
				buffer[2] = 64;		/* velocity */
				buffer[1] = note_frqs[j];
				buffer[0] = 0x80;	/* note off */
			}
		}
		loop_index = loop_index+1 >= loop_nsamp ? 0 : loop_index+1;
	}
	return 0;
}
示例#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;
	}
}
示例#3
0
文件: keyer_ptt.c 项目: recri/keyer
static void _send(_t *dp, void *midi_out, jack_nframes_t t, unsigned char cmd, unsigned char note) {
  unsigned char midi[] = { cmd | (dp->opts.chan-1), note, 0 };
  unsigned char* buffer = jack_midi_event_reserve(midi_out, t, 3);
  if (buffer == NULL) {
    fprintf(stderr, "jack won't buffer 3 midi bytes!\n");
  } else {
    memcpy(buffer, midi, 3);
  }
}
示例#4
0
文件: lou.c 项目: seierstad/LouWiiGui
void note_on(struct note_t note, void* port_buf, int i) {
	unsigned char* buffer;
	buffer = jack_midi_event_reserve(port_buf, i, 3);
	buffer[2] = note.velocity;		/* velocity */
	buffer[1] = note.note_number;	/* note number */
	buffer[0] = MIDI_NOTE_ON + midi_channel;	/* note on */
	active_notes.note[active_notes.size] = note;
	active_notes.size++;
}
示例#5
0
MidiData* MidiBuffer::reserveEvent(int sample, size_t dataSize) {
    if(!isValid()) {
        return 0;
    }

    return jack_midi_event_reserve(
        _jackBuffer,
        (jack_nframes_t)sample,
        dataSize);
}
示例#6
0
文件: drumbox.c 项目: kspi/drumbox
void send_note(void *midi_out_buffer, jack_nframes_t ofs, float velocity) {
  jack_midi_data_t *midi_note =
    jack_midi_event_reserve(midi_out_buffer, 0, 3);

  midi_note[0] = 0x90;             /* noteon */
  midi_note[1] = note;             /* freq */
  midi_note[2] = MIN(127, (unsigned char) (velocity * 127)); /* velocity */

  DEBUG("sending note with velocity = %u\n", midi_note[2]);
}  
示例#7
0
文件: midi.c 项目: recri/keyer
static int _process(jack_nframes_t nframes, void *arg) {
  // process input events
  _t *data = (_t *)arg;
  framework_midi_event_init(&data->fw, NULL, nframes);
  /* for all frames in the buffer */
  for(int i = 0; i < nframes; i++) {
    /* process all midi events at this sample time */
    jack_midi_event_t event;
    int port;
    while (framework_midi_event_get(&data->fw, i, &event, &port)) {
      if (data->started && _writeable(data, event.size))
	_write(data, sdrkit_last_frame_time(arg)+i, event.size, event.buffer);
    }
  }

  // process output events
  _t *dp = (_t *)arg;
  void* midi_out = jack_port_get_buffer(framework_midi_output(dp,0), nframes);
  jack_midi_event_t event;

  // find out what there is to do
  framework_midi_event_init(&dp->fw, &dp->midi, nframes);

  // clear the jack output buffer
  jack_midi_clear_buffer(midi_out);

  // for each frame in this callback
  for(int i = 0; i < nframes; i += 1) {
    // process all midi output events at this sample frame
    int port;
    while (framework_midi_event_get(&dp->fw, i, &event, &port)) {
      if (event.size != 0) {
	unsigned char* buffer = jack_midi_event_reserve(midi_out, i, event.size);
	if (buffer == NULL) {
	  fprintf(stderr, "%s:%d: jack won't buffer %ld midi bytes!\n", __FILE__, __LINE__, (long)event.size);
	} else {
	  memcpy(buffer, event.buffer, event.size);
	  //fprintf(stderr, "midi_insert sent %x %x %x\n", buffer[0], buffer[1], buffer[2]);
	}
      }
    }
  }
  return 0;
}
示例#8
0
文件: lou.c 项目: seierstad/LouWiiGui
void mute(void *port_buf, int i) {
	unsigned char* buffer;

	int j;
	for(j=0; j < MAX_DELAYED_NOTES_COUNT; j++){
		if (delayed_notes[j].note.velocity != 0) {
			timer_delete(delayed_notes[j].timer);
		}
		delayed_notes[j].note.velocity = 0;
	}
	queued_notes.size = 0;
	while(active_notes.size > 0) {
		buffer = jack_midi_event_reserve(port_buf, i, 3);
		buffer[2] = active_notes.note[active_notes.size - 1].velocity;		/* velocity */
		buffer[1] = active_notes.note[active_notes.size - 1].note_number;	/* note number */
		buffer[0] = MIDI_NOTE_OFF + midi_channel;	/* note off */
		active_notes.size--;
	}
}
示例#9
0
/*
 * ============================ Input ==============================
 */
static
void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info)
{
	// process port->early_events
	alsa_midi_event_t ev;
	while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) {
		jack_midi_data_t* buf;
		int64_t time = ev.time - info->period_start;
		if (time < 0)
			time = 0;
		else if (time >= info->nframes)
			time = info->nframes - 1;
		buf = jack_midi_event_reserve(port->jack_buf, (jack_nframes_t)time, ev.size);
		if (buf)
			jack_ringbuffer_read(port->early_events, (char*)buf, ev.size);
		else
			jack_ringbuffer_read_advance(port->early_events, ev.size);
		debug_log("input: it's time for %d bytes at %lld", ev.size, time);
	}
}
示例#10
0
// Jack process callback
int jackProcessOut( jack_nframes_t nframes, void *arg )
{
  JackMidiData *data = (JackMidiData *) arg;
  jack_midi_data_t *midiData;
  int space;

  // Is port created?
  if ( data->port == NULL ) return 0;

  void *buff = jack_port_get_buffer( data->port, nframes );
  jack_midi_clear_buffer( buff );

  while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) {
    jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) );
    midiData = jack_midi_event_reserve( buff, 0, space );

    jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space );
  }

  return 0;
}
示例#11
0
bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
{
    if (!_out_client_jackport) // p3.3.55
        return false;
    void* pb = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55

    int frameOffset = audio->getFrameOffset();
    unsigned pos = audio->pos().frame();
    int ft = e.time() - frameOffset - pos;

    if (ft < 0)
        ft = 0;
    if (ft >= (int) segmentSize)
    {
        if(debugMsg)
            printf("MidiJackDevice::queueEvent: Event time:%d out of range. offset:%d ft:%d (seg=%d)\n", e.time(), frameOffset, ft, segmentSize);
        if (ft > (int) segmentSize)
            ft = segmentSize - 1;
    }

#ifdef JACK_MIDI_DEBUG
    printf("MidiJackDevice::queueEvent time:%d type:%d ch:%d A:%d B:%d\n", e.time(), e.type(), e.channel(), e.dataA(), e.dataB());
#endif

    switch (e.type())
    {
        case ME_NOTEON:
        case ME_NOTEOFF:
        case ME_POLYAFTER:
        case ME_CONTROLLER:
        case ME_PITCHBEND:
        {
#ifdef JACK_MIDI_DEBUG
            printf("MidiJackDevice::queueEvent note on/off polyafter controller or pitch\n");
#endif

            unsigned char* p = jack_midi_event_reserve(pb, ft, 3);
            if (p == 0)
            {
                #ifdef JACK_MIDI_DEBUG
                fprintf(stderr, "MidiJackDevice::queueEvent NOTE CONTROL PAT or PB: buffer overflow, stopping until next cycle\n");
                #endif
                return false;
            }
            p[0] = e.type() | e.channel();
            p[1] = e.dataA();
            p[2] = e.dataB();
        }
            break;

        case ME_PROGRAM:
        case ME_AFTERTOUCH:
        {
#ifdef JACK_MIDI_DEBUG
            printf("MidiJackDevice::queueEvent program or aftertouch\n");
#endif

            unsigned char* p = jack_midi_event_reserve(pb, ft, 2);
            if (p == 0)
            {
                #ifdef JACK_MIDI_DEBUG
                fprintf(stderr, "MidiJackDevice::queueEvent PROG or AT: buffer overflow, stopping until next cycle\n");
                #endif
                return false;
            }
            p[0] = e.type() | e.channel();
            p[1] = e.dataA();
        }
            break;
        case ME_SYSEX:
        {
#ifdef JACK_MIDI_DEBUG
            printf("MidiJackDevice::queueEvent sysex\n");
#endif

            const unsigned char* data = e.data();
            int len = e.len();
            unsigned char* p = jack_midi_event_reserve(pb, ft, len + 2);
            if (p == 0)
            {
                fprintf(stderr, "MidiJackDevice::queueEvent ME_SYSEX: buffer overflow, sysex too big, event lost\n");
                return true;
            }
            p[0] = 0xf0;
            p[len + 1] = 0xf7;
            memcpy(p + 1, data, len);
        }
            break;
        case ME_SONGPOS:
        case ME_CLOCK:
        case ME_START:
        case ME_CONTINUE:
        case ME_STOP:
            if(debugMsg)
                printf("MidiJackDevice::queueEvent: event type %x not supported\n", e.type());
            return true;
            break;
    }

    return true;
}
示例#12
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;
	}
}
示例#13
0
static int
a2j_process (jack_nframes_t nframes, void * arg)
{
	struct a2j* self = (struct a2j *) arg;
	struct a2j_stream * stream_ptr;
	int i;
	struct a2j_port ** port_ptr;
	struct a2j_port * port;

	if (g_freewheeling) {
		return 0;
	}

	self->cycle_start = jack_last_frame_time (self->jack_client);
	
	stream_ptr = &self->stream;
	a2j_add_ports (stream_ptr);
	
	// process ports
	
	for (i = 0 ; i < PORT_HASH_SIZE ; i++) {

		port_ptr = &stream_ptr->port_hash[i];

		while (*port_ptr != NULL) {

			struct a2j_alsa_midi_event ev;
			jack_nframes_t now;
			jack_nframes_t one_period;
			char *ev_buf;
				
			port = *port_ptr;
			
			if (port->is_dead) {
				if (jack_ringbuffer_write_space (self->port_del) >= sizeof(port_ptr)) {
				
					a2j_debug("jack: removed port %s", port->name);
					*port_ptr = port->next;
					jack_ringbuffer_write (self->port_del, (char*)&port, sizeof(port));
				} else {
					a2j_error ("port deletion lost - no space in event buffer!");
				}

				port_ptr = &port->next;
				continue;
			}

			port->jack_buf = jack_port_get_buffer(port->jack_port, nframes);
				
			/* grab data queued by the ALSA input thread and write it into the JACK
			   port buffer. it will delivered during the JACK period that this
			   function is called from.
			*/
				
			/* first clear the JACK port buffer in preparation for new data 
			 */
				
			// a2j_debug ("PORT: %s process input", jack_port_name (port->jack_port));
				
			jack_midi_clear_buffer (port->jack_buf);
				
			now = jack_frame_time (self->jack_client);
			one_period = jack_get_buffer_size (self->jack_client);
				
			while (jack_ringbuffer_peek (port->inbound_events, (char*)&ev, sizeof(ev) ) == sizeof(ev) ) {
					
				jack_midi_data_t* buf;
				jack_nframes_t offset;
					
				if (ev.time >= self->cycle_start) {
					break;
				}
					
				//jack_ringbuffer_read_advance (port->inbound_events, sizeof (ev));
				ev_buf = (char *) alloca( sizeof(ev) + ev.size );
					
				if (jack_ringbuffer_peek (port->inbound_events, ev_buf, sizeof(ev) + ev.size ) != sizeof(ev) + ev.size)
					break;
					
				offset = self->cycle_start - ev.time;
				if (offset > one_period) {
					/* from a previous cycle, somehow. cram it in at the front */
					offset = 0;
				} else {
					/* offset from start of the current cycle */
					offset = one_period - offset;
				}
					
				a2j_debug ("event at %d offset %d", ev.time, offset);
					
				/* make sure there is space for it */
					
				buf = jack_midi_event_reserve (port->jack_buf, offset, ev.size);
					
				if (buf) {
					/* grab the event */
					memcpy( buf, ev_buf + sizeof(ev), ev.size );
				} else {
					/* throw it away (no space) */
					a2j_error ("threw away MIDI event - not reserved at time %d", ev.time);
				}
				jack_ringbuffer_read_advance (port->inbound_events, sizeof(ev) + ev.size);
					
				a2j_debug("input on %s: sucked %d bytes from inbound at %d", jack_port_name (port->jack_port), ev.size, ev.time);
			}
			
			port_ptr = &port->next;
		}
	}

	return 0;
}
示例#14
0
文件: process.c 项目: amstan/guitar
int process(jack_nframes_t nframes, void *arg) {
    struct guitarseq *guitarseq = arg;
    if(!guitarseq) {
        fprintf(stderr, "No guitarseq instance!\n");
        return 1;
    }

    void* port_buf;
    jack_nframes_t now = jack_frame_time (guitarseq->jack_client);

    //Output
    port_buf = jack_port_get_buffer(guitarseq->out_port, nframes);
    jack_midi_clear_buffer(port_buf);
    while (1) {
        jack_nframes_t time;
        //TODO: Do a safer read, in case only part of the message is here
        if (!jack_ringbuffer_read (guitarseq->out_buffer, (char *)&time, sizeof(time))) {
            break;
        }

        // from the future?
        if (time >= now) {
            break;
        }

        // time it right
        jack_nframes_t offset = time - now + nframes - 1;

        // get the size of the event
        size_t size;
        jack_ringbuffer_read(guitarseq->out_buffer, (char *)&size, sizeof(size));

        INFO("out event at %u%+d size %zu\n", now, offset, size);

        if (offset > nframes)
            // from the past, somehow. cram it in at the front
            offset = 0;

        // proceed to giving it to jack
        jack_midi_data_t *buffer = jack_midi_event_reserve (port_buf, offset, size);
        if(buffer) {
            jack_ringbuffer_read(guitarseq->out_buffer, (char *)buffer, size);
        } else {
            // throw it away :( TODO: find more
            jack_ringbuffer_read_advance (guitarseq->out_buffer, size);
            ERROR("threw away MIDI event - no space reserved at time %u offset %d\n",time,offset);
        }
    }

    // 	Input
    port_buf = jack_port_get_buffer(guitarseq->in_port, nframes);
    jack_nframes_t event_count = jack_midi_get_event_count(port_buf);
    for(jack_nframes_t i=0; i<event_count; i++) {
        jack_midi_event_t in_event;
        jack_midi_event_get(&in_event, port_buf, i);

        //adds a note to the ringbuffer
        if (jack_ringbuffer_write_space(guitarseq->in_buffer) >= sizeof(in_event.time)+sizeof(in_event.size)+in_event.size) {
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.time, sizeof(in_event.time));
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.size, sizeof(in_event.size));
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)in_event.buffer, in_event.size);
        } else {
            ERROR("Couldn't write to ringbuffer at %u, %zu midi data bytes lost\n", in_event.time, in_event.size);
        }
    }

    return 0;
}
示例#15
0
// JACK specifics.
int qmidinetJackMidiDevice::process ( jack_nframes_t nframes )
{
	jack_nframes_t buffer_size = jack_get_buffer_size(m_pJackClient);

	m_last_frame_time  = jack_last_frame_time(m_pJackClient);

	// Enqueue/dequeue events
	// to/from ring-buffers...
	for (int i = 0; i < m_nports; ++i) {

		if (m_ppJackPortIn && m_ppJackPortIn[i] && m_pJackBufferIn) {
			void *pvBufferIn
				= jack_port_get_buffer(m_ppJackPortIn[i], nframes);
			const int nevents = jack_midi_get_event_count(pvBufferIn);
			const unsigned int nlimit
				= jack_ringbuffer_write_space(m_pJackBufferIn);
			unsigned char  achBuffer[nlimit];
			unsigned char *pchBuffer = &achBuffer[0];
			unsigned int nwrite = 0;
			for (int n = 0; n < nevents; ++n) {
				if (nwrite + sizeof(qmidinetJackMidiEvent) >= nlimit)
					break;
				qmidinetJackMidiEvent *pJackEventIn
					= (struct qmidinetJackMidiEvent *) pchBuffer;
				jack_midi_event_get(&pJackEventIn->event, pvBufferIn, n);
				if (nwrite + sizeof(qmidinetJackMidiEvent)
					+ pJackEventIn->event.size >= nlimit)
					break;
				pJackEventIn->port = i;
				pchBuffer += sizeof(qmidinetJackMidiEvent);
				nwrite += sizeof(qmidinetJackMidiEvent);
				::memcpy(pchBuffer,
					pJackEventIn->event.buffer, pJackEventIn->event.size);
				pchBuffer += pJackEventIn->event.size;
				nwrite += pJackEventIn->event.size;
			}
			if (nwrite > 0) {
				jack_ringbuffer_write(m_pJackBufferIn,
					(const char *) achBuffer, nwrite);
			}
		}
	
		if (m_ppJackPortOut && m_ppJackPortOut[i] && m_pJackBufferOut) {
			void *pvBufferOut
				= jack_port_get_buffer(m_ppJackPortOut[i], nframes);
			jack_midi_clear_buffer(pvBufferOut);
			const unsigned int nlimit
				= jack_midi_max_event_size(pvBufferOut);
			unsigned int nread = 0;
			qmidinetJackMidiEvent ev;
			while (jack_ringbuffer_peek(m_pJackBufferOut,
					(char *) &ev, sizeof(ev)) == sizeof(ev)
					&& nread < nlimit) {
				if (ev.port != i)
					break;
				if (ev.event.time > m_last_frame_time)
					break;
				jack_nframes_t offset = m_last_frame_time - ev.event.time;
				if (offset > buffer_size)
					offset = 0;
				else
					offset = buffer_size - offset;
				jack_ringbuffer_read_advance(m_pJackBufferOut, sizeof(ev));
				jack_midi_data_t *pMidiData
					= jack_midi_event_reserve(pvBufferOut, offset, ev.event.size);
				if (pMidiData)
					jack_ringbuffer_read(m_pJackBufferOut,
						(char *) pMidiData, ev.event.size);
				else
				jack_ringbuffer_read_advance(m_pJackBufferOut, ev.event.size);
				nread += ev.event.size;
			}
		}
	}

	if (m_pJackBufferIn
		&& jack_ringbuffer_read_space(m_pJackBufferIn) > 0)
		m_pRecvThread->sync();

	return 0;
}
示例#16
0
文件: main.c 项目: dbkaplun/mictomidi
void toggle_midi_event(void *out, int frame, midi_event_t *midi_event, float volume) {
	unsigned char* buffer = jack_midi_event_reserve(out, frame, 3);
	buffer[0] = 0x80 | ((midi_event->playing = !midi_event->playing) << 4) | (midi_event->channel & 0xF); // On this channel, set on or off this
	buffer[1] = midi_event->note; // note,
	buffer[2] = 0x7F * (analog ? volume : 1); // played at this velocity.
}
示例#17
0
static int
handle_process(jack_nframes_t frames, void *arg)
{
    jack_midi_data_t *buffer;
    jack_midi_event_t event;
    jack_nframes_t event_count;
    jack_nframes_t event_time;
    jack_nframes_t frame;
    size_t i;
    jack_nframes_t last_frame_time;
    jack_midi_data_t *message;
    jack_time_t microseconds;
    void *port_buffer;
    jack_time_t time;
    jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames));
    switch (process_state) {

    case 0:
        /* State: initializing */
        switch (wait_semaphore(init_semaphore, 0)) {
        case -1:
            set_process_error(SOURCE_WAIT_SEMAPHORE, get_semaphore_error());
            /* Fallthrough on purpose */
        case 0:
            return 0;
        }
        highest_latency = 0;
        lowest_latency = 0;
        messages_received = 0;
        messages_sent = 0;
        process_state = 1;
        total_latency = 0;
        total_latency_time = 0;
        unexpected_messages = 0;
        xrun_count = 0;
        jack_port_get_latency_range(remote_in_port, JackCaptureLatency,
                                    &in_latency_range);
        jack_port_get_latency_range(remote_out_port, JackPlaybackLatency,
                                    &out_latency_range);
        goto send_message;

    case 1:
        /* State: processing */
        port_buffer = jack_port_get_buffer(in_port, frames);
        event_count = jack_midi_get_event_count(port_buffer);
        last_frame_time = jack_last_frame_time(client);
        for (i = 0; i < event_count; i++) {
            jack_midi_event_get(&event, port_buffer, i);
            message = (messages_received % 2) ? message_2 : message_1;
            if ((event.size == message_size) &&
                (! memcmp(message, event.buffer,
                          message_size * sizeof(jack_midi_data_t)))) {
                goto found_message;
            }
            unexpected_messages++;
        }
        microseconds = jack_frames_to_time(client, last_frame_time) -
            last_activity_time;
        if ((microseconds / 1000000) >= timeout) {
            set_process_error(SOURCE_PROCESS, ERROR_MSG_TIMEOUT);
        }
        break;
    found_message:
        event_time = last_frame_time + event.time;
        frame = event_time - last_activity;
        time = jack_frames_to_time(client, event_time) - last_activity_time;
        if ((! highest_latency) || (frame > highest_latency)) {
            highest_latency = frame;
            highest_latency_time = time;
        }
        if ((! lowest_latency) || (frame < lowest_latency)) {
            lowest_latency = frame;
            lowest_latency_time = time;
        }
        latency_time_values[messages_received] = time;
        latency_values[messages_received] = frame;
        total_latency += frame;
        total_latency_time += time;
        messages_received++;
        if (messages_received == samples) {
            process_state = 2;
            if (! signal_semaphore(process_semaphore)) {
                /* Sigh ... */
                die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error());
            }
            break;
        }
    send_message:
        frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames);
        if (frame >= frames) {
            frame = frames - 1;
        }
        port_buffer = jack_port_get_buffer(out_port, frames);
        buffer = jack_midi_event_reserve(port_buffer, frame, message_size);
        if (buffer == NULL) {
            set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE);
            break;
        }
        message = (messages_sent % 2) ? message_2 : message_1;
        memcpy(buffer, message, message_size * sizeof(jack_midi_data_t));
        last_activity = jack_last_frame_time(client) + frame;
        last_activity_time = jack_frames_to_time(client, last_activity);
        messages_sent++;

    case 2:
        /* State: finished - do nothing */
    case -1:
        /* State: error - do nothing */
    case -2:
        /* State: signalled - do nothing */
        ;
    }
    return 0;
}
示例#18
0
static int process_callback(jack_nframes_t nframes, void *arg)
{
    int i, ax, axis_note, axis_velocity;
    void* port_buffer = jack_port_get_buffer(output_port, nframes);
    unsigned char* buffer;
    unsigned char axis_playing[24];
    jack_midi_clear_buffer(port_buffer);

    for (i=0; i<nframes; i++)
    {
        for (ax=0; ax<20; ax++)
        {

            if (!isPoly)
            {
              buffer = jack_midi_event_reserve(port_buffer, i, 3);
              buffer[2] = 0x00; //as much poly as the host can get
              buffer[1] = 0x7F; //enable poly
              buffer[0] = 0xB0; //control mode
              isPoly = 1;
              if (debug) printf("Polyphonic mode enabled\n");
            }

            if (black_keys)
            {
              if (ax==0) axis_note = -2; //dummy
              else if (ax==1) axis_note = 0x02; //leftY (Modulation)
              else if (ax==2) axis_note = 0x0A; //rightH (Pan)
              else if (ax==3) axis_note = -2; //dummy
              else if (ax==4) axis_note = 0x10; //Acc X (Misc 1) 0x10
              else if (ax==5) axis_note = 0x11; //Acc Y (Misc 2) 0x11
              else if (ax==6) axis_note = 0x12; //Acc Z (Misc 3) 0x12
              else if (ax==7) axis_note = -2; //gyro (doesn't work)
              else if (ax==8) axis_note = 61+(12*oct);  //up
              else if (ax==9) axis_note = 62+(12*oct);  //right
              else if (ax==10) axis_note = 63+(12*oct); //down
              else if (ax==11) axis_note = 60+(12*oct); //left
              else if (ax==12) axis_note = 65+(12*oct); //l2
              else if (ax==13) axis_note = 66+(12*oct); //r2
              else if (ax==14) axis_note = 64+(12*oct); //l1
              else if (ax==15) axis_note = 67+(12*oct); //r1
              else if (ax==16) axis_note = 69+(12*oct); //triangle
              else if (ax==17) axis_note = 70+(12*oct); //circle
              else if (ax==18) axis_note = 71+(12*oct); //cross
              else if (ax==19) axis_note = 68+(12*oct); //square
            }
            else
            {
              if (ax==0) axis_note = -2; //dummy
              else if (ax==1) axis_note = 0x02; //leftY (Modulation)
              else if (ax==2) axis_note = 0x0A; //rightH (Pan)
              else if (ax==3) axis_note = -2; //dummy
              else if (ax==4) axis_note = 0x10; //Acc X (Misc 1) 0x10
              else if (ax==5) axis_note = 0x11; //Acc Y (Misc 2) 0x11
              else if (ax==6) axis_note = 0x12; //Acc Z (Misc 3) 0x12
              else if (ax==7) axis_note = -2; //gyro (doesn't work)
              else if (ax==8) axis_note = 62+(12*oct);  //up
              else if (ax==9) axis_note = 64+(12*oct);  //right
              else if (ax==10) axis_note = 65+(12*oct); //down
              else if (ax==11) axis_note = 60+(12*oct); //left
              else if (ax==12) axis_note = 69+(12*oct); //l2
              else if (ax==13) axis_note = 71+(12*oct); //r2
              else if (ax==14) axis_note = 67+(12*oct); //l1
              else if (ax==15) axis_note = 72+(12*oct); //r1
              else if (ax==16) axis_note = 76+(12*oct); //triangle
              else if (ax==17) axis_note = 77+(12*oct); //circle
              else if (ax==18) axis_note = 79+(12*oct); //cross
              else if (ax==19) axis_note = 74+(12*oct); //square
            }

            if (ax==1)
              axis_velocity = abs(axis[ax]/0xff) - 1; // modulation
            else if (ax==2)
              axis_velocity = ((axis[ax]/0xff)/2) + 63; // pan
            else if (ax<7)
              axis_velocity = ((axis[ax]/0xff)/2) + 63; // other controls
            else if (ax>=8 && ax<=19) { // keys
              axis_velocity = (axis[ax]/0xff) - 1;
              if (axis_velocity > 0) {
                axis_velocity = axis_velocity*(6.0-logf(axis_velocity));
                if (axis_velocity < 0)
                  axis_velocity = 0;
                else if (axis_velocity > 127)
                  axis_velocity = 127;
              }
            } else
              axis_velocity = (axis[ax]/0xff) - 1; // all the others

            if (axis_velocity == -1) axis_velocity = 0;

            if (axis[ax])
                axis_playing[ax] = 1;
            else
                axis_playing[ax] = 0;

            if (axis_prev_action[ax] != axis_playing[ax])
            {
                axis_is_checked[ax] = 0;
            }

            if (!axis_is_checked[ax])
            {

                if (axis_playing[ax])
                {
                    buffer = jack_midi_event_reserve(port_buffer, i, 3);
                    buffer[2] = axis_velocity;
                    buffer[1] = axis_note;
                    if (ax>7)
                      buffer[0] = 0x90; //note-on
                    else
                      buffer[0] = 0xB0; //control/mode
                    axis_prev_action[ax] = 1;
                    if (debug && (ax<4 || ax>7) && axis_note>0) printf("PLAY: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]);
                }
                else
                {
                    buffer = jack_midi_event_reserve(port_buffer, i, 3);
                    buffer[2] = axis_velocity;
                    buffer[1] = axis_note;
                    if (ax>7)
                      buffer[0] = 0x80;//note-off
                    else
                      buffer[0] = 0xB0; //control/mode
                    axis_prev_action[ax] = 0;
                    if (debug && (ax<4 || ax>7) && axis_note>0) printf("STOP: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]);
                }
                axis_is_checked[ax] = 1;
            }
            else if (axis_prev_velocity[ax] != axis[ax])
            {
                buffer = jack_midi_event_reserve(port_buffer, i, 3);
                buffer[2] = axis_velocity;
                buffer[1] = axis_note;
                if (ax>7)
                    buffer[0] = 0xA0; //aftertouch
                else
                    buffer[0] = 0xB0; //control/mode
                if (debug && (ax<4 || ax>7) && axis_note>0) printf("CTRL: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]);
            }

            axis_prev_velocity[ax] = axis[ax];
        }
    }

    return 0;
}
示例#19
0
文件: lou.c 项目: seierstad/LouWiiGui
int process(jack_nframes_t nframes, void *arg) {
	int i,j;
	void* port_buf = jack_port_get_buffer(output_port, nframes);
	unsigned char* buffer;
	jack_midi_clear_buffer(port_buf);

	for(i = 0; i < nframes; i++) {
		while(queued_notes.size > 0) {
			note_on(queued_notes.note[queued_notes.size - 1], port_buf, i);
			queued_notes.size--;
		}
		if (strummer_action != STRUMMER_ACTION_NONE) {
			if (strummer_action == STRUMMER_ACTION_MID_DOWN || strummer_action == STRUMMER_ACTION_MID_UP) {
				strum_chord(chord[chord_state], port_buf, i);
				strummer_action = STRUMMER_ACTION_NONE;
			}
			else {
				if (strummer_state != STRUMMER_STATE_SUSTAINED) {
					mute(port_buf, i);
					strummer_action = STRUMMER_ACTION_NONE;
				}
			}
		}
		if (whammy_action != WHAMMY_ACTION_NONE) {
			buffer = jack_midi_event_reserve(port_buf, i, 3);
			unsigned int pitch_shift = (MIDI_PITCH_CENTER * whammy_state) / CWIID_GUITAR_WHAMMY_MAX ;
			unsigned int pitch_value = MIDI_PITCH_CENTER - pitch_shift;
			buffer[2] = (pitch_value & 0x3F80) >> 7;  // most significant bits
			buffer[1] = pitch_value & 0x007f;         // least significant bits
			buffer[0] = MIDI_PITCH_WHEEL + midi_channel;	// pitch wheel change 
			printf("whammy! %x, %x, %x, desimalt: %d\n", buffer[0], buffer[2], buffer[1], pitch_value);
			whammy_action = WHAMMY_ACTION_NONE;
		}
		if (touchbar_action != TOUCHBAR_ACTION_NONE) {
			buffer = jack_midi_event_reserve(port_buf, i, 3);

			// scale input to output values (5th represents maximum possible input value)
			unsigned int modulation = (MIDI_MODULATION_MAX * touchbar_state) / CWIID_GUITAR_TOUCHBAR_5TH ; 
			printf("touchbar action! %d, %x, sent %x\n", touchbar_action, touchbar_state, modulation);
			buffer[2] = modulation;
			buffer[1] = 0x1;        // modulation
			buffer[0] = MIDI_CONTROL_CHANGE + midi_channel;	// control change 
			touchbar_action = TOUCHBAR_ACTION_NONE;
		}
		if (stick_action != STICK_ACTION_NONE) {
			printf("stick_action!\n");
			unsigned int volume = last_sent_volume_value;
			if (stick_action == STICK_ACTION_ROTATE_COUNTER_CLOCKWISE) {
				volume += stick_zone_average_value / 2 ;
				if (volume > 127) {
					volume = 127; 
				}
			}
			else if (stick_action == STICK_ACTION_ROTATE_CLOCKWISE) {
				if (volume >= stick_zone_average_value / 2) {
					volume -= stick_zone_average_value / 2;
				} else {
					volume = 0;
				}
			}
			if (volume != last_sent_volume_value) {
				printf("volume: %d\n", volume);
				buffer = jack_midi_event_reserve(port_buf, i, 3);
				buffer[2] = volume;
				buffer[1] = 0x7;        // volume
				buffer[0] = MIDI_CONTROL_CHANGE + midi_channel;	// control change
				last_sent_volume_value = volume;
			}
			stick_action = STICK_ACTION_NONE;
		}
		while (drums_action != 0) {
			uint8_t send_note_off = 0;
			buffer = jack_midi_event_reserve(port_buf, i, 3);
			buffer[2] = 0x7F;		/* velocity */
			if ((drums_action & RED) == RED) {
/*				if ((drums_state & RED) == RED) {
					send_note_off = 1;
				}
				drums_state ^= RED;
*/
				buffer[1] = 38;	/* note number */
				drums_action &= ~RED;
			} else if ((drums_action & YELLOW) == YELLOW) {
/*				if ((drums_state & YELLOW) == YELLOW) {
					send_note_off = 1;
				}
				drums_state ^= YELLOW;
*/
				buffer[1] = 42;	/* note number */
				drums_action &= ~YELLOW;
			} else if ((drums_action & BLUE) == BLUE) {
/*				if ((drums_state & BLUE) == BLUE) {
					send_note_off = 1;
				}
				drums_state ^= BLUE;
*/
				buffer[1] = 48;	/* note number */
				drums_action &= ~BLUE;
			} else if ((drums_action & ORANGE) == ORANGE) {
/*				if ((drums_state & ORANGE) == ORANGE) {
					send_note_off = 1;
				}
				drums_state ^= ORANGE;
*/
				buffer[1] = 51;	/* note number */
				drums_action &= ~ORANGE;
			} else if ((drums_action & GREEN) == GREEN) {
/*				if ((drums_state & GREEN) == GREEN) {
					send_note_off = 1;
				}
				drums_state ^= GREEN;
*/
				buffer[1] = 45;	/* note number */
				drums_action &= ~GREEN;
			} else if ((drums_action & PEDAL) == PEDAL) {
/*				if ((drums_state & PEDAL) == PEDAL) {
					send_note_off = 1;
				}
				drums_state ^= PEDAL;
*/
				buffer[1] = 36;	/* note number */
				drums_action &= ~PEDAL;
			}
			
			if (send_note_off) {
				buffer[0] = MIDI_NOTE_OFF + 9;	// note off
			} else {
				buffer[0] = MIDI_NOTE_ON + 9;	// note on
			}
		}
		
		if (crossfader_action != CROSSFADER_ACTION_NONE) {
			buffer = jack_midi_event_reserve(port_buf, i, 3);
			uint8_t crossfader_midi_value = current_turntables_state.crossfader * 127 / CWIID_TURNTABLES_CROSSFADER_MAX;
			buffer[2] = crossfader_midi_value;
			buffer[1] = MIDI_BALANCE_MSB;
			buffer[0] = MIDI_CONTROL_CHANGE + midi_channel;	// control change
			crossfader_action = CROSSFADER_ACTION_NONE;
		}
		if (effect_dial_action != EFFECT_DIAL_ACTION_NONE) {
			buffer = jack_midi_event_reserve(port_buf, i, 3);
			buffer[0] = MIDI_CONTROL_CHANGE + midi_channel;	// control change
			buffer[1] = MIDI_EFFECT_CTL_1_MSB;
			int16_t signed_value;
			
			switch (effect_dial_action) {
			case EFFECT_DIAL_ACTION_ROTATE_CLOCKWISE:
				effect_dial_state.value += effect_dial_state.change;
				if (effect_dial_state.value > effect_dial_state.max_value) {
					effect_dial_state.value = effect_dial_state.max_value;
				}
				break;
			case EFFECT_DIAL_ACTION_ROTATE_COUNTER_CLOCKWISE:
				signed_value = effect_dial_state.value + effect_dial_state.change;
				effect_dial_state.value += effect_dial_state.change;
				if (signed_value < effect_dial_state.min_value) {
					effect_dial_state.value = effect_dial_state.min_value;
				}
				break;
			case EFFECT_DIAL_ACTION_INITIALIZE:
				printf("initialize\n");
				current_turntables_state.effect_dial = effect_dial_state.initial_value;
				break;
			}
			buffer[2] = effect_dial_state.value;
			effect_dial_action = EFFECT_DIAL_ACTION_NONE;
		}

	}