#include #include #include #include #include #include #include "defines.h" #include "globals.h" #include "jack.h" using namespace std; //#define DO_DEBUGGING_EVENTS jack_port_t *midi_in; jack_port_t *out_port[N_CHANNELS]; #ifdef STEREO jack_port_t *out_port2[N_CHANNELS]; #endif jack_client_t *jack_client = NULL; void maybe_calc_stuff() //TODO woandershinschieben? lfo.cpp oder so? { static int lfocnt=0; static int snhcnt=0; if (lfocnt==0) { lfocnt=lfo_update_frames; for (int i=0;i history; list::iterator it; float now=float(jack_get_time())/1000000; cout << "got an XRUN! if this happens too often, consider reducing CPU usage, for\n example by setting a voice limit or by quitting other programs"<= xrun_n) { cout << "PANIC -- TOO MANY XRUNs! killing all voices" << endl<panic(); history.clear(); } return 0; } #define IGNORE_MIDI_OFFSET int process_callback(jack_nframes_t nframes, void *notused) { #ifdef DO_DEBUGGING_EVENTS static jack_nframes_t tmp=0, tmp2=0; #endif static jack_nframes_t next_cleanup=0; size_t curr_event=0, n_events, i, chan; void *inport; jack_default_audio_sample_t *outbuf[N_CHANNELS]; #ifdef STEREO jack_default_audio_sample_t *outbuf2[N_CHANNELS]; #endif jack_midi_event_t event; jack_nframes_t lastframe; lastframe=jack_last_frame_time(jack_client); if (nframes <= 0) { output_note ("NOTE: Process callback called with nframes = 0; bug in JACK?"); return 0; } for (i=0;i=next_cleanup) { next_cleanup=lastframe+cleanup_interval; for (i=0;icleanup(); } #ifdef DO_DEBUGGING_EVENTS if (tmp==0) //DEBUG !!! { tmp=lastframe; channel[0]->set_controller(5,10); channel[0]->set_controller(65,127); channel[0]->event(0x90,80,64); // channel[0]->event(0x90,84,64); } else if (tmp2==0) { if (lastframe>tmp+44100*2) { tmp2=1; cout << "BÄÄM" << endl; channel[0]->event(0x90,84,64); } } else if (tmp2==1) { if (lastframe>tmp+44100*4) { tmp2=2; channel[0]->event(0x90,87,5); channel[0]->set_controller(57, 127); cout << "BÄÄM2" << endl; } } else { if (lastframe>tmp+44100*10) { cout << "finished" << endl; exit(0); } } #endif #ifdef FRAMESKIP if (outtemp_nframes_left) { jack_nframes_t real_nframes; if (outtemp_nframes_left > nframes) { real_nframes=nframes; outtemp_nframes_left-=nframes; } else { real_nframes=outtemp_nframes_left; outtemp_nframes_left=0; } for (i=0;i=event.time)) { output_verbose("processing event #"+IntToStr(curr_event)+" of "+IntToStr(n_events)+" events"); if (event.size > 3) { output_verbose(" Ignoring MIDI message longer than three bytes, probably a SysEx."); } else { chan=event.buffer[0] & 0x0F; output_verbose(" channel="+IntToStr(chan)+", data is "+IntToStrHex(event.buffer[0])+" "+IntToStrHex(event.buffer[1])+" "+IntToStrHex(event.buffer[2])); channel[chan]->event(event.buffer[0], event.buffer[1], event.buffer[2]); } n_events--; curr_event++; //as long as there are some events left and getting one fails, get the next while ((n_events) && (jack_midi_event_get(&event, inport, curr_event /*, nframes */))) { output_note("NOTE: lost a note :("); n_events--; curr_event++; } } maybe_calc_stuff(); for (int j=0;jget_sample())/ONE*VOL_FACTOR; #else jack_default_audio_sample_t sample=jack_default_audio_sample_t(channel[j]->get_sample())/ONE*VOL_FACTOR; outbuf[j][i]=channel[j]->balL*sample; outbuf2[j][i]=channel[j]->balR*sample; #endif // if the above changes, (1) must also change #ifdef FRAMESKIP for (size_t k=i+frameskip-1;k>i;k--) { outbuf[j][k]=outbuf[j][i]; #ifdef STEREO outbuf2[j][k]=outbuf2[j][i]; #endif } #endif } } #ifdef FRAMESKIP if (i!=nframes) // nicht aufgegangen? { for (int j=0;jget_sample())/ONE*VOL_FACTOR; #else jack_default_audio_sample_t sample=jack_default_audio_sample_t(channel[j]->get_sample())/ONE*VOL_FACTOR; outtemp[j]=channel[j]->balL*sample; outtemp2[j]=channel[j]->balR*sample; #endif } outtemp_nframes_left=frameskip-nframes+i; for (i=i; i