コード例 #1
0
ファイル: midisine.c プロジェクト: KimJeongYeon/jack2_android
static int process(jack_nframes_t nframes, void *arg)
{
	int i;
	void* port_buf = jack_port_get_buffer(input_port, nframes);
	jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
	jack_midi_event_t in_event;
	jack_nframes_t event_index = 0;
	jack_nframes_t event_count = jack_midi_get_event_count(port_buf);
	if(event_count > 1)
	{
		printf(" midisine: have %d events\n", event_count);
		for(i=0; i<event_count; i++)
		{
			jack_midi_event_get(&in_event, port_buf, i);
			printf("    event %d time is %d. 1st byte is 0x%x\n", i, in_event.time, *(in_event.buffer));
		}
/*		printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/
	}
	jack_midi_event_get(&in_event, port_buf, 0);
	for(i = 0; i < nframes; i++)
	{
		if ((in_event.time == i) && (event_index < event_count))
		{
			if (((*(in_event.buffer) & 0xf0)) == 0x90)
			{
                /* note on */
                note = *(in_event.buffer + 1);
                if (*(in_event.buffer + 2) == 0) {
                    note_on = 0.0;
                } else {
                    note_on = (float)(*(in_event.buffer + 2)) / 127.f;
                }
			}
			else if (((*(in_event.buffer)) & 0xf0) == 0x80)
			{
				/* note off */
				note = *(in_event.buffer + 1);
				note_on = 0.0;
			}
			event_index++;
			if(event_index < event_count)
				jack_midi_event_get(&in_event, port_buf, event_index);
		}
		ramp += note_frqs[note];
		ramp = (ramp > 1.0) ? ramp - 2.0 : ramp;
		out[i] = note_on*sin(2*M_PI*ramp);
	}
	return 0;
}
コード例 #2
0
ファイル: alsa_rawmidi.c プロジェクト: basilnut/jack2
static
void do_jack_output(process_jack_t *proc)
{
    output_port_t *port = (output_port_t*) proc->port;
    int nevents = jack_midi_get_event_count(proc->buffer);
    int i;
    if (nevents)
        debug_log("jack_out: %d events in %s", nevents, port->base.name);
    for (i=0; i<nevents; ++i) {
        jack_midi_event_t event;
        event_head_t hdr;

        jack_midi_event_get(&event, proc->buffer, i);

        if (jack_ringbuffer_write_space(port->base.data_ring) < event.size || jack_ringbuffer_write_space(port->base.event_ring) < sizeof(hdr)) {
            debug_log("jack_out: output buffer overflow on %s", port->base.name);
            break;
        }

        midi_pack_event(&port->packer, &event);

        jack_ringbuffer_write(port->base.data_ring, (char*)event.buffer, event.size);

        hdr.time = proc->frame_time + event.time + proc->nframes;
        hdr.size = event.size;
        jack_ringbuffer_write(port->base.event_ring, (char*)&hdr, sizeof(hdr));
        debug_log("jack_out: sent %d-byte event at %ld", (int)event.size, (long)event.time);
    }
}
コード例 #3
0
ファイル: midi_dump.c プロジェクト: Barrett17/jack2
int
process (jack_nframes_t frames, void* arg)
{
	void* buffer;
	jack_nframes_t N;
	jack_nframes_t i;
	char description[256];

	buffer = jack_port_get_buffer (port, frames);
	assert (buffer);

	N = jack_midi_get_event_count (buffer);
	for (i = 0; i < N; ++i) {
		jack_midi_event_t event;
		int r;

		r = jack_midi_event_get (&event, buffer, i);
		if (r == 0) {
			size_t j;

			printf ("%d:", event.time);
			for (j = 0; j < event.size; ++j) {
				printf (" %x", event.buffer[j]);
			}

			describe (&event, description, sizeof (description));
			printf (" %s", description);

			printf ("\n");
		}
	}

	return 0;
}
コード例 #4
0
ファイル: jack.c プロジェクト: BackupTheBerlios/galan
PRIVATE void midiinport_realtime_handler(Generator *g, AEvent *event) {
    MidiInData *data = g->data;
    jack_nframes_t nframes = event->d.integer;
    void * input_buf;
    jack_midi_event_t input_event;
    jack_nframes_t input_event_count;
    jack_nframes_t i;
    unsigned char * data;

    input_buf = jack_port_get_buffer(data->port, nframes);
    input_event_count = jack_midi_get_event_count(input_buf, nframes);

  /* iterate over all incoming JACK MIDI events */
  for (i = 0; i < input_event_count; i++)
  {
    /* retrieve JACK MIDI event */
    jack_midi_event_get(&input_event, input_buf, i, nframes);

    event->time = input_event.time + gen_get_sampletime();
    event->type = AE_MIDIEVENT;
    event->midiev.len = input_event.size;
    memcpy( &(event->midiev.midistring), input_event.buffer,  input_event.size);

    
    /* normalise note events if needed */
    if ((input_event.size == 3) && ((event->midiev[0] & 0xF0) == 0x90) &&
        (event->midiev[2] == 0))
    {
      event->midiev[0] = 0x80 | (event->midiev[0] & 0x0F);
    }

    gen_send_events(g, EVT_MIDIEVT, -1, &e);
  }

}
コード例 #5
0
ファイル: jack_midi.c プロジェクト: yoyz/audio
jack_read_midi(jack_nframes_t nframes) {
	jack_nframes_t i;

	midi_buf=jack_port_get_buffer(midi_port, nframes);
	jack_nframes_t  num_events=jack_midi_get_event_count(midi_buf);
	for(i=0; i<num_events; i++) {
		if(jack_midi_event_get(&midi_event, midi_buf, i)) return;
		int status=midi_event.buffer[0];
		jack_midi_data_t param=midi_event.buffer[1];
		jack_midi_data_t value=midi_event.buffer[2];
		//printf("JACK MIDI event: %x %x %x\n", status, param, value);

		int ev_type=status&0xf0;
		int channel=status&0x0f;

		switch(ev_type) {
			case SND_SEQ_EVENT_CONTROLLER:
				if(!midi_channels[channel].in_use) break;
				if(param==64) {
					if(value>64) midi_channels[channel].sustain=1;
					else midi_channels[channel].sustain=0;
				} else if(param==1) {
					// modulation controlling vibrato: value=0-127
					midi_channels[channel].vibrato=value;
					//printf("%d\n", value);
					midi_channels[channel].vibrato_changed=1;
				}
				break;
			// case SND_SEQ_EVENT_KEYPRESS:
			case SND_SEQ_EVENT_CHANPRESS:
				if(!midi_channels[channel].in_use) break;
				midi_channels[channel].chanpress=value;
				midi_channels[channel].chanpress_changed=1;
				break;
			case SND_SEQ_EVENT_NOTEON:
				if(!midi_channels[channel].in_use) break;
				note_on(channel, param, value);
				break;
			case SND_SEQ_EVENT_NOTEOFF:
				if(!midi_channels[channel].in_use) break;
				note_off(channel, param);
				break;
			case SND_SEQ_EVENT_PITCHBEND:
				// value=-8192 to +8191
				if(!midi_channels[channel].in_use) break;
				//int pitchbend=(value*128)|(param&0x7f);
				int pitchbend=(((value&0x7f)<<7)|(param&0x7f))-8192;
				//printf("got pitchbend %x %x: %x %d\n", param, value, pitchbend, pitchbend);
				midi_channels[channel].pitchbend=pitchbend;
				break;
			case SND_SEQ_EVENT_PGMCHANGE:
				if(midi_channels[channel].program==-1) break;
				//printf("prg change %d\n", value);
				midi_channels[channel].program=param;
				break;
		}
	}
}
コード例 #6
0
ファイル: jack_player.c プロジェクト: ayyi/samplecat
int jack_audio_callback(jack_nframes_t nframes, void *arg) {
	int c,s;
	WfAudioInfo* nfo = &myplayer->info;

#ifdef JACK_MIDI
	int n;
	void *jack_buf = jack_port_get_buffer(jack_midi_port, nframes);
	int nevents = jack_midi_get_event_count(jack_buf);
	for (n=0; n<nevents; n++) {
		jack_midi_event_t ev;
		jack_midi_event_get(&ev, jack_buf, n);

		if (ev.size < 3 || ev.size > 3) continue; // filter note on/off
		else {
			event_queue[queued_events_end].time = ev.time;
			event_queue[queued_events_end].size = ev.size;
			memcpy (event_queue[queued_events_end].buffer, ev.buffer, ev.size);
			queued_events_end = (queued_events_end +1 ) % JACK_MIDI_QUEUE_SIZE;
		}
	}
	if (queued_events_start != queued_events_end) {
		/* Tell the midi thread there is work to do. */
		if(pthread_mutex_trylock(&midi_thread_lock) == 0) {
			pthread_cond_signal(&midi_ready);
			pthread_mutex_unlock(&midi_thread_lock);
		}
	}
#endif

	if (!player_active) return (0);

	for(c=0; c<nfo->channels; c++) {
		j_out[c] = (jack_default_audio_sample_t*) jack_port_get_buffer(j_output_port[c], nframes);
	}

	if(playpause || jack_ringbuffer_read_space(rb) < nfo->channels * nframes * sizeof(jack_default_audio_sample_t)) {
		silent = 1;
		for(c=0; c< nfo->channels; c++) {
			memset(j_out[c], 0, nframes * sizeof(jack_default_audio_sample_t));
		}
	} else {
		silent=0;
		/* de-interleave */
		for(s=0; s<nframes; s++) {
			for(c=0; c< nfo->channels; c++) {
				jack_ringbuffer_read(rb, (char*) &j_out[c][s], sizeof(jack_default_audio_sample_t));
			}
		}
	}

	/* Tell the player thread there is work to do. */
	if(pthread_mutex_trylock(&player_thread_lock) == 0) {
		pthread_cond_signal(&buffer_ready);
		pthread_mutex_unlock(&player_thread_lock);
	}

	return(0);
};
コード例 #7
0
ファイル: alsa_seqmidi.c プロジェクト: Andux/jack2
static
void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info)
{
	stream_t *str = &self->stream[info->dir];
	int nevents = jack_midi_get_event_count(port->jack_buf);
	int i;
	for (i=0; i<nevents; ++i) {
		jack_midi_event_t jack_event;
		snd_seq_event_t alsa_event;
		int64_t frame_offset;
		int64_t out_time;
		snd_seq_real_time_t out_rt;
		int err;

		jack_midi_event_get(&jack_event, port->jack_buf, i);

		snd_seq_ev_clear(&alsa_event);
		snd_midi_event_reset_encode(str->codec);
		if (!snd_midi_event_encode(str->codec, jack_event.buffer, jack_event.size, &alsa_event))
			continue; // invalid event

		snd_seq_ev_set_source(&alsa_event, self->port_id);
		snd_seq_ev_set_dest(&alsa_event, port->remote.client, port->remote.port);

		/* NOTE: in case of xrun it could become negative, so it is essential to use signed type! */
		frame_offset = (int64_t)jack_event.time + info->period_start + info->nframes - info->cur_frames;
		if (frame_offset < 0) {
			frame_offset = info->nframes + jack_event.time;
			error_log("internal xrun detected: frame_offset = %"PRId64"\n", frame_offset);
		}
		/* Ken Ellinwood reported problems with this assert.
		 * Seems, magic 2 should be replaced with nperiods. */
		//FIXME: assert (frame_offset < info->nframes*2);
		//if (frame_offset < info->nframes * info->nperiods)
		//        debug_log("alsa_out: BLAH-BLAH-BLAH");

		out_time = info->alsa_time + (frame_offset * NSEC_PER_SEC) / info->sample_rate;

		debug_log("alsa_out: frame_offset = %lld, info->alsa_time = %lld, out_time = %lld, port->last_out_time = %lld",
			frame_offset, info->alsa_time, out_time, port->last_out_time);

		// we should use absolute time to prevent reordering caused by rounding errors
		if (out_time < port->last_out_time) {
			debug_log("alsa_out: limiting out_time %lld at %lld", out_time, port->last_out_time);
			out_time = port->last_out_time;
		} else
			port->last_out_time = out_time;

		out_rt.tv_nsec = out_time % NSEC_PER_SEC;
		out_rt.tv_sec = out_time / NSEC_PER_SEC;
		snd_seq_ev_schedule_real(&alsa_event, self->queue, 0, &out_rt);

		err = snd_seq_event_output(self->seq, &alsa_event);
		debug_log("alsa_out: written %d bytes to %s at %+d (%lld): %d", (int)jack_event.size, port->name, (int)frame_offset, out_time, err);
	}
}
コード例 #8
0
ファイル: MidiJack.cpp プロジェクト: BaraMGB/lmms
// we read data from jack
void MidiJack::JackMidiRead(jack_nframes_t nframes)
{
	unsigned int i,b;
	void* port_buf = jack_port_get_buffer(m_input_port, nframes);
	jack_midi_event_t in_event;
	jack_nframes_t event_index = 0;
	jack_nframes_t event_count = jack_midi_get_event_count(port_buf);

	jack_midi_event_get(&in_event, port_buf, 0);
	for(i=0; i<nframes; i++)
	{
		if((in_event.time == i) && (event_index < event_count))
		{
			// lmms is setup to parse bytes coming from a device
			// parse it byte by byte as it expects
			for(b=0;b<in_event.size;b++)
				parseData( *(in_event.buffer + b) );

			event_index++;
			if(event_index < event_count)
				jack_midi_event_get(&in_event, port_buf, event_index);
		}
	}
}
コード例 #9
0
ファイル: JackAudioProvider.hpp プロジェクト: cellux/synthlab
    static int jackProcessCallback(jack_nframes_t nframes, void *arg) {
      JackAudioProvider *jap = static_cast<JackAudioProvider*>(arg);
      Synth *synth = jap->synth_;
      SampleBufferAllocator::reset();
      typename Synth::InputBuffer input;
      typename Synth::OutputBuffer output;
      for (int i=0; i<Synth::InputBuffer::nChannels; i++) {
	jack_default_audio_sample_t *in = (jack_default_audio_sample_t*) jack_port_get_buffer(jap->inputPorts_[i], nframes);
	Sample *buf = input[i];
	std::copy(in,in+nframes,buf);
      }
      void *midiBuf = jack_port_get_buffer(jap->midiInPort_, nframes);
      jack_nframes_t midiEventCount = jack_midi_get_event_count(midiBuf);
      jack_midi_event_t midiEvent;
      for (int i=0; i<midiEventCount; i++) {
	jack_midi_event_get(&midiEvent, midiBuf, i);
	unsigned char midiCommand = *(midiEvent.buffer) & 0xf0;
        //std::cout << "got midi command: " << int(midiCommand) << "\n";
	if (midiEvent.size > 2) {
	  unsigned char midiValue1 = *(midiEvent.buffer+1);
	  unsigned char midiValue2 = *(midiEvent.buffer+2);
	  int delay = midiEvent.time;
	  switch (midiCommand) {
	  case 0x80:
	    synth->noteOff(midiValue1, midiValue2, delay);
	    break;
	  case 0x90:
	    synth->noteOn(midiValue1, midiValue2, delay);
	    break;
          case 0xb0:
            synth->controlChange(jap->midiCtrlMap_[midiValue1], midiValue2);
            break;
          case 0xe0:
            // pitch bend
            synth->controlChange(128, midiValue1 | (midiValue2<<7));
            break;
	  }
	}
      }
      synth->render(nframes, output, input);
      for (int i=0; i<Synth::OutputBuffer::nChannels; i++) {
	jack_default_audio_sample_t *out = (jack_default_audio_sample_t*) jack_port_get_buffer(jap->outputPorts_[i], nframes);
	Sample *buf = output[i];
	std::copy(buf,buf+nframes,out);
      }
      return 0;
    }
