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
32 #include <jack/jack.h>
33 #include <jack/types.h>
34 #include <jack/ringbuffer.h>
35 #include <jack/midiport.h>
36 #include <jack/transport.h>
39 #include <lash/lash.h>
40 lash_client_t
* lash_client
;
46 //#include "uihelper.h"
52 extern std::vector
<track
*> tracks
;
54 jack_client_t
* client
;
56 jack_port_t
* outport
[PORT_COUNT
];
58 void* pbo
[PORT_COUNT
];
61 jack_ringbuffer_t
* outbuf
;
62 jack_ringbuffer_t
* inbuf
;
64 static int playing
= 0;
65 static int looping
= 0;
66 static int recording
=0;
67 static int loop_start
= 0;
68 static int loop_end
= TICKS_PER_BEAT
*4;
69 static int passthru
= 1;
70 static int rec_port
= 0;
72 static int trackinit
= 1;
74 static int init_chans
= 1;
76 static uint64_t cur_frame
= 0;
77 static uint64_t last_frame
= 0;
78 static int frame_jump
= 0;
82 static int new_bpm
= 120;
83 static int tpb
= TICKS_PER_BEAT
;
84 static int sample_rate
= 0;
85 static int frame_count
= 0;
87 #define t2f(X) ((uint64_t)X*60*sample_rate/(bpm*tpb))
88 #define f2t(X) ((uint64_t)X*bpm*tpb/(sample_rate*60))
95 /* callback for seq.c and play.c */
96 void dispatch_event(mevent
* e
, int track
, int tick_base
){
100 int p
= tracks
[track
]->port
;
101 int c
= tracks
[track
]->chan
;
103 //uint64_t base = t2f(tick_base);
104 //uint64_t frame = t2f(e->tick) + base - last_frame + frame_jump;
105 uint64_t eframe
= t2f((uint64_t)(e
->tick
+tick_base
));
106 uint64_t frame
= eframe
- last_frame
+ frame_jump
;
108 if(e
->type
== -1){//dummy events
112 if(looping
&& e
->tick
+tick_base
== loop_end
&& e
->type
!= MIDI_NOTE_OFF
){
113 //dispatch only note off events on a loop_end
117 //printf("%d %d %d %llu %llu %llu\n",e->tick,tick_base,e->tick+tick_base, eframe, last_frame, frame);
119 if(eframe
< last_frame
){
120 printf("dispatch: %llu %llu negative frame index. BOOM segfault.\n", t2f(e
->tick
+tick_base
), last_frame
);
124 if(frame
== frame_count
){
125 //printf("dispatch: scheduling bug. frame index == frame count.\n");
129 unsigned char buf
[3];
131 if(midi_encode(e
,c
,buf
,&n
) < 0){
135 md
= jack_midi_event_reserve(pbo
[p
],frame
,n
);
137 md
= jack_midi_event_reserve(pbo
[p
],frame_count
-1,n
);
139 printf("dispatch: can't reserve midi event.\n");
142 printf("dispatch: send midi using scheduling kludge.\n");
144 for(int i
=0; i
<n
; i
++){
157 static int process(jack_nframes_t nframes
, void* arg
){
159 frame_count
= 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
<PORT_COUNT
; i
++){
169 pbo
[i
] = jack_port_get_buffer(outport
[i
],nframes
);
170 jack_midi_clear_buffer(pbo
[i
]);
172 pbi
= jack_port_get_buffer(inport
,nframes
);
176 if(init_chans
&& trackinit
&& playing
){
179 for(int j
=0; j
<tracks
.size(); j
++){
180 int ch
= tracks
[j
]->chan
;
181 int pt
= tracks
[j
]->port
;
186 buf
[2] = tracks
[j
]->bank
;
191 buf
[1] = tracks
[j
]->prog
;
197 buf
[2] = tracks
[j
]->vol
;
203 buf
[2] = tracks
[j
]->pan
;
209 //handle outgoing immediate midi events
213 while(jack_ringbuffer_read_space(outbuf
) > 0){
214 jack_ringbuffer_read(outbuf
,&p
,1);
215 jack_ringbuffer_read(outbuf
,(char*)&n
,2);
216 jack_ringbuffer_read(outbuf
,buf
,n
);
217 md1
= jack_midi_event_reserve(pbo
[p
],0,n
);
219 printf("gui: can't reserve midi event\n");
222 for(int i
=0; i
<n
; i
++){
236 printf("process: someone set the bpm to zero!\n");
239 cur_frame
= t2f(cur_tick
);
240 last_frame
= t2f(last_tick
);
243 last_frame
= cur_frame
;
244 cur_frame
+= nframes
;
245 last_tick
= cur_tick
;
246 cur_tick
= f2t(cur_frame
);
253 /* this only handles the case where the nframes covers the
254 loop boundary once. a more robust way would split it into
255 before covering n loop boundaries, a loop for n looping regions,
256 and a final section covering part of the loop region. this
257 would only need to be used for insanely high bpm */
258 if(lf
&& last_tick
< le
&& cur_tick
> le
){
259 //printf("split l%d m%d r%d\n",last_tick,loop_end,cur_tick);
260 int split_frame
= t2f(le
) - last_frame
+ 1;
261 int left_over
= nframes
- split_frame
;
262 int jump
= split_frame
;
263 cur_frame
= last_frame
+ jump
;
264 cur_tick
= f2t(cur_frame
);
265 //printf("cur tick %d\n",cur_tick);
269 //printf("cur tick %d\n",cur_tick);
271 last_frame
= t2f(ls
);
272 cur_frame
= last_frame
+ left_over
;
273 cur_tick
= f2t(cur_frame
);
277 else if(lf
&& cur_tick
> le
){
279 last_frame
= t2f(ls
);
280 cur_frame
= last_frame
+ nframes
;
281 cur_tick
= f2t(cur_frame
);
282 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
286 //printf("%llu %llu %d %d\n",last_frame,cur_frame,last_tick,cur_tick);
293 //handle incoming midi events
295 for(int i
=0; i
<jack_midi_get_event_count(pbi
); i
++){
296 jack_midi_event_get(&me
,pbi
,i
);
298 //printf("%d got midi event, type 0x%x, value 0x%x 0x%x\n",i,md1[0],md1[1],md1[2]);
300 md2
= jack_midi_event_reserve(pbo
[rec_port
],0,me
.size
);
302 printf("passthru: can't reserve midi event\n");
305 memcpy(md2
,md1
,me
.size
);
308 rec_tick
= last_tick
+ (me
.time
*bpm
*tpb
)/(sample_rate
*60);
310 //if(playing && recording){
311 uint16_t size
= me
.size
;
312 jack_ringbuffer_write(inbuf
,(char*)&rec_tick
,4);
313 jack_ringbuffer_write(inbuf
,(char*)&size
,2);
314 jack_ringbuffer_write(inbuf
,(char*)md1
,me
.size
);
326 /* backend api wrapper */
328 int init_backend(int* argc
, char*** argv
){
330 client
= jack_client_open("Epichord",(jack_options_t
)0,NULL
);
332 printf("init_backend: failure to open jack client\n");
336 jack_set_process_callback(client
, process
, NULL
);
339 for(int i
=0; i
<PORT_COUNT
; i
++){
340 sprintf(buf
,"midi out %d",i
);
341 outport
[i
]=jack_port_register(client
,buf
,JACK_DEFAULT_MIDI_TYPE
,JackPortIsOutput
,0);
344 inport
=jack_port_register(client
, "midi in", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
346 outbuf
= jack_ringbuffer_create(1024);
347 inbuf
= jack_ringbuffer_create(1024);
349 sample_rate
= jack_get_sample_rate(client
);
351 jack_activate(client
);
355 lash_client
= lash_init(lash_extract_args(argc
, argv
), "Epichord",
356 LASH_Config_File
, LASH_PROTOCOL( 2, 0 ));
358 printf("init_backend: lash failed to initialize\n");
361 lash_jack_client_name(lash_client
, "Epichord");
372 int shutdown_backend(){
376 jack_deactivate(client
);
384 jack_transport_start(client
);
389 jack_transport_stop(client
);
392 int reset_backend(int tick
){
396 cur_frame
= t2f(tick
);
397 last_frame
= cur_frame
;
402 jack_transport_locate(client
, t2f(tick
));
406 void toggle_backend_recording(){
416 //send a midi event from the gui thread
417 void send_midi(char* raw
, uint16_t n
, uint8_t port
){
419 printf("send_midi: cant send, immediate message too big\n");
426 //FIXME check return value
427 jack_ringbuffer_write(outbuf
,buf
,3+n
);
430 void send_midi_local(char* raw
, uint16_t n
){
431 uint32_t tick
= cur_tick
;
433 //FIXME chec return value
434 jack_ringbuffer_write(inbuf
,(char*)&tick
,4);
435 jack_ringbuffer_write(inbuf
,(char*)&size
,2);
436 jack_ringbuffer_write(inbuf
,raw
,n
);
441 std::string sysexbuf
;
442 //get next incoming midi event for gui thread
443 int recv_midi(int* chan
, int* tick
, int* type
, int* val1
, int* val2
){
447 if(jack_ringbuffer_read(inbuf
,(char*)&t
,4) == 0){
450 jack_ringbuffer_read(inbuf
,(char*)&n
,2);
451 buf
= (unsigned char*)malloc(n
);
452 jack_ringbuffer_read(inbuf
,(char*)buf
,n
);
464 for(int i
=2; i
<n
-1; i
++){
465 snprintf(hbuf
,8,"%02x ",buf
[i
]);
466 sysexbuf
.append(hbuf
);
476 const char* getsysexbuf(){
477 return sysexbuf
.c_str();
481 void all_notes_off(){
482 for(int i
=0; i
<tracks
.size(); i
++){
487 void program_change(int track
, int prog
){
488 int port
= tracks
[track
]->port
;
489 int chan
= tracks
[track
]->chan
;
492 buf
[0] = 0xC0 | chan
;
494 send_midi(buf
, 2, port
);
497 void midi_bank_controller(int track
, int bank
){
498 int port
= tracks
[track
]->port
;
499 int chan
= tracks
[track
]->chan
;
502 buf
[0] = 0xB0 | chan
;
505 send_midi(buf
, 3, port
);
509 send_midi(buf
, 3, port
);
512 void midi_volume_controller(int track
, int vol
){
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_pan_controller(int track
, int pan
){
524 int port
= tracks
[track
]->port
;
525 int chan
= tracks
[track
]->chan
;
528 buf
[0] = 0xB0 | chan
;
531 send_midi(buf
, 3, port
);
534 void midi_expression_controller(int track
, int expr
){
535 int port
= tracks
[track
]->port
;
536 int chan
= tracks
[track
]->chan
;
539 buf
[0] = 0xB0 | chan
;
542 send_midi(buf
, 3, port
);
546 void midi_note_off(int note
, int chan
, int port
){
548 buf
[0] = 0x80 | chan
;
551 send_midi(buf
,3,port
);
554 void midi_track_off(int track
){
555 int chan
= tracks
[track
]->chan
;
556 int port
= tracks
[track
]->port
;
558 OnBitArray
* onbits
= &(tracks
[track
]->onbits
);
559 onbits
->search_init();
560 int note
= onbits
->search_next();
562 midi_note_off(note
, chan
, port
);
563 note
= onbits
->search_next();
569 void backend_set_trackinit(int v
){
572 void backend_set_passthru(int v
){
576 void set_loop_start(int tick
){
580 void set_loop_end(int tick
){
584 int get_loop_start(){
592 int get_play_position(){
597 void set_solo(int s
){
605 int is_backend_playing(){
609 int is_backend_recording(){
610 return recording
&&playing
;
627 void set_rec_port(int n
){
632 char* session_string
;
633 int backend_session_process(){
634 int ret
= SESSION_NOMORE
;
640 e
= lash_get_event(lash_client
);
642 return SESSION_NOMORE
;
645 asprintf(&session_string
,"%s",lash_event_get_string(e
));
646 const int t
= lash_event_get_type (e
);
651 printf("session_process: LASH save\n");
652 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Save_File
));
655 case LASH_Restore_File
:
656 printf("session_process: LASH load\n");
657 lash_send_event(lash_client
, lash_event_new_with_type(LASH_Restore_File
));
661 printf("session_process: LASH quit\n");
665 printf("session_process: unhandled LASH event (%d)\n", t
);
667 case LASH_Client_Name
: printf("LASH_Client_Name\n"); break;
668 case LASH_Jack_Client_Name
: printf("LASH_Jack_Client_Name\n"); break;
669 case LASH_Alsa_Client_ID
: printf("LASH_Alsa_Client_ID\n"); break;
670 case LASH_Save_File
: printf("LASH_Save_File\n"); break;
671 case LASH_Save_Data_Set
: printf("LASH_Save_Data_Set\n"); break;
672 case LASH_Restore_Data_Set
: printf("LASH_Restore_Data_Set\n"); break;
673 case LASH_Save
: printf("LASH_Save\n"); break;
675 ret
= SESSION_UNHANDLED
;
678 //lash_event_destroy(e);
683 char* get_session_string(){
684 return session_string
;