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
;
53 extern std::vector
<track
*> tracks
;
55 jack_client_t
* client
;
57 jack_port_t
* outport
[PORT_COUNT
];
59 void* pbo
[PORT_COUNT
];
62 jack_ringbuffer_t
* outbuf
;
63 jack_ringbuffer_t
* inbuf
;
65 static int playing
= 0;
66 static int looping
= 0;
67 static int recording
=0;
68 static int loop_start
= 0;
69 static int loop_end
= 512;
70 static int passthru
= 1;
71 static int rec_port
= 0;
73 static int init_chans
= 1;
75 static uint64_t cur_frame
= 0;
76 static uint64_t last_frame
= 0;
77 static int frame_jump
= 0;
81 static int new_bpm
= 120;
82 static int tpb
= TICKS_PER_BEAT
;
83 static int sample_rate
= 0;
84 static int frame_count
= 0;
86 #define t2f(X) ((uint64_t)X*60*sample_rate/(bpm*tpb))
87 #define f2t(X) ((uint64_t)X*bpm*tpb/(sample_rate*60))
91 //void (*update_display)() = NULL;
93 /* callback for seq.c and play.c */
94 /* THIS BARELY WORKS */
95 void dispatch_event(mevent
* e
, int track
, int tick_base
){
99 int p
= tracks
[track
]->port
;
100 int c
= tracks
[track
]->chan
;
102 uint64_t base
= t2f(tick_base
);
103 uint64_t frame
= t2f(e
->tick
) + base
- last_frame
+ frame_jump
;
109 if(looping
&& e
->tick
+tick_base
== loop_end
&& e
->type
!= MIDI_NOTE_OFF
){
110 //dispatch only note off events on a loop_end
114 //printf("0x%x %d %llu %llu %llu %d %llu %d\n", e->type, e->tick, t2f(e->tick), base, last_frame, frame_jump, frame, bpm);
116 if(t2f(e
->tick
)+base
< last_frame
){
117 printf("playing a note in the past?? lucky it didnt segfault!\n");
121 if(frame
== frame_count
){
125 unsigned char buf
[3];
127 if(midi_encode(e
,c
,buf
,&n
) < 0){
131 md
= jack_midi_event_reserve(pbo
[p
],frame
,n
);
133 md
= jack_midi_event_reserve(pbo
[p
],frame_count
-1,n
);
135 printf("dispatch: can't reserve midi event\n");
139 for(int i
=0; i
<n
; i
++){
150 static int process(jack_nframes_t nframes
, void* arg
){
152 frame_count
= nframes
;
154 //handle incoming midi events
155 for(int i
=0; i
<PORT_COUNT
; i
++){
156 pbo
[i
] = jack_port_get_buffer(outport
[i
],nframes
);
157 jack_midi_clear_buffer(pbo
[i
]);
159 pbi
= jack_port_get_buffer(inport
,nframes
);
161 jack_midi_data_t
* md1
;
162 jack_midi_data_t
* md2
;
164 jack_midi_event_t me
;
168 for(int i
=0; i
<jack_midi_get_event_count(pbi
); i
++){
169 jack_midi_event_get(&me
,pbi
,i
);
171 //printf("%d got midi event, type 0x%x, value 0x%x 0x%x\n",i,md1[0],md1[1],md1[2]);
173 md2
= jack_midi_event_reserve(pbo
[rec_port
],0,me
.size
);
175 printf("passthru: can't reserve midi event\n");
178 memcpy(md2
,md1
,me
.size
);
181 rec_tick
= last_tick
+ (me
.time
*bpm
*tpb
)/(sample_rate
*60);
183 //if(playing && recording){
184 uint16_t size
= me
.size
;
185 jack_ringbuffer_write(inbuf
,(char*)&rec_tick
,4);
186 jack_ringbuffer_write(inbuf
,(char*)&size
,2);
187 jack_ringbuffer_write(inbuf
,(char*)md1
,me
.size
);
192 if(init_chans
&& playing
){
195 for(int j
=0; j
<tracks
.size(); j
++){
196 int ch
= tracks
[j
]->chan
;
197 int pt
= tracks
[j
]->port
;
202 buf
[2] = tracks
[j
]->bank
;
207 buf
[1] = tracks
[j
]->prog
;
213 buf
[2] = tracks
[j
]->vol
;
219 buf
[2] = tracks
[j
]->pan
;
225 //handle outgoing immediate midi events
229 while(jack_ringbuffer_read_space(outbuf
) > 0){
230 jack_ringbuffer_read(outbuf
,&p
,1);
231 jack_ringbuffer_read(outbuf
,(char*)&n
,2);
232 jack_ringbuffer_read(outbuf
,buf
,n
);
233 md1
= jack_midi_event_reserve(pbo
[p
],0,n
);
235 printf("gui: can't reserve midi event\n");
238 for(int i
=0; i
<n
; i
++){
248 cur_frame
= t2f(cur_tick
);
249 last_frame
= t2f(last_tick
);
252 last_frame
= cur_frame
;
253 cur_frame
+= nframes
;
254 last_tick
= cur_tick
;
255 cur_tick
= f2t(cur_frame
);
262 /* this only handles the case where the nframes covers the
263 loop boundary once. a more robust way would split it into
264 before covering n loop boundaries, a loop for n looping regions,
265 and a final section covering part of the loop region. this
266 would only need to be used for insanely high bpm */
267 if(lf
&& last_tick
< le
&& cur_tick
> le
){
268 //printf("split l%d m%d r%d\n",last_tick,loop_end,cur_tick);
269 int split_frame
= t2f(le
) - last_frame
+ 1;
270 int left_over
= nframes
- split_frame
;
271 int jump
= split_frame
;
272 cur_frame
= last_frame
+ jump
;
273 cur_tick
= f2t(cur_frame
);
274 //printf("cur tick %d\n",cur_tick);
275 play_seq(cur_tick
, dispatch_event
);
278 //printf("cur tick %d\n",cur_tick);
280 last_frame
= t2f(ls
);
281 cur_frame
= last_frame
+ left_over
;
282 cur_tick
= f2t(cur_frame
);
284 play_seq(cur_tick
, dispatch_event
);
286 else if(lf
&& cur_tick
> le
){
288 last_frame
= t2f(ls
);
289 cur_frame
= last_frame
+ nframes
;
290 cur_tick
= f2t(cur_frame
);
291 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
292 play_seq(cur_tick
, dispatch_event
);
295 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
296 play_seq(cur_tick
, dispatch_event
);
307 /* backend api wrapper */
309 int init_backend(int* argc
, char*** argv
){
311 client
= jack_client_open("Epichord",(jack_options_t
)0,NULL
);
313 printf("failure to open jack client\n");
317 jack_set_process_callback(client
, process
, 0);
320 for(int i
=0; i
<PORT_COUNT
; i
++){
321 sprintf(buf
,"midi out %d",i
);
322 outport
[i
]=jack_port_register(client
,buf
,JACK_DEFAULT_MIDI_TYPE
,JackPortIsOutput
,0);
325 inport
=jack_port_register(client
, "midi in", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
327 outbuf
= jack_ringbuffer_create(1024);
328 inbuf
= jack_ringbuffer_create(1024);
330 sample_rate
= jack_get_sample_rate(client
);
332 jack_activate(client
);
336 lash_client
= lash_init(lash_extract_args(argc
, argv
), "Epichord",
337 LASH_Config_File
, LASH_PROTOCOL( 2, 0 ));
339 printf("lash failed to initialize\n");
342 lash_jack_client_name(lash_client
, "Epichord");
353 int shutdown_backend(){
357 jack_deactivate(client
);
371 int reset_backend(int tick
){
375 cur_frame
= t2f(tick
);
376 last_frame
= cur_frame
;
383 void toggle_backend_recording(){
393 //send a midi event from the gui thread
394 void send_midi(char* raw
, uint16_t n
, uint8_t port
){
396 printf("send_midi: cant send, immediate message too big\n");
403 //FIXME check return value
404 jack_ringbuffer_write(outbuf
,buf
,3+n
);
407 void send_midi_local(char* raw
, uint16_t n
){
408 uint32_t tick
= cur_tick
;
410 //FIXME chec return value
411 jack_ringbuffer_write(inbuf
,(char*)&tick
,4);
412 jack_ringbuffer_write(inbuf
,(char*)&size
,2);
413 jack_ringbuffer_write(inbuf
,raw
,n
);
418 std::string sysexbuf
;
419 //get next incoming midi event for gui thread
420 int recv_midi(int* chan
, int* tick
, int* type
, int* val1
, int* val2
){
424 if(jack_ringbuffer_read(inbuf
,(char*)&t
,4) == 0){
427 jack_ringbuffer_read(inbuf
,(char*)&n
,2);
428 buf
= (unsigned char*)malloc(n
);
429 jack_ringbuffer_read(inbuf
,(char*)buf
,n
);
441 for(int i
=2; i
<n
-1; i
++){
442 snprintf(hbuf
,8,"%02x ",buf
[i
]);
443 sysexbuf
.append(hbuf
);
451 const char* getsysexbuf(){
452 return sysexbuf
.c_str();
456 void all_notes_off(){
457 for(int i
=0; i
<tracks
.size(); i
++){
462 void program_change(int track
, int prog
){
463 int port
= tracks
[track
]->port
;
464 int chan
= tracks
[track
]->chan
;
467 buf
[0] = 0xC0 | chan
;
469 send_midi(buf
, 2, port
);
472 void midi_bank_controller(int track
, int bank
){
473 int port
= tracks
[track
]->port
;
474 int chan
= tracks
[track
]->chan
;
477 buf
[0] = 0xB0 | chan
;
480 send_midi(buf
, 3, port
);
483 void midi_volume_controller(int track
, int vol
){
484 int port
= tracks
[track
]->port
;
485 int chan
= tracks
[track
]->chan
;
488 buf
[0] = 0xB0 | chan
;
491 send_midi(buf
, 3, port
);
494 void midi_pan_controller(int track
, int pan
){
495 int port
= tracks
[track
]->port
;
496 int chan
= tracks
[track
]->chan
;
499 buf
[0] = 0xB0 | chan
;
502 send_midi(buf
, 3, port
);
505 void midi_expression_controller(int track
, int expr
){
506 int port
= tracks
[track
]->port
;
507 int chan
= tracks
[track
]->chan
;
510 buf
[0] = 0xB0 | chan
;
513 send_midi(buf
, 3, port
);
517 void midi_note_off(int note
, int chan
, int port
){
519 buf
[0] = 0x80 | chan
;
522 send_midi(buf
,3,port
);
525 void midi_track_off(int track
){
526 int chan
= tracks
[track
]->chan
;
527 int port
= tracks
[track
]->port
;
529 midi_channel_off(chan
,port
);
532 void midi_channel_off(int chan
, int port
){
533 char buf
[3] = {0xB0,123,0};
534 buf
[0] = 0xB0 | chan
;
535 send_midi(buf
,3,port
);
537 buf
[0] = 0xB0 | chan
;
539 send_midi(buf
,3,port
);
543 void backend_set_passthru(int v
){
547 void set_loop_start(int tick
){
551 void set_loop_end(int tick
){
555 int get_loop_start(){
563 int get_play_position(){
568 void set_solo(int s
){
576 int is_backend_playing(){
580 int is_backend_recording(){
581 return recording
&&playing
;
599 char* session_string
;
600 int backend_session_process(){
601 int ret
= SESSION_NOMORE
;
607 e
= lash_get_event(lash_client
);
609 return SESSION_NOMORE
;
612 asprintf(&session_string
,"%s",lash_event_get_string(e
));
613 const int t
= lash_event_get_type (e
);
618 printf("session_process: LASH save\n");
619 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Save_File
));
622 case LASH_Restore_File
:
623 printf("session_process: LASH load\n");
624 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Restore_File
));
628 printf("session_process: LASH quit\n");
632 printf("session_process: unhandled LASH event (%d)\n", t
);
634 case LASH_Client_Name
: printf("LASH_Client_Name\n"); break;
635 case LASH_Jack_Client_Name
: printf("LASH_Jack_Client_Name\n"); break;
636 case LASH_Alsa_Client_ID
: printf("LASH_Alsa_Client_ID\n"); break;
637 case LASH_Save_File
: printf("LASH_Save_File\n"); break;
638 case LASH_Save_Data_Set
: printf("LASH_Save_Data_Set\n"); break;
639 case LASH_Restore_Data_Set
: printf("LASH_Restore_Data_Set\n"); break;
640 case LASH_Save
: printf("LASH_Save\n"); break;
642 ret
= SESSION_UNHANDLED
;
645 //lash_event_destroy(e);
650 char* get_session_string(){
651 return session_string
;