Example #1
0
void
decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf)
{
    int i;
    jack_midi_clear_buffer (buf);
    for (i = 0; i < buffer_size_uint32 - 3;)
    {
        uint32_t payload_size;
        payload_size = buffer_uint32[i];
        payload_size = ntohl (payload_size);
        if (payload_size)
        {
            jack_midi_event_t event;
            event.time = ntohl (buffer_uint32[i+1]);
            event.size = ntohl (buffer_uint32[i+2]);
            event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3]));
            jack_midi_event_write (buf, event.time, event.buffer, event.size);

            // skip to the next event
            unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1;
            i += 3+nb_data_quads;
        }
        else
            break; // no events can follow an empty event, we're done
    }
Example #2
0
void MidiBuffer::clearEventBuffer() {
    if(!isValid()) {
        return;
    }

    jack_midi_clear_buffer(_jackBuffer);
}
Example #3
0
static
void jack_process(alsa_seqmidi_t *self, struct process_info *info)
{
	stream_t *str = &self->stream[info->dir];
	port_jack_func process = port_type[info->dir].jack_func;
	int i, del=0;

	add_ports(str);

	// process ports
	for (i=0; i<PORT_HASH_SIZE; ++i) {
		port_t **pport = &str->ports[i];
		while (*pport) {
			port_t *port = *pport;
			port->jack_buf = jack_port_get_buffer(port->jack_port, info->nframes);
			if (info->dir == PORT_INPUT)
				jack_midi_clear_buffer(port->jack_buf);

			if (!port->is_dead)
				(*process)(self, port, info);
			else if (jack_ringbuffer_write_space(self->port_del) >= sizeof(port)) {
				debug_log("jack: removed port %s", port->name);
				*pport = port->next;
				jack_ringbuffer_write(self->port_del, (char*)&port, sizeof(port));
				del++;
				continue;
			}

			pport = &port->next;
		}
	}

	if (del)
		sem_post(&self->port_sem);
}
Example #4
0
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;
}
Example #5
0
int process(jack_nframes_t nframes, void *arg) {
  sample_t *in = jack_port_get_buffer(input_port, nframes);

  void *midi_out = jack_port_get_buffer(output_port, nframes);
  jack_midi_clear_buffer(midi_out);

  for (unsigned int i = 0; i < nframes; i++) {
    sample_t cur = in[i];

    last_idx = wrap(last_idx + 1, LAST_WIDTH);
    last[last_idx] = fabs(cur);

    for (unsigned int j = 0; j < LAST_WIDTH; j++) {
      fft_in[j] = last[wrap(last_idx + j, LAST_WIDTH)];
    }

    fftwf_execute(fft_plan);

    power = 0;
    for (unsigned int j = 0; j < FFT_SIZE; j++) {
      power += fabs(fft_out[j]);
    }
    power /= FFT_SIZE;
    
    if (!hit && (power > 2)) {
      hit = true;
      DEBUG("HIT   power = %.3f \n", power);
      send_note(midi_out, i, 0.5);
    } else if (hit && (power < 0.9)) {
      hit = false;
      DEBUG("UNHIT power = %.3f \n", power);
    }
    
    static float minp;
    static float maxp;
    if (delay == 0) {
      DEBUG("power ∈ [%+2.3f, %+2.3f] \r", minp, maxp);
      /* unsigned int star = power; */
      /* for (unsigned int j = 0; j < star; j++) DEBUG(" "); */
      /* DEBUG("*\r"); */
      delay = 30000;
      minp = 1e9;
      maxp = -1e9;
    } else {
      if (power < minp) minp = power;
      if (power > maxp) maxp = power;
      
      --delay;
    }
  }
    
  return 0;      
}
Example #6
0
static
void jack_process(midi_stream_t *str, jack_nframes_t nframes)
{
    int r, w;
    process_jack_t proc;
    jack_nframes_t cur_frames;

    if (!str->owner->keep_walking)
        return;

    proc.midi = str->owner;
    proc.nframes = nframes;
    proc.frame_time = jack_last_frame_time(proc.midi->client);
    cur_frames = jack_frame_time(proc.midi->client);
    int periods_diff = cur_frames - proc.frame_time;
    if (periods_diff < proc.nframes) {
        int periods_lost = periods_diff / proc.nframes;
        proc.frame_time += periods_lost * proc.nframes;
        debug_log("xrun detected: %d periods lost", periods_lost);
    }

    // process existing ports
    for (r=0, w=0; r<str->jack.nports; ++r) {
        midi_port_t *port = str->jack.ports[r];
        proc.port = port;

        assert (port->state > PORT_ADDED_TO_JACK && port->state < PORT_REMOVED_FROM_JACK);

        proc.buffer = jack_port_get_buffer(port->jack, nframes);
        if (str->mode == POLLIN)
            jack_midi_clear_buffer(proc.buffer);

        if (port->state == PORT_REMOVED_FROM_MIDI) {
            port->state = PORT_REMOVED_FROM_JACK; // this signals to scan thread
            continue; // this effectively removes port from the midi->in.jack.ports[]
        }

        (str->process_jack)(&proc);

        if (r != w)
            str->jack.ports[w] = port;
        ++w;
    }
    if (str->jack.nports != w)
        debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w);
    str->jack.nports = w;

    jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet

    // wake midi thread
    write(str->wake_pipe[1], &r, 1);
}
Example #7
0
    void PlayerHandler::process(const jack_nframes_t nframes)
    {
      void* outPortBuf = jack_port_get_buffer(m_outputPort, nframes);

      jack_midi_clear_buffer(outPortBuf);

      jack_position_t pos;
      const jack_transport_state_t state = jack_transport_query(m_client, &pos);

      switch (state)
      {
      case JackTransportStopped:
	{
	  if (m_previousState != state)
	  {
	    // stop them all now
	    allNotesOff(outPortBuf, 0);
	    // reset position
	    m_position = 0;
	  }
	  break;
	}
      case JackTransportRolling:
	{
	  const jack_nframes_t framesAtStart = jack_last_frame_time(m_client);
	  const jack_nframes_t lastFrame = framesAtStart + nframes;

	  const jack_nframes_t startFrame = framesAtStart - pos.frame;

	  while (m_position < m_master.size() && startFrame + m_master[m_position].m_time >= framesAtStart && startFrame + m_master[m_position].m_time < lastFrame)
	  {
	    const MidiEvent & event = m_master[m_position];
	    const jack_nframes_t newOffset = event.m_time - pos.frame;
	    jack_midi_event_write(outPortBuf, newOffset, event.m_data, event.m_size);
	    noteChange(event.m_data);

	    ++m_position;
	  }
	  break;
	}
      default:
	{
	  break;
	}
      }

      m_previousState = state;
    }
