Enhanced possible debugging output.
[jacksampler.git] / src / jacksampler.cc
1 /* JackSampler - JACK based sampler
2  * Copyright (C) 2009-2010 Stefan Westerfeld
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <sfi/sfistore.h>
20 #include <bse/bsemain.h>
21 #include <bse/bseloader.h>
22 #include <bse/gslfft.h>
23 #include <bse/bsemathsignal.h>
24 #include <bse/bseblockutils.hh>
25 #include <list>
26 #include <unistd.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <bse/gsldatautils.h>
30
31 #include <stdio.h>
32 #include <math.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <string>
36 #include <vector>
37
38 #include <jack/jack.h>
39 #include <jack/midiport.h>
40
41 #include "main.hh"
42 #include "jacksampler.hh"
43 #include "microconf.hh"
44
45 using std::string;
46 using std::vector;
47
48 static float
49 freqFromNote (float note)
50 {
51   return 440 * exp (log (2) * (note - 69) / 12.0);
52 }
53
54 static bool
55 isNoteOn (const jack_midi_event_t& event)
56 {
57   if ((event.buffer[0] & 0xf0) == 0x90)
58     {
59       if (event.buffer[2] != 0) /* note on with velocity 0 => note off */
60         return true;
61     }
62   return false;
63 }
64
65 static bool
66 isNoteOff (const jack_midi_event_t& event)
67 {
68   if ((event.buffer[0] & 0xf0) == 0x90)
69     {
70       if (event.buffer[2] == 0) /* note on with velocity 0 => note off */
71         return true;
72     }
73   else if ((event.buffer[0] & 0xf0) == 0x80)
74     {
75       return true;
76     }
77   return false;
78 }
79
80 JackSampler::JackSampler() :
81   voices (256),
82   instrument (1),
83   pedal_down (false),
84   release_delay_ms (0),
85   release_ms (50),
86   mout (0),
87   instrument_count (0)
88 {
89 }
90
91 void
92 JackSampler::init (const Options& options, jack_client_t *client, int argc, char **argv)
93 {
94   for (int i = 1; i < argc; i++)
95     parse_config (options, i, argv[i]);
96   instrument_count = argc - 1;
97
98   jack_set_process_callback (client, jack_process, this);
99
100   jack_mix_freq = jack_get_sample_rate (client);
101
102   input_port = jack_port_register (client, "midi_in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
103   output_port = jack_port_register (client, "audio_out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
104
105   if (jack_activate (client))
106     {
107       fprintf (stderr, "cannot activate client");
108       exit (1);
109     }
110 }
111
112 int
113 JackSampler::process (jack_nframes_t nframes)
114 {
115   jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
116   void* port_buf = jack_port_get_buffer (input_port, nframes);
117   jack_nframes_t event_count = jack_midi_get_event_count (port_buf);
118   jack_midi_event_t in_event;
119   jack_nframes_t event_index = 0;
120
121   jack_midi_event_get (&in_event, port_buf, 0);
122   for (int i = 0; i < nframes; i++)
123     {
124       while ((in_event.time == i) && (event_index < event_count))
125         {
126           // process event
127           if (isNoteOn (in_event))
128             {
129               /* note on */
130               //printf ("note on %d mout = %f\n", in_event.buffer[1], mout);
131               /* find unused voice */
132               int v = 0;
133               while ((v < voices.size()) && (voices[v].state != Voice::UNUSED))
134                 v++;
135               if (v != voices.size())
136                 {
137                   //printf ("voice = %d\n", v);
138                   voices[v].note  = in_event.buffer[1];
139                   voices[v].env   = 1.0;
140                   voices[v].pos   = 0.0;
141                   voices[v].frequency = freqFromNote (in_event.buffer[1]);
142                   voices[v].velocity = in_event.buffer[2] / 127.0;
143                   voices[v].sample = NULL;
144                   float best_delta = 1e20;
145                   for (size_t s = 0; s < samples.size(); s++)
146                     {
147                       // find nearest sample with a logarithmic distance measure: delta of 220 and 440 == delta of 440 and 880 == 2
148                       float delta = std::max (voices[v].frequency / samples[s].osc_freq, samples[s].osc_freq / voices[v].frequency);
149                       if (samples[s].instrument == instrument && delta < best_delta)
150                         {
151                           voices[v].sample = &samples[s];
152                           best_delta = delta;
153                         }
154                     }
155                   if (voices[v].sample) /* only switch to on if a sample was found */
156                     {
157                       voices[v].state = Voice::ON;
158                       //printf ("sample=%s\n", voices[v].sample->file_name.c_str());
159                       //printf ("stepping=%f\n", voices[v].frequency / voices[v].sample->osc_freq * voices[v].sample->mix_freq / jack_mix_freq);
160                     }
161                 }
162               else
163                 {
164                   printf ("NO MORE VOICES\n");
165                 }
166             }
167           else if (isNoteOff (in_event))
168             {
169               /* note off */
170               //printf ("note off %d\n", in_event.buffer[1]);
171
172               for (int v = 0; v < voices.size(); v++)
173                 {
174                   if (voices[v].state == Voice::ON && voices[v].note == in_event.buffer[1])
175                     {
176                       if (pedal_down)
177                         voices[v].pedal = true;
178                       else
179                         {
180                           //printf ("off voice %d\n", v);
181                           voices[v].state = Voice::RELEASE_DELAY;
182                           voices[v].rd_pos = 0;
183                         }
184                     }
185                 }
186             }
187           else if ((in_event.buffer[0] & 0xf0) == 0xb0)
188             {
189               //printf ("got midi controller event status=%x controller=%x value=%x\n",
190               //        in_event.buffer[0], in_event.buffer[1], in_event.buffer[2]);
191               if (in_event.buffer[1] == 0x40)
192                 {
193                   pedal_down = in_event.buffer[2] > 0x40;
194                   if (!pedal_down)
195                     {
196                       /* release voices which are sustained due to the pedal */
197                       for (int v = 0; v < voices.size(); v++)
198                         {
199                           if (voices[v].pedal)
200                             {
201                               voices[v].state = Voice::RELEASE_DELAY;
202                               voices[v].rd_pos = 0;
203                               voices[v].pedal = false;
204                             }
205                         }
206                     }
207                 }
208             }
209
210           // get next event
211           event_index++;
212           if (event_index < event_count)
213             jack_midi_event_get (&in_event, port_buf, event_index);
214         }
215
216       // generate one sample
217       out[i] = 0.0;
218       for (int v = 0; v < voices.size(); v++)
219         {
220           if (voices[v].state != Voice::UNUSED)
221             {
222               voices[v].pos += voices[v].frequency / voices[v].sample->osc_freq *
223                                voices[v].sample->mix_freq / jack_mix_freq;
224
225               int ipos = voices[v].pos;
226               double dpos = voices[v].pos - ipos;
227               if (ipos < (voices[v].sample->pcm_data.size() - 1))
228                 {
229                   double left = voices[v].sample->pcm_data[ipos];
230                   double right = voices[v].sample->pcm_data[ipos + 1];
231                   out[i] += (left * (1.0 - dpos) + right * dpos) * voices[v].env * voices[v].velocity;
232                 }
233             }
234           if (voices[v].state == Voice::RELEASE_DELAY)
235             {
236               voices[v].rd_pos += 1000.0 / jack_mix_freq;
237               if (voices[v].rd_pos > release_delay_ms)
238                 voices[v].state = Voice::FADE_OUT;
239             }
240           if (voices[v].state == Voice::FADE_OUT)
241             {
242               voices[v].env -= (1000.0 / jack_mix_freq) / release_ms;
243               if (voices[v].env <= 0)
244                 {
245                   voices[v].state = Voice::UNUSED;
246                   voices[v].pedal = false;
247                 }
248             }
249         }
250       out[i] *= 0.333;    /* empiric */
251       mout = std::max (fabs (out[i]), mout);
252     }
253   return 0;
254 }
255
256 int
257 JackSampler::jack_process (jack_nframes_t nframes, void *arg)
258 {
259   JackSampler *instance = reinterpret_cast<JackSampler *> (arg);
260   return instance->process (nframes);
261 }
262
263 void
264 JackSampler::load_note (const Options& options, int note, const char *file_name, int instrument)
265 {
266   /* open input */
267   BseErrorType error;
268
269   BseWaveFileInfo *wave_file_info = bse_wave_file_info_load (file_name, &error);
270   if (!wave_file_info)
271     {
272       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
273       exit (1);
274     }
275
276   BseWaveDsc *waveDsc = bse_wave_dsc_load (wave_file_info, 0, FALSE, &error);
277   if (!waveDsc)
278     {
279       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
280       exit (1);
281     }
282
283   GslDataHandle *dhandle = bse_wave_handle_create (waveDsc, 0, &error);
284   if (!dhandle)
285     {
286       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
287       exit (1);
288     }
289
290   error = gsl_data_handle_open (dhandle);
291   if (error)
292     {
293       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
294       exit (1);
295     }
296
297   Sample s;
298
299   vector<float> block (1024);
300   uint64 pos = 0;
301   uint64 len = gsl_data_handle_length (dhandle);
302   while (pos < len)
303     {
304       uint64 r = gsl_data_handle_read (dhandle, pos, block.size(), &block[0]);
305
306       for (int i = 0; i < r; i++)
307         s.pcm_data.push_back (block[i]);
308       pos += r;
309     }
310   printf ("loaded sample, length = %ld\n", s.pcm_data.size());
311   s.mix_freq = gsl_data_handle_mix_freq (dhandle);
312   s.osc_freq = freqFromNote (note);
313   s.instrument = instrument;
314   s.file_name = file_name;
315   samples.push_back (s);
316 }
317
318 void
319 JackSampler::parse_config (const Options& options, int instrument, const char *name)
320 {
321   MicroConf cfg (name);
322
323   while (cfg.next())
324     {
325       int    note = 0;
326       double d = 0;
327       string file;
328
329       if (cfg.command ("sample", note, file))
330         {
331           load_note (options, note, file.c_str(), instrument);
332           printf ("NOTE %d FILE %s\n", note, file.c_str());
333         }
334       else if (cfg.command ("release_delay", d))
335         {
336           release_delay_ms = d;
337           printf ("RELEASE_DELAY %f ms\n", release_delay_ms);
338         }
339       else if (cfg.command ("release", d))
340         {
341           release_ms = d;
342           printf ("RELEASE %f ms\n", release_ms);
343         }
344       else
345         {
346           cfg.die_if_unknown();
347         }
348     }
349 }
350
351 void
352 JackSampler::change_instrument (int new_instrument)
353 {
354   instrument = new_instrument;
355   printf ("JackSampler: changed instrument to %d\n", instrument);
356 }
357
358 void
359 JackSampler::status()
360 {
361   int unused = 0;
362   int on = 0;
363   int release_delay = 0;
364   int fade_out = 0;
365
366   for (size_t i = 0; i < voices.size(); i++)
367     {
368       if (voices[i].state == Voice::UNUSED)
369         unused++;
370       else if (voices[i].state == Voice::ON)
371         on++;
372       else if (voices[i].state == Voice::RELEASE_DELAY)
373         release_delay++;
374       else if (voices[i].state == Voice::FADE_OUT)
375         fade_out++;
376       else
377         g_assert_not_reached();
378     }
379   printf ("sampling rate:   %.2f\n", jack_mix_freq);
380   printf ("instruments:     %d\n", instrument_count);
381   printf ("active instr.:   %d\n", instrument);
382   printf ("total voices:    %d\n", voices.size());
383   printf ("\n");
384   printf (" * unused        %d\n", unused);
385   printf (" * on            %d\n", on);
386   printf (" * release delay %d\n", release_delay);
387   printf (" * fade out      %d\n", fade_out);
388 }
389
390 void
391 JackSampler::reset()
392 {
393   // reset all voices the hard way (might click)
394   for (size_t v = 0; v < voices.size(); v++)
395     voices[v].state = Voice::UNUSED;
396 }