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
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>
39 #include <lash/lash.h>
40 lash_client_t
* lash_client
;
46 //#include "uihelper.h"
54 extern std::vector
<track
*> tracks
;
56 jack_client_t
* client
;
58 jack_port_t
* outport
[PORT_COUNT
];
60 void* pbo
[PORT_COUNT
];
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;
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
){
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
113 if(looping
&& e
->tick
+tick_base
== loop_end
&& e
->type
!= MIDI_NOTE_OFF
){
114 //dispatch only note off events on a loop_end
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
);
125 if(frame
== frame_count
){
126 //printf("dispatch: scheduling bug. frame index == frame count.\n");
130 unsigned char buf
[3];
132 if(midi_encode(e
,c
,buf
,&n
) < 0){
136 md
= jack_midi_event_reserve(pbo
[p
],frame
,n
);
138 md
= jack_midi_event_reserve(pbo
[p
],frame_count
-1,n
);
140 printf("dispatch: can't reserve midi event.\n");
143 printf("dispatch: send midi using scheduling kludge.\n");
145 for(int i
=0; i
<n
; i
++){
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
;
176 for(int i
=0; i
<jack_midi_get_event_count(pbi
); i
++){
177 jack_midi_event_get(&me
,pbi
,i
);
179 //printf("%d got midi event, type 0x%x, value 0x%x 0x%x\n",i,md1[0],md1[1],md1[2]);
181 md2
= jack_midi_event_reserve(pbo
[rec_port
],0,me
.size
);
183 printf("passthru: can't reserve midi event\n");
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
);
200 if(init_chans
&& trackinit
&& playing
){
203 for(int j
=0; j
<tracks
.size(); j
++){
204 int ch
= tracks
[j
]->chan
;
205 int pt
= tracks
[j
]->port
;
210 buf
[2] = tracks
[j
]->bank
;
215 buf
[1] = tracks
[j
]->prog
;
221 buf
[2] = tracks
[j
]->vol
;
227 buf
[2] = tracks
[j
]->pan
;
233 //handle outgoing immediate midi events
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
);
243 printf("gui: can't reserve midi event\n");
246 for(int i
=0; i
<n
; i
++){
259 printf("process: someone set the bpm to zero!\n");
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
);
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);
292 //printf("cur tick %d\n",cur_tick);
294 last_frame
= t2f(ls
);
295 cur_frame
= last_frame
+ left_over
;
296 cur_tick
= f2t(cur_frame
);
300 else if(lf
&& cur_tick
> le
){
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);
309 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
321 /* backend api wrapper */
323 int init_backend(int* argc
, char*** argv
){
325 client
= jack_client_open("Epichord",(jack_options_t
)0,NULL
);
327 printf("init_backend: failure to open jack client\n");
331 jack_set_process_callback(client
, process
, NULL
);
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
);
350 lash_client
= lash_init(lash_extract_args(argc
, argv
), "Epichord",
351 LASH_Config_File
, LASH_PROTOCOL( 2, 0 ));
353 printf("init_backend: lash failed to initialize\n");
356 lash_jack_client_name(lash_client
, "Epichord");
367 int shutdown_backend(){
371 jack_deactivate(client
);
379 jack_transport_start(client
);
384 jack_transport_stop(client
);
387 int reset_backend(int tick
){
391 cur_frame
= t2f(tick
);
392 last_frame
= cur_frame
;
397 jack_transport_locate(client
, t2f(tick
));
401 void toggle_backend_recording(){
411 //send a midi event from the gui thread
412 void send_midi(char* raw
, uint16_t n
, uint8_t port
){
414 printf("send_midi: cant send, immediate message too big\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
;
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
){
442 if(jack_ringbuffer_read(inbuf
,(char*)&t
,4) == 0){
445 jack_ringbuffer_read(inbuf
,(char*)&n
,2);
446 buf
= (unsigned char*)malloc(n
);
447 jack_ringbuffer_read(inbuf
,(char*)buf
,n
);
459 for(int i
=2; i
<n
-1; i
++){
460 snprintf(hbuf
,8,"%02x ",buf
[i
]);
461 sysexbuf
.append(hbuf
);
469 const char* getsysexbuf(){
470 return sysexbuf
.c_str();
474 void all_notes_off(){
475 for(int i
=0; i
<tracks
.size(); i
++){
480 void program_change(int track
, int prog
){
481 int port
= tracks
[track
]->port
;
482 int chan
= tracks
[track
]->chan
;
485 buf
[0] = 0xC0 | chan
;
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
;
495 buf
[0] = 0xB0 | chan
;
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
;
506 buf
[0] = 0xB0 | chan
;
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
;
517 buf
[0] = 0xB0 | chan
;
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
;
528 buf
[0] = 0xB0 | chan
;
531 send_midi(buf
, 3, port
);
535 void midi_note_off(int note
, int chan
, int port
){
537 buf
[0] = 0x80 | chan
;
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
;
557 send_midi(buf
,3,port
);
561 void backend_set_trackinit(int v
){
564 void backend_set_passthru(int v
){
568 void set_loop_start(int tick
){
572 void set_loop_end(int tick
){
576 int get_loop_start(){
584 int get_play_position(){
589 void set_solo(int s
){
597 int is_backend_playing(){
601 int is_backend_recording(){
602 return recording
&&playing
;
619 void set_rec_port(int n
){
624 char* session_string
;
625 int backend_session_process(){
626 int ret
= SESSION_NOMORE
;
632 e
= lash_get_event(lash_client
);
634 return SESSION_NOMORE
;
637 asprintf(&session_string
,"%s",lash_event_get_string(e
));
638 const int t
= lash_event_get_type (e
);
643 printf("session_process: LASH save\n");
644 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Save_File
));
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
));
653 printf("session_process: LASH quit\n");
657 printf("session_process: unhandled LASH event (%d)\n", 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
;
670 //lash_event_destroy(e);
675 char* get_session_string(){
676 return session_string
;