Example #8
0
File: midi.c Project: 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;
}
Example #9
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;
}
int process(jack_nframes_t nframes, void *arg) {
    int j;
    data *par = (data *) arg;

    jack_midi_event_t *event = (jack_midi_event_t *) jack_port_get_buffer(par->inPort, nframes);
    int eCount = jack_midi_get_event_count(event);
    void *buffer = jack_port_get_buffer(par->outPort, nframes);
    jack_midi_clear_buffer(buffer);

    for (eCount, j = 0; eCount > 0; eCount--, j++) {
        jack_midi_event_t nextE;
        jack_midi_event_get(&nextE, event, j);

        // Filtering by channel
        char ch = nextE.buffer[0] & 0x0F;

        if (par->channelFilter >= 0) {
            if (ch != par->channelFilter) return 0;
        }

        if (nextE.buffer[0] & 0x80 || nextE.buffer[0] & 0x90) {
            if (nextE.buffer[1] >= par->currentNote) {
                nextE.buffer[0] &= 0xF0;
                nextE.buffer[0] += par->ch2Num;
                nextE.buffer[1] += par->ch2Shift;
            }
            else {
                nextE.buffer[0] &= 0xF0;
                nextE.buffer[0] += par->ch1Num;
                nextE.buffer[1] += par->ch1Shift;
            }

        }


        jack_midi_event_write(buffer, nextE.time, nextE.buffer, nextE.size);
    }

    return 0;
}
Example #11
0
void* luajack_get_buffer(luajack_t *port)
/* Wrapper of jack_port_get_buffer() */
	{
#define cud ((pud)->cud)
	pud_t *pud;
	if(!(pud = get_pud(port))) return NULL;
	if(!IsProcessCallback(cud))
		{ luajack_error("function available only in process callback"); return NULL; }
	if(pud->buf)
		{ luajack_error("buffer already retrieved"); return NULL; }
	pud->nframes = cud->nframes;
	pud->buf = jack_port_get_buffer(pud->port, pud->nframes);
	if(!pud->buf)
		{ luajack_error("cannot get port buffer"); return NULL; }
	pud->bufp = 0;
	if(PortIsMidi(pud))
		{
		if(PortIsOutput(pud))
			jack_midi_clear_buffer(pud->buf);
		}	
	return pud->buf;
#undef cud
	}
