5d51ba61573786d12ed0e0fa19420a1fd2ba8cd2
[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                     voices[v].state = Voice::ON;
157                 }
158               else
159                 {
160                   printf ("NO MORE VOICES\n");
161                 }
162             }
163           else if (isNoteOff (in_event))
164             {
165               /* note on */
166               //printf ("note off %d\n", in_event.buffer[1]);
167
168               for (int v = 0; v < voices.size(); v++)
169                 {
170                   if (voices[v].state == Voice::ON && voices[v].note == in_event.buffer[1])
171                     {
172                       if (pedal_down)
173                         voices[v].pedal = true;
174                       else
175                         {
176                           //printf ("off voice %d\n", v);
177                           voices[v].state = Voice::RELEASE_DELAY;
178                           voices[v].rd_pos = 0;
179                         }
180                     }
181                 }
182             }
183           else if ((in_event.buffer[0] & 0xf0) == 0xb0)
184             {
185               //printf ("got midi controller event status=%x controller=%x value=%x\n",
186               //        in_event.buffer[0], in_event.buffer[1], in_event.buffer[2]);
187               if (in_event.buffer[1] == 0x40)
188                 {
189                   pedal_down = in_event.buffer[2] > 0x40;
190                   if (!pedal_down)
191                     {
192                       /* release voices which are sustained due to the pedal */
193                       for (int v = 0; v < voices.size(); v++)
194                         {
195                           if (voices[v].pedal)
196                             {
197                               voices[v].state = Voice::RELEASE_DELAY;
198                               voices[v].rd_pos = 0;
199                               voices[v].pedal = false;
200                             }
201                         }
202                     }
203                 }
204             }
205
206           // get next event
207           event_index++;
208           if (event_index < event_count)
209             jack_midi_event_get (&in_event, port_buf, event_index);
210         }
211
212       // generate one sample
213       out[i] = 0.0;
214       for (int v = 0; v < voices.size(); v++)
215         {
216           if (voices[v].state != Voice::UNUSED)
217             {
218               voices[v].pos += voices[v].frequency / voices[v].sample->osc_freq *
219                                voices[v].sample->mix_freq / jack_mix_freq;
220
221               int ipos = voices[v].pos;
222               double dpos = voices[v].pos - ipos;
223               if (ipos < (voices[v].sample->pcm_data.size() - 1))
224                 {
225                   double left = voices[v].sample->pcm_data[ipos];
226                   double right = voices[v].sample->pcm_data[ipos + 1];
227                   out[i] += (left * (1.0 - dpos) + right * dpos) * voices[v].env * voices[v].velocity;
228                 }
229             }
230           if (voices[v].state == Voice::RELEASE_DELAY)
231             {
232               voices[v].rd_pos += 1000.0 / jack_mix_freq;
233               if (voices[v].rd_pos > release_delay_ms)
234                 voices[v].state = Voice::FADE_OUT;
235             }
236           if (voices[v].state == Voice::FADE_OUT)
237             {
238               voices[v].env -= (1000.0 / jack_mix_freq) / release_ms;
239               if (voices[v].env <= 0)
240                 {
241                   voices[v].state = Voice::UNUSED;
242                   voices[v].pedal = false;
243                 }
244             }
245         }
246       out[i] *= 0.333;    /* empiric */
247       mout = std::max (fabs (out[i]), mout);
248     }
249   return 0;
250 }
251
252 int
253 JackSampler::jack_process (jack_nframes_t nframes, void *arg)
254 {
255   JackSampler *instance = reinterpret_cast<JackSampler *> (arg);
256   return instance->process (nframes);
257 }
258
259 void
260 JackSampler::load_note (const Options& options, int note, const char *file_name, int instrument)
261 {
262   /* open input */
263   BseErrorType error;
264
265   BseWaveFileInfo *wave_file_info = bse_wave_file_info_load (file_name, &error);
266   if (!wave_file_info)
267     {
268       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
269       exit (1);
270     }
271
272   BseWaveDsc *waveDsc = bse_wave_dsc_load (wave_file_info, 0, FALSE, &error);
273   if (!waveDsc)
274     {
275       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
276       exit (1);
277     }
278
279   GslDataHandle *dhandle = bse_wave_handle_create (waveDsc, 0, &error);
280   if (!dhandle)
281     {
282       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
283       exit (1);
284     }
285
286   error = gsl_data_handle_open (dhandle);
287   if (error)
288     {
289       fprintf (stderr, "%s: can't open the input file %s: %s\n", options.program_name.c_str(), file_name, bse_error_blurb (error));
290       exit (1);
291     }
292
293   Sample s;
294
295   vector<float> block (1024);
296   uint64 pos = 0;
297   uint64 len = gsl_data_handle_length (dhandle);
298   while (pos < len)
299     {
300       uint64 r = gsl_data_handle_read (dhandle, pos, block.size(), &block[0]);
301
302       for (int i = 0; i < r; i++)
303         s.pcm_data.push_back (block[i]);
304       pos += r;
305     }
306   printf ("loaded sample, length = %ld\n", s.pcm_data.size());
307   s.mix_freq = gsl_data_handle_mix_freq (dhandle);
308   s.osc_freq = freqFromNote (note);
309   s.instrument = instrument;
310   samples.push_back (s);
311 }
312
313 void
314 JackSampler::parse_config (const Options& options, int instrument, const char *name)
315 {
316   MicroConf cfg (name);
317
318   while (cfg.next())
319     {
320       int    note = 0;
321       double d = 0;
322       string file;
323
324       if (cfg.command ("sample", note, file))
325         {
326           load_note (options, note, file.c_str(), instrument);
327           printf ("NOTE %d FILE %s\n", note, file.c_str());
328         }
329       else if (cfg.command ("release_delay", d))
330         {
331           release_delay_ms = d;
332           printf ("RELEASE_DELAY %f ms\n", release_delay_ms);
333         }
334       else if (cfg.command ("release", d))
335         {
336           release_ms = d;
337           printf ("RELEASE %f ms\n", release_ms);
338         }
339       else
340         {
341           cfg.die_if_unknown();
342         }
343     }
344 }
345
346 void
347 JackSampler::change_instrument (int new_instrument)
348 {
349   instrument = new_instrument;
350   printf ("JackSampler: changed instrument to %d\n", instrument);
351 }
352
353 void
354 JackSampler::status()
355 {
356   int unused = 0;
357   int on = 0;
358   int release_delay = 0;
359   int fade_out = 0;
360
361   for (size_t i = 0; i < voices.size(); i++)
362     {
363       if (voices[i].state == Voice::UNUSED)
364         unused++;
365       else if (voices[i].state == Voice::ON)
366         on++;
367       else if (voices[i].state == Voice::RELEASE_DELAY)
368         release_delay++;
369       else if (voices[i].state == Voice::FADE_OUT)
370         fade_out++;
371       else
372         g_assert_not_reached();
373     }
374   printf ("sampling rate:   %.2f\n", jack_mix_freq);
375   printf ("instruments:     %d\n", instrument_count);
376   printf ("active instr.:   %d\n", instrument);
377   printf ("total voices:    %d\n", voices.size());
378   printf ("\n");
379   printf (" * unused        %d\n", unused);
380   printf (" * on            %d\n", on);
381   printf (" * release delay %d\n", release_delay);
382   printf (" * fade out      %d\n", fade_out);
383 }
384
385 void
386 JackSampler::reset()
387 {
388   // reset all voices the hard way (might click)
389   for (size_t v = 0; v < voices.size(); v++)
390     voices[v].state = Voice::UNUSED;
391 }