Fixed problematic, wrong jack transport things.
[epichord.git] / src / jack.cpp
blob62c87f6973306cb45db628a60455d8d95c6fcbb6
1 /*
2 Epichord - a midi sequencer
3 Copyright (C) 2008 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
23 #include <stdio.h>
24 #include <string.h>
26 #include <vector>
27 #include <string>
29 #include <pthread.h>
30 #include <jack/jack.h>
31 #include <jack/types.h>
32 #include <jack/ringbuffer.h>
33 #include <jack/midiport.h>
34 #include <jack/transport.h>
36 #define HAVE_LASH
38 #ifdef HAVE_LASH
39 #include <lash/lash.h>
40 lash_client_t* lash_client;
41 #endif
43 #include "seq.h"
44 #include "backend.h"
46 //#include "uihelper.h"
48 //#include "ui.h"
50 #define PORT_COUNT 8
52 //#define HAVE_LASH
54 extern std::vector<track*> tracks;
56 jack_client_t* client;
58 jack_port_t* outport[PORT_COUNT];
59 jack_port_t* inport;
60 void* pbo[PORT_COUNT];
61 void* pbi;
63 jack_ringbuffer_t* outbuf;
64 jack_ringbuffer_t* inbuf;
66 static int playing = 0;
67 static int looping = 0;
68 static int recording=0;
69 static int loop_start = 0;
70 static int loop_end = TICKS_PER_BEAT*4;
71 static int passthru = 1;
72 static int rec_port = 0;
73 static int trackinit = 1;
75 static int init_chans = 1;
77 static uint64_t cur_frame = 0;
78 static uint64_t last_frame = 0;
79 static int frame_jump = 0;
80 static int cur_tick;
81 static int last_tick;
82 static int bpm = 120;
83 static int new_bpm = 120;
84 static int tpb = TICKS_PER_BEAT;
85 static int sample_rate = 0;
86 static int frame_count = 0;
88 #define t2f(X) ((uint64_t)X*60*sample_rate/(bpm*tpb))
89 #define f2t(X) ((uint64_t)X*bpm*tpb/(sample_rate*60))
96 /* callback for seq.c and play.c */
97 void dispatch_event(mevent* e, int track, int tick_base){
99 jack_midi_data_t* md;
101 int p = tracks[track]->port;
102 int c = tracks[track]->chan;
104 //uint64_t base = t2f(tick_base);
105 //uint64_t frame = t2f(e->tick) + base - last_frame + frame_jump;
106 uint64_t eframe = t2f((uint64_t)(e->tick+tick_base));
107 uint64_t frame = eframe - last_frame + frame_jump;
109 if(e->type == -1){//dummy events
110 return;
113 if(looping && e->tick+tick_base == loop_end && e->type != MIDI_NOTE_OFF){
114 //dispatch only note off events on a loop_end
115 return;
118 //printf("%d %d %d %llu %llu %llu\n",e->tick,tick_base,e->tick+tick_base, eframe, last_frame, frame);
120 if(eframe < last_frame){
121 printf("dispatch: %llu %llu negative frame index. BOOM segfault.\n", t2f(e->tick+tick_base), last_frame);
122 return;
125 if(frame == frame_count){
126 //printf("dispatch: scheduling bug. frame index == frame count.\n");
127 frame--;
130 unsigned char buf[3];
131 size_t n;
132 if(midi_encode(e,c,buf,&n) < 0){
133 return;
136 md = jack_midi_event_reserve(pbo[p],frame,n);
137 if(md == NULL){
138 md = jack_midi_event_reserve(pbo[p],frame_count-1,n);
139 if(md == NULL){
140 printf("dispatch: can't reserve midi event.\n");
141 return;
143 printf("dispatch: send midi using scheduling kludge.\n");
145 for(int i=0; i<n; i++){
146 md[i] = buf[i];
153 /* jack callbacks */
157 static int H = 1;
158 static int process(jack_nframes_t nframes, void* arg){
160 frame_count = nframes;
162 //handle incoming midi events
163 for(int i=0; i<PORT_COUNT; i++){
164 pbo[i] = jack_port_get_buffer(outport[i],nframes);
165 jack_midi_clear_buffer(pbo[i]);
167 pbi = jack_port_get_buffer(inport,nframes);
169 jack_midi_data_t* md1;
170 jack_midi_data_t* md2;
172 jack_midi_event_t me;
174 uint32_t rec_tick;
176 for(int i=0; i<jack_midi_get_event_count(pbi); i++){
177 jack_midi_event_get(&me,pbi,i);
178 md1 = me.buffer;
179 //printf("%d got midi event, type 0x%x, value 0x%x 0x%x\n",i,md1[0],md1[1],md1[2]);
180 if(passthru){
181 md2 = jack_midi_event_reserve(pbo[rec_port],0,me.size);
182 if(md2 == NULL){
183 printf("passthru: can't reserve midi event\n");
185 else{
186 memcpy(md2,md1,me.size);
189 rec_tick = last_tick + (me.time*bpm*tpb)/(sample_rate*60);
191 //if(playing && recording){
192 uint16_t size = me.size;
193 jack_ringbuffer_write(inbuf,(char*)&rec_tick,4);
194 jack_ringbuffer_write(inbuf,(char*)&size,2);
195 jack_ringbuffer_write(inbuf,(char*)md1,me.size);
196 // }
199 //init chans
200 if(init_chans && trackinit && playing){
201 init_chans=0;
202 char buf[3];
203 for(int j=0; j<tracks.size(); j++){
204 int ch = tracks[j]->chan;
205 int pt = tracks[j]->port;
207 //bank select
208 buf[0] = 0xB0 | ch;
209 buf[1] = 0;
210 buf[2] = tracks[j]->bank;
211 send_midi(buf,3,pt);
213 //program change
214 buf[0] = 0xC0 | ch;
215 buf[1] = tracks[j]->prog;
216 send_midi(buf,2,pt);
218 //channel volume
219 buf[0] = 0xB0 | ch;
220 buf[1] = 7;
221 buf[2] = tracks[j]->vol;
222 send_midi(buf,3,pt);
224 //channel pan
225 buf[0] = 0xB0 | ch;
226 buf[1] = 10;
227 buf[2] = tracks[j]->pan;
228 send_midi(buf,3,pt);
233 //handle outgoing immediate midi events
234 uint16_t n;
235 char p;
236 char buf[1024];
237 while(jack_ringbuffer_read_space(outbuf) > 0){
238 jack_ringbuffer_read(outbuf,&p,1);
239 jack_ringbuffer_read(outbuf,(char*)&n,2);
240 jack_ringbuffer_read(outbuf,buf,n);
241 md1 = jack_midi_event_reserve(pbo[p],0,n);
242 if(md1 == NULL){
243 printf("gui: can't reserve midi event\n");
244 break;
246 for(int i=0; i<n; i++){
247 md1[i]=buf[i];
252 //play
253 if(playing){
254 if(bpm != new_bpm){
255 if(new_bpm != 0){
256 bpm = new_bpm;
258 else{
259 printf("process: someone set the bpm to zero!\n");
260 bpm = 120;
262 cur_frame = t2f(cur_tick);
263 last_frame = t2f(last_tick);
266 last_frame = cur_frame;
267 cur_frame += nframes;
268 last_tick = cur_tick;
269 cur_tick = f2t(cur_frame);
270 frame_jump = 0;
271 int le = loop_end;
272 int ls = loop_start;
273 int lf = looping;
276 /* this only handles the case where the nframes covers the
277 loop boundary once. a more robust way would split it into
278 before covering n loop boundaries, a loop for n looping regions,
279 and a final section covering part of the loop region. this
280 would only need to be used for insanely high bpm */
281 if(lf && last_tick < le && cur_tick > le ){
282 //printf("split l%d m%d r%d\n",last_tick,loop_end,cur_tick);
283 int split_frame = t2f(le) - last_frame + 1;
284 int left_over = nframes - split_frame;
285 int jump = split_frame;
286 cur_frame = last_frame + jump;
287 cur_tick = f2t(cur_frame);
288 //printf("cur tick %d\n",cur_tick);
289 play_seq(cur_tick);
291 reset_backend(ls);
292 //printf("cur tick %d\n",cur_tick);
293 frame_jump = jump;
294 last_frame = t2f(ls);
295 cur_frame = last_frame + left_over;
296 cur_tick = f2t(cur_frame);
298 play_seq(cur_tick);
300 else if(lf && cur_tick > le){
301 reset_backend(ls);
302 last_frame = t2f(ls);
303 cur_frame = last_frame + nframes;
304 cur_tick = f2t(cur_frame);
305 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
306 play_seq(cur_tick);
308 else{
309 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
310 play_seq(cur_tick);
314 return 0;
321 /* backend api wrapper */
323 int init_backend(int* argc, char*** argv){
325 client = jack_client_open("Epichord",(jack_options_t)0,NULL);
326 if(client == NULL){
327 printf("init_backend: failure to open jack client\n");
328 return -1;
331 jack_set_process_callback(client, process, NULL);
333 char buf[64];
334 for(int i=0; i<PORT_COUNT; i++){
335 sprintf(buf,"midi out %d",i);
336 outport[i]=jack_port_register(client,buf,JACK_DEFAULT_MIDI_TYPE,JackPortIsOutput,0);
339 inport=jack_port_register(client, "midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
341 outbuf = jack_ringbuffer_create(1024);
342 inbuf = jack_ringbuffer_create(1024);
344 sample_rate = jack_get_sample_rate(client);
346 jack_activate(client);
348 #ifdef HAVE_LASH
350 lash_client = lash_init(lash_extract_args(argc, argv), "Epichord",
351 LASH_Config_File, LASH_PROTOCOL( 2, 0 ));
352 if(!lash_client){
353 printf("init_backend: lash failed to initialize\n");
355 else{
356 lash_jack_client_name(lash_client, "Epichord");
359 #endif
361 return 0;
367 int shutdown_backend(){
368 pause_backend();
369 all_notes_off();
370 sleep(1);
371 jack_deactivate(client);
372 //sleep(1);
373 return 0;
377 int start_backend(){
378 playing = 1;
379 jack_transport_start(client);
382 int pause_backend(){
383 playing = 0;
384 jack_transport_stop(client);
387 int reset_backend(int tick){
388 if(tick==0){
389 init_chans = 1;
391 cur_frame = t2f(tick);
392 last_frame = cur_frame;
393 last_tick = tick;
394 cur_tick = tick;
395 set_seq_pos(tick);
397 jack_transport_locate(client, t2f(tick));
401 void toggle_backend_recording(){
402 if(recording){
403 recording = 0;
405 else{
406 recording = 1;
411 //send a midi event from the gui thread
412 void send_midi(char* raw, uint16_t n, uint8_t port){
413 if(n>1024){
414 printf("send_midi: cant send, immediate message too big\n");
415 return;
417 char buf[2048];
418 buf[0] = port;
419 memcpy(buf+1,&n,2);
420 memcpy(buf+3,raw,n);
421 //FIXME check return value
422 jack_ringbuffer_write(outbuf,buf,3+n);
425 void send_midi_local(char* raw, uint16_t n){
426 uint32_t tick = cur_tick;
427 uint16_t size = n;
428 //FIXME chec return value
429 jack_ringbuffer_write(inbuf,(char*)&tick,4);
430 jack_ringbuffer_write(inbuf,(char*)&size,2);
431 jack_ringbuffer_write(inbuf,raw,n);
436 std::string sysexbuf;
437 //get next incoming midi event for gui thread
438 int recv_midi(int* chan, int* tick, int* type, int* val1, int* val2){
439 uint16_t n;
440 uint32_t t;
441 unsigned char* buf;
442 if(jack_ringbuffer_read(inbuf,(char*)&t,4) == 0){
443 return 0;
445 jack_ringbuffer_read(inbuf,(char*)&n,2);
446 buf = (unsigned char*)malloc(n);
447 jack_ringbuffer_read(inbuf,(char*)buf,n);
449 *tick = t;
450 *chan = buf[0]&0x0f;
451 *type = buf[0]&0xf0;
452 *val1 = buf[1];
453 *val2 = buf[2];
455 char hbuf[8];
457 if (buf[0]==0xf0){
458 sysexbuf = "";
459 for(int i=2; i<n-1; i++){
460 snprintf(hbuf,8,"%02x ",buf[i]);
461 sysexbuf.append(hbuf);
465 free(buf);
466 return 1;
469 const char* getsysexbuf(){
470 return sysexbuf.c_str();
474 void all_notes_off(){
475 for(int i=0; i<tracks.size(); i++){
476 midi_track_off(i);
480 void program_change(int track, int prog){
481 int port = tracks[track]->port;
482 int chan = tracks[track]->chan;
484 char buf[2];
485 buf[0] = 0xC0 | chan;
486 buf[1] = prog;
487 send_midi(buf, 2, port);
490 void midi_bank_controller(int track, int bank){
491 int port = tracks[track]->port;
492 int chan = tracks[track]->chan;
494 char buf[3];
495 buf[0] = 0xB0 | chan;
496 buf[1] = 0;
497 buf[2] = bank;
498 send_midi(buf, 3, port);
501 void midi_volume_controller(int track, int vol){
502 int port = tracks[track]->port;
503 int chan = tracks[track]->chan;
505 char buf[3];
506 buf[0] = 0xB0 | chan;
507 buf[1] = 7;
508 buf[2] = vol;
509 send_midi(buf, 3, port);
512 void midi_pan_controller(int track, int pan){
513 int port = tracks[track]->port;
514 int chan = tracks[track]->chan;
516 char buf[3];
517 buf[0] = 0xB0 | chan;
518 buf[1] = 10;
519 buf[2] = pan;
520 send_midi(buf, 3, port);
523 void midi_expression_controller(int track, int expr){
524 int port = tracks[track]->port;
525 int chan = tracks[track]->chan;
527 char buf[3];
528 buf[0] = 0xB0 | chan;
529 buf[1] = 11;
530 buf[2] = expr;
531 send_midi(buf, 3, port);
535 void midi_note_off(int note, int chan, int port){
536 char buf[3];
537 buf[0] = 0x80 | chan;
538 buf[1] = note;
539 buf[2] = 0x00;
540 send_midi(buf,3,port);
543 void midi_track_off(int track){
544 int chan = tracks[track]->chan;
545 int port = tracks[track]->port;
547 midi_channel_off(chan,port);
550 void midi_channel_off(int chan, int port){
551 char buf[3] = {0xB0,123,0};
552 buf[0] = 0xB0 | chan;
553 send_midi(buf,3,port);
555 buf[0] = 0xB0 | chan;
556 buf[1] = 120;
557 send_midi(buf,3,port);
561 void backend_set_trackinit(int v){
562 trackinit = v;
564 void backend_set_passthru(int v){
565 passthru = v;
568 void set_loop_start(int tick){
569 loop_start = tick;
572 void set_loop_end(int tick){
573 loop_end = tick;
576 int get_loop_start(){
577 return loop_start;
580 int get_loop_end(){
581 return loop_end;
584 int get_play_position(){
585 return cur_tick;
588 int solo;
589 void set_solo(int s){
590 solo = s;
593 int get_solo(){
594 return solo;
597 int is_backend_playing(){
598 return playing;
601 int is_backend_recording(){
602 return recording&&playing;
605 void toggle_loop(){
606 if(looping){
607 looping = 0;
609 else{
610 looping = 1;
615 void set_bpm(int n){
616 new_bpm = n;
619 void set_rec_port(int n){
620 rec_port = n;
624 char* session_string;
625 int backend_session_process(){
626 int ret = SESSION_NOMORE;
627 #ifdef HAVE_LASH
628 lash_event_t *e;
630 char *name;
632 e = lash_get_event(lash_client);
633 if(!e){
634 return SESSION_NOMORE;
637 asprintf(&session_string,"%s",lash_event_get_string(e));
638 const int t = lash_event_get_type (e);
640 switch(t)
642 case LASH_Save_File:
643 printf("session_process: LASH save\n");
644 lash_send_event(lash_client, lash_event_new_with_type(LASH_Save_File));
645 ret = SESSION_SAVE;
646 break;
647 case LASH_Restore_File:
648 printf("session_process: LASH load\n");
649 lash_send_event(lash_client, lash_event_new_with_type(LASH_Restore_File));
650 ret = SESSION_LOAD;
651 break;
652 case LASH_Quit:
653 printf("session_process: LASH quit\n");
654 ret = SESSION_QUIT;
655 break;
656 default:
657 printf("session_process: unhandled LASH event (%d)\n", t);
658 switch(t){
659 case LASH_Client_Name: printf("LASH_Client_Name\n"); break;
660 case LASH_Jack_Client_Name: printf("LASH_Jack_Client_Name\n"); break;
661 case LASH_Alsa_Client_ID: printf("LASH_Alsa_Client_ID\n"); break;
662 case LASH_Save_File: printf("LASH_Save_File\n"); break;
663 case LASH_Save_Data_Set: printf("LASH_Save_Data_Set\n"); break;
664 case LASH_Restore_Data_Set: printf("LASH_Restore_Data_Set\n"); break;
665 case LASH_Save: printf("LASH_Save\n"); break;
667 ret = SESSION_UNHANDLED;
668 break;
670 //lash_event_destroy(e);
671 #endif
672 return ret;
675 char* get_session_string(){
676 return session_string;