Example #12
0
void midiSendLong(unsigned char *buf, unsigned long len) {
  /*int err = snd_rawmidi_write(handle_out, buf, len);
  if (err != len) {
    fprintf(stderr, "could not write %ld byte to output, return: %d\n", len, err);
    exit(1);
  }*/
  if (jack_midi_output_port == NULL) {
    fprintf(stderr, "midiSendLong failed: output port closed\n");
    exit(1);
  }

  void* output_buf = jack_port_get_buffer (jack_midi_output_port, 1);   
  jack_midi_clear_buffer(output_buf);  

  printhex("send:", buf, len);

  int err = jack_midi_event_write(output_buf, 0, buf, len);
  if (err != 0) { 
    if (err == ENOBUFS) { // if there's not enough space in buffer for event
    }
    fprintf(stderr, "could not write %ld byte to output, return: %d\n", len, err);
    exit(1);
  }
}
Example #13
0
int process(jack_nframes_t nframes, void *arg) {
	jack_default_audio_sample_t *in = (jack_default_audio_sample_t *)jack_port_get_buffer(input_port, nframes);
	void *out = jack_port_get_buffer(output_port, nframes);

	jack_midi_clear_buffer(out);

	static int count = -1;

	int is_on;
	float volume;

	int frame;
	for(frame = 0; frame < nframes; frame++) {
		if((is_on = (volume = fabs(in[frame])) > threshold))
			count = 0;
		else if(count++ == min_time_between_hits)
			count = -1;

		if(is_on != midi_event.playing && -midi_event.playing == count)
			toggle_midi_event(out, frame, &midi_event, volume);
	}

	return 0;
}
Example #14
0
int process(jack_nframes_t nframes, void* arg)
{
    TimerProcess.Start();

    static uint64_t frametime = 0;
    TJackSynth* synth = static_cast<TJackSynth*>(arg);

    /* Process MIDI input */
    void* inbuf = jack_port_get_buffer(MidiIn, nframes);
    jack_nframes_t event_count = jack_midi_get_event_count(inbuf);
    for (jack_nframes_t i = 0; i < event_count; i++) {
        jack_midi_event_t event;
        jack_midi_event_get(&event, inbuf, i);
        std::vector<uint8_t> data(event.buffer, event.buffer + event.size);
        synth->HandleMidi(data, frametime + event.time);
    }

    /* Send MIDI */
    void* outbuf = jack_port_get_buffer(MidiOut, nframes);
    jack_midi_clear_buffer(outbuf);
    while (!MidiOutQueue.empty()) {
        const std::vector<uint8_t>& data = MidiOutQueue.front();
        int ret = jack_midi_event_write(outbuf, 0, data.data(), data.size());
        MidiOutQueue.pop();
        if (ret != 0) {
            fprintf(stderr, "MIDI send error\n");
        }
    }

    synth->Process(nframes);

    frametime += nframes;
    TimerProcess.Stop();

    return 0;
}
Example #15
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;
}
Example #16
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;
}
Example #17
0
static int process_cb(jack_nframes_t nframes, void *arg)
{
    struct cbox_jack_io_impl *jii = arg;
    struct cbox_io *io = jii->ioi.pio;
    struct cbox_io_callbacks *cb = io->cb;
    
    io->io_env.buffer_size = nframes;
    for (int i = 0; i < io->io_env.input_count; i++)
        io->input_buffers[i] = jack_port_get_buffer(jii->inputs[i], nframes);
    for (int i = 0; i < io->io_env.output_count; i++)
    {
        io->output_buffers[i] = jack_port_get_buffer(jii->outputs[i], nframes);
        if (!io->output_buffers[i])
            continue;
        for (int j = 0; j < nframes; j ++)
            io->output_buffers[i][j] = 0.f;
    }
    for (GSList *p = io->midi_inputs; p; p = p->next)
    {
        struct cbox_jack_midi_input *input = p->data;
        if (input->hdr.output_set || input->hdr.enable_appsink)
        {
            copy_midi_data_to_buffer(input->port, io->io_env.buffer_size, &input->hdr.buffer);
            if (input->hdr.enable_appsink)
                cbox_midi_appsink_supply(&input->hdr.appsink, &input->hdr.buffer);
        }
        else
            cbox_midi_buffer_clear(&input->hdr.buffer);
    }
    if (cb->on_transport_sync)
    {
        jack_transport_state_t state = jack_transport_query(jii->client, NULL);
        if (state != jii->last_transport_state)
        {
            jack_position_t pos;
            jack_transport_query(jii->client, &pos);
            if (jii->debug_transport)
                g_message("JACK transport: incoming state change, state = %s, last state = %s, pos = %d\n", transport_state_names[state], transport_state_names[(int)jii->last_transport_state], (int)pos.frame);
            if (state == JackTransportStopped)
            {
                if (cb->on_transport_sync(cb->user_data, ts_stopping, pos.frame))
                    jii->last_transport_state = state;
            }
            else
            if (state == JackTransportRolling && jii->last_transport_state == JackTransportStarting)
            {
                if (cb->on_transport_sync(cb->user_data, ts_rolling, pos.frame))
                    jii->last_transport_state = state;
            }
            else
                jii->last_transport_state = state;
        }
    }
    cb->process(cb->user_data, io, nframes);
    for (int i = 0; i < io->io_env.input_count; i++)
        io->input_buffers[i] = NULL;
    for (int i = 0; i < io->io_env.output_count; i++)
        io->output_buffers[i] = NULL;
    for (GSList *p = io->midi_outputs; p; p = g_slist_next(p))
    {
        struct cbox_jack_midi_output *midiout = p->data;

        void *pbuf = jack_port_get_buffer(midiout->port, nframes);
        jack_midi_clear_buffer(pbuf);

        cbox_midi_merger_render(&midiout->hdr.merger);
        if (midiout->hdr.buffer.count)
        {
            uint8_t tmp_data[4];
            for (int i = 0; i < midiout->hdr.buffer.count; i++)
            {
                const struct cbox_midi_event *event = cbox_midi_buffer_get_event(&midiout->hdr.buffer, i);
                const uint8_t *pdata = cbox_midi_event_get_data(event);
                if ((pdata[0] & 0xF0) == 0x90 && !pdata[2] && event->size == 3)
                {
                    tmp_data[0] = pdata[0] & ~0x10;
                    tmp_data[1] = pdata[1];
                    tmp_data[2] = pdata[2];
                    pdata = tmp_data;
                }
                if (jack_midi_event_write(pbuf, event->time, pdata, event->size))
                {
                    g_warning("MIDI buffer overflow on JACK output port '%s'", midiout->hdr.name);
                    break;
                }
            }
        }
    }
    return 0;
}
Example #18
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;
	}
}
Example #19
0
// rt
static int
_process(jack_nframes_t nsamples, void *data)
{
	prog_t *handle = data;
	bin_t *bin = &handle->bin;
	sp_app_t *app = bin->app;

#if defined(JACK_HAS_CYCLE_TIMES)
	clock_gettime(CLOCK_REALTIME, &handle->ntp);
	handle->ntp.tv_sec += JAN_1970; // convert NTP to OSC time
	jack_nframes_t offset = jack_frames_since_cycle_start(handle->client);

	float T;
	jack_get_cycle_times(handle->client, &handle->cycle.cur_frames,
		&handle->cycle.cur_usecs, &handle->cycle.nxt_usecs, &T);
	(void)T;
	
	handle->cycle.ref_frames = handle->cycle.cur_frames + offset;

	// calculate apparent period
	double diff = 1e-6 * (handle->cycle.nxt_usecs - handle->cycle.cur_usecs);

	// calculate apparent samples per period
	handle->cycle.dT = nsamples / diff;
	handle->cycle.dTm1 = 1.0 / handle->cycle.dT;
#endif

	// get transport position
	jack_position_t pos;
	jack_transport_state_t rolling = jack_transport_query(handle->client, &pos) == JackTransportRolling;
	int trans_changed = (rolling != handle->trans.rolling)
		|| (pos.frame != handle->trans.frame)
		|| (pos.beats_per_bar != handle->trans.beats_per_bar)
		|| (pos.beat_type != handle->trans.beat_type)
		|| (pos.ticks_per_beat != handle->trans.ticks_per_beat)
		|| (pos.beats_per_minute != handle->trans.beats_per_minute);

	const size_t sample_buf_size = sizeof(float) * nsamples;
	const sp_app_system_source_t *sources = sp_app_get_system_sources(app);
	const sp_app_system_sink_t *sinks = sp_app_get_system_sinks(app);

	if(sp_app_bypassed(app)) // aka loading state
	{
		//fprintf(stderr, "app is bypassed\n");

		// clear output buffers
		for(const sp_app_system_sink_t *sink=sinks;
			sink->type != SYSTEM_PORT_NONE;
			sink++)
		{
			switch(sink->type)
			{
				case SYSTEM_PORT_NONE:
				case SYSTEM_PORT_CONTROL:
				case SYSTEM_PORT_COM:
					break;

				case SYSTEM_PORT_AUDIO:
				case SYSTEM_PORT_CV:
				{
					void *out_buf = jack_port_get_buffer(sink->sys_port, nsamples);
					memset(out_buf, 0x0, sample_buf_size);
					break;
				}
				case SYSTEM_PORT_MIDI:
				case SYSTEM_PORT_OSC:
				{
					void *out_buf = jack_port_get_buffer(sink->sys_port, nsamples);
					jack_midi_clear_buffer(out_buf);
					break;
				}
			}
		}

		bin_process_pre(bin, nsamples, true);
		bin_process_post(bin);

		return 0;
	}

	//TODO use __builtin_assume_aligned

	// fill input buffers
	for(const sp_app_system_source_t *source=sources;
		source->type != SYSTEM_PORT_NONE;
		source++)
	{
		switch(source->type)
		{
			case SYSTEM_PORT_NONE:
			case SYSTEM_PORT_CONTROL:
				break;

			case SYSTEM_PORT_AUDIO:
			case SYSTEM_PORT_CV:
			{
				const void *in_buf = jack_port_get_buffer(source->sys_port, nsamples);
				memcpy(source->buf, in_buf, sample_buf_size);
				break;
			}
			case SYSTEM_PORT_MIDI:
			{
				void *in_buf = jack_port_get_buffer(source->sys_port, nsamples);
				void *seq_in = source->buf;

				LV2_Atom_Forge *forge = &handle->forge;
				LV2_Atom_Forge_Frame frame;
				lv2_atom_forge_set_buffer(forge, seq_in, SEQ_SIZE);
				LV2_Atom_Forge_Ref ref = lv2_atom_forge_sequence_head(forge, &frame, 0);

				if(ref && trans_changed)
					ref = _trans_event(handle, forge, rolling, &pos);

				int n = jack_midi_get_event_count(in_buf);
				for(int i=0; i<n; i++)
				{
					jack_midi_event_t mev;
					jack_midi_event_get(&mev, in_buf, i);

					//add jack midi event to in_buf
					if(ref)
						ref = lv2_atom_forge_frame_time(forge, mev.time);
					if(ref)
						ref = lv2_atom_forge_atom(forge, mev.size, handle->midi_MidiEvent);
					if(ref)
						ref = lv2_atom_forge_raw(forge, mev.buffer, mev.size);
					if(ref)
						lv2_atom_forge_pad(forge, mev.size);
				}
				if(ref)
					lv2_atom_forge_pop(forge, &frame);
				else
					lv2_atom_sequence_clear(seq_in);

				break;
			}

			case SYSTEM_PORT_OSC:
			{
				void *in_buf = jack_port_get_buffer(source->sys_port, nsamples);
				void *seq_in = source->buf;

				LV2_Atom_Forge *forge = &handle->forge;
				LV2_Atom_Forge_Frame frame;
				lv2_atom_forge_set_buffer(forge, seq_in, SEQ_SIZE);
				LV2_Atom_Forge_Ref ref = lv2_atom_forge_sequence_head(forge, &frame, 0);

				if(ref && trans_changed)
					ref = _trans_event(handle, forge, rolling, &pos);

				int n = jack_midi_get_event_count(in_buf);	
				for(int i=0; i<n; i++)
				{
					jack_midi_event_t mev;
					jack_midi_event_get(&mev, (void *)in_buf, i);

					//add jack osc event to in_buf
					if(osc_check_packet(mev.buffer, mev.size))
					{
						if(ref)
							ref = lv2_atom_forge_frame_time(forge, mev.time);
						handle->ref = ref;
						osc_dispatch_method(mev.buffer, mev.size, methods,
							_bundle_in, _bundle_out, handle);
						ref = handle->ref;
					}
				}
				if(ref)
					lv2_atom_forge_pop(forge, &frame);
				else
					lv2_atom_sequence_clear(seq_in);

				break;
			}

			case SYSTEM_PORT_COM:
			{
				void *seq_in = source->buf;

				LV2_Atom_Forge *forge = &handle->forge;
				LV2_Atom_Forge_Frame frame;
				lv2_atom_forge_set_buffer(forge, seq_in, SEQ_SIZE);
				LV2_Atom_Forge_Ref ref = lv2_atom_forge_sequence_head(forge, &frame, 0);

				const LV2_Atom_Object *obj;
				size_t size;
				while((obj = varchunk_read_request(bin->app_from_com, &size)))
				{
					if(ref)
						ref = lv2_atom_forge_frame_time(forge, 0);
					if(ref)
						ref = lv2_atom_forge_raw(forge, obj, size);
					if(ref)
						lv2_atom_forge_pad(forge, size);

					varchunk_read_advance(bin->app_from_com);
				}
				if(ref)
					lv2_atom_forge_pop(forge, &frame);
				else
					lv2_atom_sequence_clear(seq_in);

				break;
			}
		}
	}

	// update transport state
	handle->trans.rolling = rolling;
	handle->trans.frame = rolling
		? handle->trans.frame + nsamples
		: pos.frame;
	handle->trans.beats_per_bar = pos.beats_per_bar;
	handle->trans.beat_type = pos.beat_type;
	handle->trans.ticks_per_beat = pos.ticks_per_beat;
	handle->trans.beats_per_minute = pos.beats_per_minute;

	bin_process_pre(bin, nsamples, false);

	// fill output buffers
	for(const sp_app_system_sink_t *sink=sinks;
		sink->type != SYSTEM_PORT_NONE;
		sink++)
	{
		switch(sink->type)
		{
			case SYSTEM_PORT_NONE:
			case SYSTEM_PORT_CONTROL:
				break;

			case SYSTEM_PORT_AUDIO:
			case SYSTEM_PORT_CV:
			{
				void *out_buf = jack_port_get_buffer(sink->sys_port, nsamples);
				memcpy(out_buf, sink->buf, sample_buf_size);
				break;
			}
			case SYSTEM_PORT_MIDI:
			{
				void *out_buf = jack_port_get_buffer(sink->sys_port, nsamples);
				const LV2_Atom_Sequence *seq_out = sink->buf;

				// fill midi output buffer
				jack_midi_clear_buffer(out_buf);
				if(seq_out)
				{
					LV2_ATOM_SEQUENCE_FOREACH(seq_out, ev)
					{
						const LV2_Atom *atom = &ev->body;

						if(atom->type != handle->midi_MidiEvent)
							continue; // ignore non-MIDI events

						jack_midi_event_write(out_buf, ev->time.frames,
							LV2_ATOM_BODY_CONST(atom), atom->size);
					}
				}

				break;
			}

			case SYSTEM_PORT_OSC:
			{
				void *out_buf = jack_port_get_buffer(sink->sys_port, nsamples);
				const LV2_Atom_Sequence *seq_out = sink->buf;

				// fill midi output buffer
				jack_midi_clear_buffer(out_buf);
				if(seq_out)
				{
					LV2_ATOM_SEQUENCE_FOREACH(seq_out, ev)
					{
						const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;

						handle->osc_ptr = handle->osc_buf;
						handle->osc_end = handle->osc_buf + OSC_SIZE;

						osc_atom_event_unroll(&handle->oforge, obj, _bundle_push_cb,
							_bundle_pop_cb, _message_cb, handle);

						size_t size = handle->osc_ptr
							? handle->osc_ptr - handle->osc_buf
							: 0;

						if(size)
						{
							jack_midi_event_write(out_buf, ev->time.frames,
								handle->osc_buf, size);
						}
					}
				}

				break;
			}

			case SYSTEM_PORT_COM:
			{
				const LV2_Atom_Sequence *seq_out = sink->buf;

				LV2_ATOM_SEQUENCE_FOREACH(seq_out, ev)
				{
					const LV2_Atom *atom = (const LV2_Atom *)&ev->body;

					// try do process events directly
					bin->advance_ui = sp_app_from_ui(bin->app, atom);
					if(!bin->advance_ui) // queue event in ringbuffer instead
					{
						//fprintf(stderr, "plugin ui direct is blocked\n");

						void *ptr;
						size_t size = lv2_atom_total_size(atom);
						if((ptr = varchunk_write_request(bin->app_from_app, size)))
						{
							memcpy(ptr, atom, size);
							varchunk_write_advance(bin->app_from_app, size);
						}
						else
						{
							//fprintf(stderr, "app_from_ui ringbuffer full\n");
							//FIXME
						}
					}
				}
				break;
			}
		}
	}
	
	bin_process_post(bin);

	return 0;
}
Example #20
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;
}
Example #21
0
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;
}
Example #22
0
    void ModeHandler::process(const jack_nframes_t nframes)
    {
      void* inPortBuf = jack_port_get_buffer(m_inputPort, nframes);
      void* outPortBuf = jack_port_get_buffer(m_outputPort, nframes);

      jack_midi_clear_buffer(outPortBuf);

      const jack_transport_state_t state = jack_transport_query(m_client, nullptr);

      const jack_nframes_t eventCount = jack_midi_get_event_count(inPortBuf);

      for (size_t i = 0; i < eventCount; ++i)
      {
	jack_midi_event_t inEvent;
	jack_midi_event_get(&inEvent, inPortBuf, i);

	const jack_midi_data_t cmd = inEvent.buffer[0] & 0xf0;

	switch (cmd)
	{
	case MIDI_NOTEON:
	case MIDI_NOTEOFF:
	  {
	    const jack_midi_data_t note = inEvent.buffer[1];
	    const jack_midi_data_t velocity = inEvent.buffer[2];

	    int noteToUse = note;

	    // we only map on a note on
	    // on a note off we use the previously mapped note
	    // and only is transport is rolling
	    if (cmd == MIDI_NOTEON && velocity > 0)
	    {
	      if (state == JackTransportRolling)
	      {
		const int newNote = transpose(m_offset, m_quirkOffset, note);

		m_mappedNotes[note] = newNote;
		noteToUse = newNote;
	      }
	    }
	    else
	    {
	      // NOTEOFF
	      if (m_mappedNotes[note] != NOT_MAPPED)
	      {
		noteToUse = m_mappedNotes[note];
		m_mappedNotes[note] = NOT_MAPPED;
	      }
	    }

	    if (noteToUse != SKIP)
	    {
	      jack_midi_data_t data[3];
	      data[0] = inEvent.buffer[0];
	      data[1] = noteToUse;;
	      data[2] = inEvent.buffer[2];

	      jack_midi_event_write(outPortBuf, inEvent.time, data, 3);
	    }
	    break;
	  }
	default:
	  {
	    // just forward everything else
	    jack_midi_event_write(outPortBuf, inEvent.time, inEvent.buffer, inEvent.size);
	  }
	}
      }
    }