コード例 #10
0
ファイル: RtMidiJack.cpp プロジェクト: svn2github/vmpk
int jackProcessIn( jack_nframes_t nframes, void *arg )
{
  JackMidiData *jData = ( (Arguments *) arg )->jackData;
  RtMidiIn :: RtMidiInData *rtData = ( (Arguments *) arg )->rtMidiIn;
  jack_midi_event_t event;
  jack_time_t long long time;

  // Is port created?
  if ( jData->port == NULL ) return 0;
  void *buff = jack_port_get_buffer( jData->port, nframes );

  // We have midi events in buffer
  int evCount = jack_midi_get_event_count( buff );
  if ( evCount > 0 ) {
    RtMidiIn::MidiMessage message;
    message.bytes.clear();

    jack_midi_event_get( &event, buff, 0 );

    for (unsigned int i = 0; i < event.size; i++ )
      message.bytes.push_back( event.buffer[i] );

    // Compute the delta time.
    time = jack_get_time();
    if ( rtData->firstMessage == true )
      rtData->firstMessage = false;
    else
      message.timeStamp = ( time - jData->lastTime ) * 0.000001;

    jData->lastTime = time;

    if ( rtData->usingCallback && !rtData->continueSysex ) {
      RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback;
      callback( message.timeStamp, &message.bytes, rtData->userData );
    }
    else {
      // As long as we haven't reached our queue size limit, push the message.
      if ( rtData->queueLimit > rtData->queue.size() )
        rtData->queue.push( message );
      else
        std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
    }
  }

  return 0;
}
コード例 #11
0
int process(unsigned nframes, void *v)
{
    (void) v;
    float seq_sqr[nframes];
    float seq_noise[nframes];
    float sqr[nframes];
    float noise[nframes];
    float lfo_f_out[nframes];
    float filter_in[nframes];
    float *output = (float*) jack_port_get_buffer(port, nframes);
	
    void *josc_buf = jack_port_get_buffer(josc, nframes);
    jack_midi_event_t in_event;
	jack_nframes_t event_count = jack_midi_get_event_count(josc_buf);
    // tag::buf-read[]
	if(event_count)
	{
		for(unsigned i=0; i<event_count; i++)
		{
			jack_midi_event_get(&in_event, josc_buf, i);
            assert(*in_event.buffer == '/');
            RtDataImpl d;
            ports.dispatch((char*)in_event.buffer+1, d);
		}
	}

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


    gen_seq(seq_sqr, seq_noise, &seq, nframes);
    gen_noise(noise, seq_noise, nframes);
    gen_square(sqr, seq_sqr, &osc, nframes);
    gen_lfo(lfo_f_out, &lfo, nframes);
    do_sum(filter_in, noise, sqr, nframes);
    do_filter(output, filter_in, lfo_f_out, &filter, nframes);
    return 0;
}
コード例 #12
0
ファイル: midibuffer.cpp プロジェクト: cybercatalyst/qtjack
MidiEvent MidiBuffer::readEvent(int index, bool *ok) {
    if(!isValid()) {
        if(ok) {
            (*ok) = false;
        }
        return MidiEvent();
    }

    MidiEvent midiEvent;
    bool success = (jack_midi_event_get(
        &midiEvent,
        _jackBuffer,
        index) == 0);

    if(ok) {
        (*ok) = success;
    }

    return midiEvent;
}
コード例 #13
0
ファイル: jackoutput.C プロジェクト: BackupTheBerlios/horgand
int jackprocess(jack_nframes_t nframes,void *arg)

