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.
28 #include <jack/jack.h>
29 #include <jack/midiport.h>
31 jack_port_t
*input_port
;
32 jack_port_t
*output_port
;
33 jack_default_audio_sample_t ramp
=0.0;
34 jack_default_audio_sample_t note_on
;
35 unsigned char note
= 0;
36 jack_default_audio_sample_t note_frqs
[128];
38 jack_client_t
*client
;
40 static void signal_handler(int sig
)
42 jack_client_close(client
);
43 fprintf(stderr
, "signal received, exiting ...\n");
47 static void calc_note_frqs(jack_default_audio_sample_t srate
)
52 note_frqs
[i
] = (2.0 * 440.0 / 32.0) * pow(2, (((jack_default_audio_sample_t
)i
- 9.0) / 12.0)) / srate
;
56 static int process(jack_nframes_t nframes
, void *arg
)
59 void* port_buf
= jack_port_get_buffer(input_port
, nframes
);
60 jack_default_audio_sample_t
*out
= (jack_default_audio_sample_t
*) jack_port_get_buffer (output_port
, nframes
);
61 jack_midi_event_t in_event
;
62 jack_nframes_t event_index
= 0;
63 jack_nframes_t event_count
= jack_midi_get_event_count(port_buf
);
66 printf(" midisine: have %d events\n", event_count
);
67 for(i
=0; i
<event_count
; i
++)
69 jack_midi_event_get(&in_event
, port_buf
, i
);
70 printf(" event %d time is %d. 1st byte is 0x%x\n", i
, in_event
.time
, *(in_event
.buffer
));
72 /* printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/
74 jack_midi_event_get(&in_event
, port_buf
, 0);
75 for(i
= 0; i
< nframes
; i
++)
77 if ((in_event
.time
== i
) && (event_index
< event_count
))
79 if (((*(in_event
.buffer
) & 0xf0)) == 0x90)
82 note
= *(in_event
.buffer
+ 1);
83 if (*(in_event
.buffer
+ 2) == 0) {
86 note_on
= (float)(*(in_event
.buffer
+ 2)) / 127.f
;
89 else if (((*(in_event
.buffer
)) & 0xf0) == 0x80)
92 note
= *(in_event
.buffer
+ 1);
96 if(event_index
< event_count
)
97 jack_midi_event_get(&in_event
, port_buf
, event_index
);
99 ramp
+= note_frqs
[note
];
100 ramp
= (ramp
> 1.0) ? ramp
- 2.0 : ramp
;
101 out
[i
] = note_on
*sin(2*M_PI
*ramp
);
106 static int srate(jack_nframes_t nframes
, void *arg
)
108 printf("the sample rate is now %" PRIu32
"/sec\n", nframes
);
109 calc_note_frqs((jack_default_audio_sample_t
)nframes
);
113 static void jack_shutdown(void *arg
)
115 fprintf(stderr
, "JACK shut down, exiting ...\n");
119 int main(int narg
, char **args
)
121 if ((client
= jack_client_open("midisine", JackNullOption
, NULL
)) == 0)
123 fprintf(stderr
, "JACK server not running?\n");
127 calc_note_frqs(jack_get_sample_rate (client
));
129 jack_set_process_callback (client
, process
, 0);
131 jack_set_sample_rate_callback (client
, srate
, 0);
133 jack_on_shutdown (client
, jack_shutdown
, 0);
135 input_port
= jack_port_register (client
, "midi_in", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
136 output_port
= jack_port_register (client
, "audio_out", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
138 if (jack_activate (client
))
140 fprintf(stderr
, "cannot activate client");
144 /* install a signal handler to properly quits jack client */
146 signal(SIGQUIT
, signal_handler
);
147 signal(SIGHUP
, signal_handler
);
149 signal(SIGTERM
, signal_handler
);
150 signal(SIGINT
, signal_handler
);
152 /* run until interrupted */
160 jack_client_close(client
);