Example #23
0
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;
		}

	}
Example #24
0
/*
** jack process callback
*/
static int _process(jack_nframes_t nframes, void *arg) {
  _t *dp = (_t *)arg;
  void *midi_out = jack_port_get_buffer(framework_midi_output(dp,0), nframes);
  jack_midi_event_t event;
  // initialize input event queue
  framework_midi_event_init(&dp->fw, &dp->midi, nframes);
  // recompute timings if necessary
  _update(dp);
  /* this is important, very strange if omitted */
  jack_midi_clear_buffer(midi_out);
  /* for all frames in the buffer */
  for (int i = 0; i < nframes; i++) {
    /* read all events for this frame */
    int port;
    while (framework_midi_event_get(&dp->fw, i, &event, &port)) {
      if (port < dp->fw.n_midi_inputs) {
	/* it is a midi_input event */
	if (event.size == 3) {
	  const unsigned char channel = (event.buffer[0]&0xF)+1;
	  const unsigned char command = event.buffer[0]&0xF0;
	  const unsigned char note = event.buffer[1];
	  if (channel == dp->opts.chan && note == dp->opts.note) {
	    if (command == MIDI_NOTE_ON) {
	      if ( ! dp->ptt_on) {
		dp->ptt_on = 1;
		_send(dp, midi_out, i, command, dp->opts.note+1);
	      }
	      dp->key_on = 1;
	      if (i+dp->ptt_delay_samples < nframes) {
		_send(dp, midi_out, i+dp->ptt_delay_samples, command, dp->opts.note);
	      } else {
		midi_buffer_write_delay(&dp->midi, i+dp->ptt_delay_samples-nframes);
		midi_buffer_write_note_on(&dp->midi, 0, channel, note, 0);
	      }
	    } else if (command == MIDI_NOTE_OFF) {
	      if (i+dp->ptt_delay_samples < nframes) {
		dp->key_on = 0;
		dp->ptt_hang_count = dp->ptt_hang_samples+dp->ptt_delay_samples;
		_send(dp, midi_out, i+dp->ptt_delay_samples, command, dp->opts.note);
	      } else {
		midi_buffer_write_delay(&dp->midi, i+dp->ptt_delay_samples-nframes);
		midi_buffer_write_note_off(&dp->midi, 0, channel, note, 0);
	      }
	    }
	  }
	}
      } else {
	/* it is a midi buffer event */
	if (event.size != 0) {
	  const unsigned char command = event.buffer[0]&0xF0;
	  if (command == MIDI_NOTE_ON) {
	    dp->key_on = 1;
	  } else if (command == MIDI_NOTE_OFF) {
	    dp->key_on = 0;
	    dp->ptt_hang_count = dp->ptt_hang_samples;
	  }
	  _send(dp, midi_out, i, command, dp->opts.note);
	}
      }
    }
    /* clock the ptt hang time counter */
    if (dp->key_on == 0 && dp->ptt_on != 0 && --dp->ptt_hang_count <= 0) {
      dp->ptt_on = 0;
      _send(dp, midi_out, i, MIDI_NOTE_OFF, dp->opts.note+1);
    }
  }
  return 0;
}
Example #25
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;
}
Example #26
0
/**
 * The process callback for this JACK application.
 * It is called by JACK at the appropriate times.
 */