{

 int i,j,count;
 

jack_midi_event_t midievent;

   jack_default_audio_sample_t *outl = (jack_default_audio_sample_t*)
   jack_port_get_buffer(outport_left, JackOUT->PERIOD);
   jack_default_audio_sample_t *outr = (jack_default_audio_sample_t*)
   jack_port_get_buffer(outport_right, JackOUT->PERIOD);
   
   float *data = (float *)jack_port_get_buffer(jack_midi_in, JackOUT->PERIOD);

pthread_mutex_lock(&jmutex);


count = jack_midi_get_event_count(data);

for (int i = 0; i < count; i++)
{                  
  jack_midi_event_get(&midievent, data, i);
  JackOUT->jack_process_midievents(&midievent);
}  

JackOUT->Alg1s(JackOUT->PERIOD,0);

for (i=0; i<JackOUT->PERIOD; i++)
{
 j = i*2;
 outl[i]=JackOUT->buf[j]*JackOUT->Master_Volume;
 outr[i]=JackOUT->buf[j+1]*JackOUT->Master_Volume;
}

pthread_mutex_unlock(&jmutex);

return(0);

};
コード例 #14
0
ファイル: midi-jack.c プロジェクト: 0438snappy/mididuino
void midiMainLoop(void) {
      fprintf (stderr, "midiMainLoop\n");

  jack_midi_event_t input_event; 

  int timeout = 10*1000*1000+time_us(); // 10 seconds in microseconds
//int exitMainLoop = 0;
  while (!exitMainLoop) {
    jack_nframes_t nframes = jack_cycle_wait(jack_client);
    /* Get input and output buffer pointers. */
    void* input_buf = jack_port_get_buffer (jack_midi_input_port, nframes);
    //void* output_buf = jack_port_get_buffer (jack_midi_output_port, nframes);

    jack_nframes_t input_event_count = jack_midi_get_event_count(input_buf);
    if (input_event_count>0) {
      unsigned int event_index = 0;
      for (;event_index<input_event_count;event_index++) {
	if (0==jack_midi_event_get(&input_event, input_buf, event_index)) {
	  if (input_event.size > 0) {

	printhex("receive:", input_event.buffer,input_event.size);

	    int i = 0;
	    for (; i < input_event.size; i++) {
	      midiReceive(input_event.buffer[i]);
	    }
	  }
        }
      }
    } 

    if (time_us() > timeout) {
        fprintf(stderr, "timeout\n");
	exit(1);
    }
  }

  jack_end();
      fprintf (stderr, "midiMainLoop:end\n");
}
コード例 #15
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;
}
コード例 #16
0
ファイル: ms.cpp プロジェクト: Mistobaan/MuseScore
static int process(jack_nframes_t nframes, void*)
      {
      void*  mi = jack_port_get_buffer(input_port, nframes);
      float* lb = (float *) jack_port_get_buffer (output_portL, nframes);
      float* rb = (float *) jack_port_get_buffer (output_portR, nframes);

      jack_nframes_t event_count = jack_midi_get_event_count(mi);
      for (int i = 0; i < event_count; i++) {
            jack_midi_event_t event;
            jack_midi_event_get(&event, mi, i);
            int type = *(event.buffer) & 0xf0;
            if (type == 0x90)
                  synth->play(Event(ME_NOTEON, 0, *(event.buffer+1), *(event.buffer+2)));
            else if (type == 0x80)
                  synth->play(Event(ME_NOTEON, 0, *(event.buffer+1), 0));
            else if (type == ME_CONTROLLER)
                  synth->play(Event(ME_CONTROLLER, 0, *(event.buffer+1), *(event.buffer+2)));

            }
      synth->process(nframes, lb, rb, 1);
      return 0;
      }
