2 Copyright (C) 2004 Ian Esten
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <jack/jack.h>
28 #include <jack/midiport.h>
30 jack_port_t
*input_port
;
31 jack_port_t
*output_port
;
32 jack_default_audio_sample_t ramp
=0.0;
33 jack_default_audio_sample_t note_on
;
34 unsigned char note
= 0;
35 jack_default_audio_sample_t note_frqs
[128];
37 jack_client_t
*client
;
39 static void signal_handler(int sig
)
41 jack_client_close(client
);
42 fprintf(stderr
, "signal received, exiting ...\n");
46 static void calc_note_frqs(jack_default_audio_sample_t srate
)
51 note_frqs
[i
] = (2.0 * 440.0 / 32.0) * pow(2, (((jack_default_audio_sample_t
)i
- 9.0) / 12.0)) / srate
;
55 static int process(jack_nframes_t nframes
, void *arg
)
58 void* port_buf
= jack_port_get_buffer(input_port
, nframes
);
59 jack_default_audio_sample_t
*out
= (jack_default_audio_sample_t
*) jack_port_get_buffer (output_port
, nframes
);
60 jack_midi_event_t in_event
;
61 jack_nframes_t event_index
= 0;
62 jack_nframes_t event_count
= jack_midi_get_event_count(port_buf
);
65 printf(" midisine: have %d events\n", event_count
);
66 for(i
=0; i
<event_count
; i
++)
68 jack_midi_event_get(&in_event
, port_buf
, i
);
69 printf(" event %d time is %d. 1st byte is 0x%x\n", i
, in_event
.time
, *(in_event
.buffer
));
71 /* printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/
73 jack_midi_event_get(&in_event
, port_buf
, 0);
74 for(i
= 0; i
< nframes
; i
++)
76 if ((in_event
.time
== i
) && (event_index
< event_count
))
78 if (((*(in_event
.buffer
) & 0xf0)) == 0x90)
81 note
= *(in_event
.buffer
+ 1);
82 if (*(in_event
.buffer
+ 2) == 0) {
85 note_on
= (float)(*(in_event
.buffer
+ 2)) / 127.f
;
88 else if (((*(in_event
.buffer
)) & 0xf0) == 0x80)
91 note
= *(in_event
.buffer
+ 1);
95 if(event_index
< event_count
)
96 jack_midi_event_get(&in_event
, port_buf
, event_index
);
98 ramp
+= note_frqs
[note
];
99 ramp
= (ramp
> 1.0) ? ramp
- 2.0 : ramp
;
100 out
[i
] = note_on
*sin(2*M_PI
*ramp
);
105 static int srate(jack_nframes_t nframes
, void *arg
)
107 printf("the sample rate is now %" PRIu32
"/sec\n", nframes
);
108 calc_note_frqs((jack_default_audio_sample_t
)nframes
);
112 static void jack_shutdown(void *arg
)
117 int main(int narg
, char **args
)
119 if ((client
= jack_client_open("midisine", JackNullOption
, NULL
)) == 0)
121 fprintf(stderr
, "jack server not running?\n");
125 calc_note_frqs(jack_get_sample_rate (client
));
127 jack_set_process_callback (client
, process
, 0);
129 jack_set_sample_rate_callback (client
, srate
, 0);
131 jack_on_shutdown (client
, jack_shutdown
, 0);
133 input_port
= jack_port_register (client
, "midi_in", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
134 output_port
= jack_port_register (client
, "audio_out", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
136 if (jack_activate (client
))
138 fprintf(stderr
, "cannot activate client");
142 /* install a signal handler to properly quits jack client */
143 signal(SIGQUIT
, signal_handler
);
144 signal(SIGTERM
, signal_handler
);
145 signal(SIGHUP
, signal_handler
);
146 signal(SIGINT
, signal_handler
);
148 /* run until interrupted */
152 jack_client_close(client
);