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
++){
251 printf("process: someone set the bpm to zero!\n");
254 cur_frame
= t2f(cur_tick
);
255 last_frame
= t2f(last_tick
);
258 last_frame
= cur_frame
;
259 cur_frame
+= nframes
;
260 last_tick
= cur_tick
;
261 cur_tick
= f2t(cur_frame
);
268 /* this only handles the case where the nframes covers the
269 loop boundary once. a more robust way would split it into
270 before covering n loop boundaries, a loop for n looping regions,
271 and a final section covering part of the loop region. this
272 would only need to be used for insanely high bpm */
273 if(lf
&& last_tick
< le
&& cur_tick
> le
){
274 //printf("split l%d m%d r%d\n",last_tick,loop_end,cur_tick);
275 int split_frame
= t2f(le
) - last_frame
+ 1;
276 int left_over
= nframes
- split_frame
;
277 int jump
= split_frame
;
278 cur_frame
= last_frame
+ jump
;
279 cur_tick
= f2t(cur_frame
);
280 //printf("cur tick %d\n",cur_tick);
284 //printf("cur tick %d\n",cur_tick);
286 last_frame
= t2f(ls
);
287 cur_frame
= last_frame
+ left_over
;
288 cur_tick
= f2t(cur_frame
);
292 else if(lf
&& cur_tick
> le
){
294 last_frame
= t2f(ls
);
295 cur_frame
= last_frame
+ nframes
;
296 cur_tick
= f2t(cur_frame
);
297 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
301 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
313 /* backend api wrapper */
315 int init_backend(int* argc
, char*** argv
){
317 client
= jack_client_open("Epichord",(jack_options_t
)0,NULL
);
319 printf("init_backend: failure to open jack client\n");
323 jack_set_process_callback(client
, process
, 0);
326 for(int i
=0; i
<PORT_COUNT
; i
++){
327 sprintf(buf
,"midi out %d",i
);
328 outport
[i
]=jack_port_register(client
,buf
,JACK_DEFAULT_MIDI_TYPE
,JackPortIsOutput
,0);
331 inport
=jack_port_register(client
, "midi in", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
333 outbuf
= jack_ringbuffer_create(1024);
334 inbuf
= jack_ringbuffer_create(1024);
336 sample_rate
= jack_get_sample_rate(client
);
338 jack_activate(client
);
342 lash_client
= lash_init(lash_extract_args(argc
, argv
), "Epichord",
343 LASH_Config_File
, LASH_PROTOCOL( 2, 0 ));
345 printf("init_backend: lash failed to initialize\n");
348 lash_jack_client_name(lash_client
, "Epichord");
359 int shutdown_backend(){
363 jack_deactivate(client
);
377 int reset_backend(int tick
){
381 cur_frame
= t2f(tick
);
382 last_frame
= cur_frame
;
389 void toggle_backend_recording(){
399 //send a midi event from the gui thread
400 void send_midi(char* raw
, uint16_t n
, uint8_t port
){
402 printf("send_midi: cant send, immediate message too big\n");
409 //FIXME check return value
410 jack_ringbuffer_write(outbuf
,buf
,3+n
);
413 void send_midi_local(char* raw
, uint16_t n
){
414 uint32_t tick
= cur_tick
;
416 //FIXME chec return value
417 jack_ringbuffer_write(inbuf
,(char*)&tick
,4);
418 jack_ringbuffer_write(inbuf
,(char*)&size
,2);
419 jack_ringbuffer_write(inbuf
,raw
,n
);
424 std::string sysexbuf
;
425 //get next incoming midi event for gui thread
426 int recv_midi(int* chan
, int* tick
, int* type
, int* val1
, int* val2
){
430 if(jack_ringbuffer_read(inbuf
,(char*)&t
,4) == 0){
433 jack_ringbuffer_read(inbuf
,(char*)&n
,2);
434 buf
= (unsigned char*)malloc(n
);
435 jack_ringbuffer_read(inbuf
,(char*)buf
,n
);
447 for(int i
=2; i
<n
-1; i
++){
448 snprintf(hbuf
,8,"%02x ",buf
[i
]);
449 sysexbuf
.append(hbuf
);
457 const char* getsysexbuf(){
458 return sysexbuf
.c_str();
462 void all_notes_off(){
463 for(int i
=0; i
<tracks
.size(); i
++){
468 void program_change(int track
, int prog
){
469 int port
= tracks
[track
]->port
;
470 int chan
= tracks
[track
]->chan
;
473 buf
[0] = 0xC0 | chan
;
475 send_midi(buf
, 2, port
);
478 void midi_bank_controller(int track
, int bank
){
479 int port
= tracks
[track
]->port
;
480 int chan
= tracks
[track
]->chan
;
483 buf
[0] = 0xB0 | chan
;
486 send_midi(buf
, 3, port
);
489 void midi_volume_controller(int track
, int vol
){
490 int port
= tracks
[track
]->port
;
491 int chan
= tracks
[track
]->chan
;
494 buf
[0] = 0xB0 | chan
;
497 send_midi(buf
, 3, port
);
500 void midi_pan_controller(int track
, int pan
){
501 int port
= tracks
[track
]->port
;
502 int chan
= tracks
[track
]->chan
;
505 buf
[0] = 0xB0 | chan
;
508 send_midi(buf
, 3, port
);
511 void midi_expression_controller(int track
, int expr
){
512 int port
= tracks
[track
]->port
;
513 int chan
= tracks
[track
]->chan
;
516 buf
[0] = 0xB0 | chan
;
519 send_midi(buf
, 3, port
);
523 void midi_note_off(int note
, int chan
, int port
){
525 buf
[0] = 0x80 | chan
;
528 send_midi(buf
,3,port
);
531 void midi_track_off(int track
){
532 int chan
= tracks
[track
]->chan
;
533 int port
= tracks
[track
]->port
;
535 midi_channel_off(chan
,port
);
538 void midi_channel_off(int chan
, int port
){
539 char buf
[3] = {0xB0,123,0};
540 buf
[0] = 0xB0 | chan
;
541 send_midi(buf
,3,port
);
543 buf
[0] = 0xB0 | chan
;
545 send_midi(buf
,3,port
);
549 void backend_set_passthru(int v
){
553 void set_loop_start(int tick
){
557 void set_loop_end(int tick
){
561 int get_loop_start(){
569 int get_play_position(){
574 void set_solo(int s
){
582 int is_backend_playing(){
586 int is_backend_recording(){
587 return recording
&&playing
;
605 char* session_string
;
606 int backend_session_process(){
607 int ret
= SESSION_NOMORE
;
613 e
= lash_get_event(lash_client
);
615 return SESSION_NOMORE
;
618 asprintf(&session_string
,"%s",lash_event_get_string(e
));
619 const int t
= lash_event_get_type (e
);
624 printf("session_process: LASH save\n");
625 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Save_File
));
628 case LASH_Restore_File
:
629 printf("session_process: LASH load\n");
630 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Restore_File
));
634 printf("session_process: LASH quit\n");
638 printf("session_process: unhandled LASH event (%d)\n", t
);
640 case LASH_Client_Name
: printf("LASH_Client_Name\n"); break;
641 case LASH_Jack_Client_Name
: printf("LASH_Jack_Client_Name\n"); break;
642 case LASH_Alsa_Client_ID
: printf("LASH_Alsa_Client_ID\n"); break;
643 case LASH_Save_File
: printf("LASH_Save_File\n"); break;
644 case LASH_Save_Data_Set
: printf("LASH_Save_Data_Set\n"); break;
645 case LASH_Restore_Data_Set
: printf("LASH_Restore_Data_Set\n"); break;
646 case LASH_Save
: printf("LASH_Save\n"); break;
648 ret
= SESSION_UNHANDLED
;
651 //lash_event_destroy(e);
656 char* get_session_string(){
657 return session_string
;