コード例 #17
0
ファイル: jackio.c プロジェクト: UIKit0/calfbox
static int copy_midi_data_to_buffer(jack_port_t *port, int buffer_size, struct cbox_midi_buffer *destination)
{
    void *midi = jack_port_get_buffer(port, buffer_size);
    if (!midi)
        return 0;
    uint32_t event_count = jack_midi_get_event_count(midi);

    cbox_midi_buffer_clear(destination);
    for (uint32_t i = 0; i < event_count; i++)
    {
        jack_midi_event_t event;
        
        if (!jack_midi_event_get(&event, midi, i))
        {
            if (!cbox_midi_buffer_write_event(destination, event.time, event.buffer, event.size))
                return -i;
        }
        else
            return -i;
    }
    
    return event_count;
}
コード例 #18
0
ファイル: jackmidi.cpp プロジェクト: ViktorNova/los
void MidiJackDevice::collectMidiEvents()/*{{{*/
{
    if (!_readEnable)
        return;

    if (!_in_client_jackport) // p3.3.55
        return;

    void* port_buf = jack_port_get_buffer(_in_client_jackport, segmentSize); // p3.3.55

    jack_midi_event_t event;
    jack_nframes_t eventCount = jack_midi_get_event_count(port_buf);
    for (jack_nframes_t i = 0; i < eventCount; ++i)
    {
        jack_midi_event_get(&event, port_buf, i);

#ifdef JACK_MIDI_DEBUG
        printf("MidiJackDevice::collectMidiEvents number:%d time:%d\n", i, event.time);
#endif

        eventReceived(&event);
    }
}/*}}}*/
コード例 #19
0
ファイル: main.cpp プロジェクト: JonasNorling/jacksynth
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;
}
コード例 #20
0
ファイル: synthpod_jack.c プロジェクト: foren197316/synthpod
// 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;
}
コード例 #21
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;
}
コード例 #22
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;
}
コード例 #23
0
ファイル: midi_latency_test.c プロジェクト: Andux/jack2
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;
}
コード例 #24
0
void
process_midi_input (jack_nframes_t nframes)
{
   static int time_of_first_event = -1;
   int /*read,*/ events, i, channel;
   jack_midi_event_t event;
   int last_frame_time = jack_last_frame_time(jack_client);
   void * port_buffer = jack_port_get_buffer(input_port, nframes);
   if (port_buffer == NULL)
   {
      warn_from_jack_thread_context
      (
         "jack_port_get_buffer failed, cannot receive anything."
      );
      return;
   }

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

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

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

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

      smf_event = smf_event_new_from_pointer(event.buffer, event.size);
      if (smf_event == NULL)
      {
         warn_from_jack_thread_context
         (
            "smf_event_from_pointer failed, RECEIVED NOTE LOST."
         );
         continue;
      }
//    assert(smf_event->midi_buffer_length >= 1);
      channel = smf_event->midi_buffer[0] & 0x0F;
      smf_track_add_event_seconds
      (
         tracks[channel], smf_event,
         nframes_to_seconds
         (
            jack_last_frame_time(jack_client) + event.time - time_of_first_event
         )
      );
   }
}
コード例 #25
0
    void jackProcess(const jack_nframes_t nframes)
    {
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
        const float* audioIns[DISTRHO_PLUGIN_NUM_INPUTS];

        for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
            audioIns[i] = (const float*)jack_port_get_buffer(fPortAudioIns[i], nframes);
#else
        static const float** audioIns = nullptr;
#endif

#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
        float* audioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS];

        for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
            audioOuts[i] = (float*)jack_port_get_buffer(fPortAudioOuts[i], nframes);