int
process (jack_nframes_t nframes, void *arg)
{
    jack_nframes_t net_period;
    int rx_bufsize, tx_bufsize;

    jack_default_audio_sample_t *buf;
    jack_port_t *port;
    JSList *node;
    int chn;
    int size, i;
    const char *porttype;
    int input_fd;

    jack_position_t local_trans_pos;

    uint32_t *packet_buf_tx, *packet_bufX;
    uint32_t *rx_packet_ptr;
    jack_time_t packet_recv_timestamp;

    if( bitdepth == 1000 || bitdepth == 999)
        net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
    else
        net_period = (float) nframes / (float) factor;

    rx_bufsize =  get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
    tx_bufsize =  get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);

    /* Allocate a buffer where both In and Out Buffer will fit */
    packet_buf_tx = alloca (tx_bufsize);

    jacknet_packet_header *pkthdr_tx = (jacknet_packet_header *) packet_buf_tx;

    /*
     * for latency==0 we need to send out the packet before we wait on the reply.
     * but this introduces a cycle of latency, when netsource is connected to itself.
     * so we send out before read only in zero latency mode.
     *
     */

    if( latency == 0 ) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    /*
     * ok... now the RECEIVE code.
     *
     */


    if( reply_port )
        input_fd = insockfd;
    else
        input_fd = outsockfd;

    // for latency == 0 we can poll.
    if( (latency == 0) || (freewheeling != 0)  ) {
        jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client);
        // Now loop until we get the right packet.
        while(1) {
            jack_nframes_t got_frame;
            if ( ! netjack_poll_deadline( input_fd, deadline ) )
                break;

            packet_cache_drain_socket(packcache, input_fd);

            if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame ))
                if( got_frame == (framecnt - latency) )
                    break;
        }
    } else {
        // normally:
        // only drain socket.
        packet_cache_drain_socket(packcache, input_fd);
    }

    size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
    /* First alternative : we received what we expected. Render the data
     * to the JACK ports so it can be played. */
    if (size == rx_bufsize) {
        uint32_t *packet_buf_rx = rx_packet_ptr;
        jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx;
        packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
        // calculate how much time there would have been, if this packet was sent at the deadline.

        int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
        packet_header_ntoh (pkthdr_rx);
        deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency;
        //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );

        if (cont_miss) {
            //printf("Frame %d  \tRecovered from dropouts\n", framecnt);
            cont_miss = 0;
        }
        render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
                                      capture_ports, capture_srcs, nframes, dont_htonl_floats);

        state_currentframe = framecnt;
        state_recv_packet_queue_time = recv_time_offset;
        state_connected = 1;
        sync_state = pkthdr_rx->sync_state;
        packet_cache_release_packet( packcache, framecnt - latency );
    }
    /* Second alternative : we've received something that's not
     * as big as expected or we missed a packet. We render silence
     * to the ouput ports */
    else {
        jack_nframes_t latency_estimate;
        if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) )
            //if( (state_latency == 0) || (latency_estimate < state_latency) )
            state_latency = latency_estimate;

        // Set the counters up.
        state_currentframe = framecnt;
        //state_latency = framecnt - pkthdr->framecnt;
        state_netxruns += 1;

        //printf ("Frame %d  \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
        //printf ("Frame %d  \tPacket missed or incomplete\n", framecnt);
        cont_miss += 1;
        chn = 0;
        node = capture_ports;
        while (node != NULL) {
            port = (jack_port_t *) node->data;
            buf = jack_port_get_buffer (port, nframes);
            porttype = jack_port_type (port);
            if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
                for (i = 0; i < nframes; i++)
                    buf[i] = 0.0;
            else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
                jack_midi_clear_buffer (buf);
            node = jack_slist_next (node);
            chn++;
        }
    }
    if (latency != 0) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    framecnt++;
    return 0;
}
Example #27
0
CARLA_EXPORT
void jack_midi_reset_buffer(void* buf)
{
    jack_midi_clear_buffer(buf);
}