#else
        static float** audioOuts = nullptr;
#endif

#if DISTRHO_PLUGIN_WANT_TIMEPOS
        jack_position_t pos;
        fTimePosition.playing = (jack_transport_query(fClient, &pos) == JackTransportRolling);

        if (pos.unique_1 == pos.unique_2)
        {
            fTimePosition.frame = pos.frame;

            if (pos.valid & JackTransportBBT)
            {
                fTimePosition.bbt.valid = true;

                fTimePosition.bbt.bar  = pos.bar;
                fTimePosition.bbt.beat = pos.beat;
                fTimePosition.bbt.tick = pos.tick;
                fTimePosition.bbt.barStartTick = pos.bar_start_tick;

                fTimePosition.bbt.beatsPerBar = pos.beats_per_bar;
                fTimePosition.bbt.beatType    = pos.beat_type;

                fTimePosition.bbt.ticksPerBeat   = pos.ticks_per_beat;
                fTimePosition.bbt.beatsPerMinute = pos.beats_per_minute;
            }
            else
                fTimePosition.bbt.valid = false;
        }
        else
        {
            fTimePosition.bbt.valid = false;
            fTimePosition.frame = 0;
        }

        fPlugin.setTimePosition(fTimePosition);
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
        void* const midiBuf = jack_port_get_buffer(fPortMidiIn, nframes);

        if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf))
        {
            uint32_t  midiEventCount = 0;
            MidiEvent midiEvents[eventCount];

            jack_midi_event_t jevent;

            for (uint32_t i=0; i < eventCount; ++i)
            {
                if (jack_midi_event_get(&jevent, midiBuf, i) != 0)
                    break;

                MidiEvent& midiEvent(midiEvents[midiEventCount++]);

                midiEvent.frame = jevent.time;
                midiEvent.size  = jevent.size;

                if (midiEvent.size > MidiEvent::kDataSize)
                    midiEvent.dataExt = jevent.buffer;
                else
                    std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size);
            }

            fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount);
        }
        else
        {
            fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0);
        }
#else
        fPlugin.run(audioIns, audioOuts, nframes);
#endif
    }
コード例 #26
0
ファイル: ModeHandler.cpp プロジェクト: audetto/asisynth
    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);
	  }
	}
      }
    }
コード例 #27
0
ファイル: main.c プロジェクト: shdawson/setBfree
int jack_audio_callback (jack_nframes_t nframes, void *arg) {
  jack_default_audio_sample_t **out = j_output_bufferptrs;
  int i;

  void *jack_midi_buf = NULL;
  int midi_events = 0;
  jack_nframes_t midi_tme_proc = 0;

  if (!synth_ready) {
    for (i=0;i<AUDIO_CHANNELS;i++) {
      out[i] = (jack_default_audio_sample_t*) jack_port_get_buffer (j_output_port[i], nframes);
      memset(out[i], 0, nframes*sizeof(jack_default_audio_sample_t));
    }
    return (0);
  }

  if (use_jack_midi) {
    jack_midi_buf = jack_port_get_buffer(jack_midi_port, nframes);
    midi_events = jack_midi_get_event_count(jack_midi_buf);
  }

  for (i=0;i<AUDIO_CHANNELS;i++) {
    out[i] = (jack_default_audio_sample_t*) jack_port_get_buffer (j_output_port[i], nframes);
  }

  static int boffset = BUFFER_SIZE_SAMPLES;

  jack_nframes_t written = 0;

  while (written < nframes) {
    int nremain = nframes - written;

    if (boffset >= BUFFER_SIZE_SAMPLES)  {
      if (use_jack_midi) {
	for (i=0; i<midi_events; i++) {
	  jack_midi_event_t ev;
	  jack_midi_event_get(&ev, jack_midi_buf, i);
	  if (ev.time >= written && ev.time < (written + BUFFER_SIZE_SAMPLES))
	    parse_raw_midi_data(arg, ev.buffer, ev.size);
	}
	midi_tme_proc = written + BUFFER_SIZE_SAMPLES;
      }
      boffset = 0;
      oscGenerateFragment (inst.synth, bufA, BUFFER_SIZE_SAMPLES);
      preamp (inst.preamp, bufA, bufB, BUFFER_SIZE_SAMPLES);
      reverb (inst.reverb, bufB, bufC, BUFFER_SIZE_SAMPLES);

#ifdef HAVE_ZITACONVOLVE
      whirlProc2(inst.whirl,
	  bufC,
	  NULL, NULL,
	  bufH[0], bufH[1],
	  bufD[0], bufD[1],
	  BUFFER_SIZE_SAMPLES);

      const float *horn[2] = { bufH[0], bufH[1] };
      const float *drum[2] = { bufD[0], bufD[1] };
      float *out[2] = { bufJ[0], bufJ[1] };

      convolve(horn, out, 2, BUFFER_SIZE_SAMPLES);
      mixdown(out, drum, AUDIO_CHANNELS, BUFFER_SIZE_SAMPLES);
#else
      whirlProc(inst.whirl, bufC, bufJ[0], bufJ[1], BUFFER_SIZE_SAMPLES);
#endif
    }

    int nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - boffset));

    for (i=0;i< AUDIO_CHANNELS; i++) {
      memcpy(&out[i][written], &bufJ[i][boffset], nread*sizeof(float));
    }
    written+=nread;
    boffset+=nread;
  }

  if (use_jack_midi) {
    /* process remaining MIDI events
     * IF nframes < BUFFER_SIZE_SAMPLES OR nframes != N * BUFFER_SIZE_SAMPLES
     */
    for (i=0; i<midi_events; i++) {
      jack_midi_event_t ev;
      jack_midi_event_get(&ev, jack_midi_buf, i);
      if (ev.time >= midi_tme_proc)
	parse_raw_midi_data(arg, ev.buffer, ev.size);
    }
  }

  return(0);
}