A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "midiutil.h"
23#include "guspat.h"
24#include "synth.h"
25#include "sequencer.h"
26
27long tempo = 375000;
28
29/* From the old patch config.... each patch is scaled.
30 * Should be moved into patchset.cfg
31 * But everyone would need a new config file.
32 *
33 * While this really does need to go into the patch config,
34 * I doubt anyone has made their own custom rockbox patchset
35 * (if you have, please send a copy my way :) )
36 */
37static const unsigned char patchScale[]=
38{
39 125,115,115,100,100,80,115,100,100,100,100,80,100,100,100,100,
40 100,100,100,100,60,100,100,100,150,155,145,100,125,86,125,85,
41 161,160,133,160,135,133,100,128,150,100,100,150,100,130,100,200,
42 100,100,125,125,100,100,100,100,124,110,111,100,139,113,115,115,
43 125,115,95,140,100,100,105,100,90,100,80,80,100,125,100,80,
44 100,100,100,250,130,100,100,100,115,100,100,120,200,100,100,80,
45 130,100,100,150,100,100,100,100,100,100,200,100,100,100,100,100,
46 100,100,113,100,200,100,100,100,30,100,100,100,100,100,100,100
47};
48
49/* Sets the volume scaling by channel volume and note volume */
50/* This way we can do the multiplication/indexing once per */
51/* MIDI event at the most, instead of once per sample. */
52static inline void setVolScale(int a)
53{
54 struct SynthObject * so = &voices[a];
55 int ch = so->ch;
56
57 so->volscale = so->vol * chVol[ch]*patchScale[chPat[ch]] / 100;
58 //((signed short int)so->vol*(signed short int)chVol[ch])*patchScale[chPat[ch]];
59}
60
61static inline void setVol(int ch, int vol)
62{
63 int a;
64 chVol[ch] = vol;
65
66 /* If channel volume changes, we need to recalculate the volume scale */
67 /* factor for all voices active on this channel */
68 for (a = 0; a < MAX_VOICES; a++)
69 if (voices[a].ch == ch)
70 setVolScale(a);
71}
72
73static inline void setPatch(int ch, int pat)
74{
75 chPat[ch]=pat;
76}
77
78/*
79 This is the new pitch bend table. There are 512 entries.
80 The middle entry is exactly 65536 - no bending.
81
82 The range of the table is one semitone /in either direction/
83 Ie, one semitone from the center.
84
85 Bends beyond this can be achieved by first offsetting the index
86 into the GUS frequency table by the appropriate number of semitones,
87 and then using this table to bend the rest of the way.
88
89 Generated using Matlab code:
90 for i=0:512, fprintf('%d,', round(2^16*2^((i-256)/1536))); end
91*/
92
93const uint32_t pitchTbl[] ICONST_ATTR={
94 61858,61872,61886,61900,61914,61928,61942,61956,61970,61983,61997,62011,
95 62025,62039,62053,62067,62081,62095,62109,62124,62138,62152,62166,62180,
96 62194,62208,62222,62236,62250,62264,62278,62292,62306,62320,62334,62348,
97 62362,62376,62390,62404,62419,62433,62447,62461,62475,62489,62503,62517,
98 62531,62545,62560,62574,62588,62602,62616,62630,62644,62658,62673,62687,
99 62701,62715,62729,62743,62757,62772,62786,62800,62814,62828,62843,62857,
100 62871,62885,62899,62913,62928,62942,62956,62970,62984,62999,63013,63027,
101 63041,63056,63070,63084,63098,63112,63127,63141,63155,63169,63184,63198,
102 63212,63227,63241,63255,63269,63284,63298,63312,63326,63341,63355,63369,
103 63384,63398,63412,63427,63441,63455,63470,63484,63498,63512,63527,63541,
104 63555,63570,63584,63599,63613,63627,63642,63656,63670,63685,63699,63713,
105 63728,63742,63757,63771,63785,63800,63814,63829,63843,63857,63872,63886,
106 63901,63915,63929,63944,63958,63973,63987,64002,64016,64030,64045,64059,
107 64074,64088,64103,64117,64132,64146,64161,64175,64190,64204,64219,64233,
108 64248,64262,64277,64291,64306,64320,64335,64349,64364,64378,64393,64407,
109 64422,64436,64451,64465,64480,64494,64509,64524,64538,64553,64567,64582,
110 64596,64611,64626,64640,64655,64669,64684,64699,64713,64728,64742,64757,
111 64772,64786,64801,64815,64830,64845,64859,64874,64889,64903,64918,64933,
112 64947,64962,64976,64991,65006,65020,65035,65050,65065,65079,65094,65109,
113 65123,65138,65153,65167,65182,65197,65211,65226,65241,65256,65270,65285,
114 65300,65315,65329,65344,65359,65374,65388,65403,65418,65433,65447,65462,
115 65477,65492,65506,65521,65536,65551,65566,65580,65595,65610,65625,65640,
116 65654,65669,65684,65699,65714,65729,65743,65758,65773,65788,65803,65818,
117 65832,65847,65862,65877,65892,65907,65922,65936,65951,65966,65981,65996,
118 66011,66026,66041,66056,66071,66085,66100,66115,66130,66145,66160,66175,
119 66190,66205,66220,66235,66250,66265,66280,66294,66309,66324,66339,66354,
120 66369,66384,66399,66414,66429,66444,66459,66474,66489,66504,66519,66534,
121 66549,66564,66579,66594,66609,66624,66639,66654,66670,66685,66700,66715,
122 66730,66745,66760,66775,66790,66805,66820,66835,66850,66865,66880,66896,
123 66911,66926,66941,66956,66971,66986,67001,67016,67032,67047,67062,67077,
124 67092,67107,67122,67137,67153,67168,67183,67198,67213,67228,67244,67259,
125 67274,67289,67304,67320,67335,67350,67365,67380,67395,67411,67426,67441,
126 67456,67472,67487,67502,67517,67532,67548,67563,67578,67593,67609,67624,
127 67639,67655,67670,67685,67700,67716,67731,67746,67761,67777,67792,67807,
128 67823,67838,67853,67869,67884,67899,67915,67930,67945,67961,67976,67991,
129 68007,68022,68037,68053,68068,68083,68099,68114,68129,68145,68160,68176,
130 68191,68206,68222,68237,68252,68268,68283,68299,68314,68330,68345,68360,
131 68376,68391,68407,68422,68438,68453,68468,68484,68499,68515,68530,68546,
132 68561,68577,68592,68608,68623,68639,68654,68670,68685,68701,68716,68732,
133 68747,68763,68778,68794,68809,68825,68840,68856,68871,68887,68902,68918,
134 68933,68949,68965,68980,68996,69011,69027,69042,69058,69074,69089,69105,
135 69120,69136,69152,69167,69183,69198,69214,69230,69245,69261,69276,69292,
136 69308,69323,69339,69355,69370,69386,69402,69417,69433
137};
138
139
140static void findDelta(struct SynthObject * so, int ch, int note)
141{
142 struct GWaveform * wf =
143 patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
144 so->wf = wf;
145
146 /* Used to be unsigned int, but math had to be done in different order to avoid overflow */
147 unsigned long long delta = 0;
148
149/*
150 Old formula:
151 delta = (((freqtable[note+chPBNoteOffset[ch]]<<FRACTSIZE) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
152
153 Plus some pitch stuff. See old SVN for how it used to be
154*/
155
156 delta = (((freqtable[note+chPBNoteOffset[ch]]))); /* anywhere from 8000 to 8000000 */
157 delta = delta * wf->sampRate; /* approx 20000 - 44000 but can vary with tuning */
158 delta = (delta * chPBFractBend[ch]); /* approx 60000 - 70000 */
159 delta = delta / (SAMPLE_RATE); /* 44100 or 22050 */
160 delta = delta / (wf->rootFreq); /* anywhere from 8000 to 8000000 */
161
162 /* Pitch bend is encoded as a fractional of 16 bits, hence the 16 */
163 delta = delta >> (16 - FRACTSIZE); /* a shift of approx 4 bits */
164 so->delta = delta;
165}
166
167static inline void computeDeltas(int ch)
168{
169 int a;
170 for (a = 0; a < MAX_VOICES; a++)
171 {
172 if (voices[a].isUsed && voices[a].ch == ch)
173 {
174 findDelta(&voices[a], ch, voices[a].note);
175 }
176 }
177}
178
179static inline void setPW(int ch, int msb, int lsb)
180{
181 chPW[ch] = msb<<2|lsb>>5;
182
183 int totalBend = (chPW[ch]-256) * chPBDepth[ch];
184 chPBNoteOffset[ch] = totalBend >> 8;
185 chPBFractBend[ch] = pitchTbl[(totalBend & 0xFF) + 256];
186
187 computeDeltas(ch);
188}
189
190static inline void pressNote(int ch, int note, int vol)
191{
192 static int lastKill = 0;
193/* Silences all channels but one, for easy debugging, for me. */
194/*
195 if(ch == 0) return;
196 if(ch == 1) return;
197 if(ch == 2) return;
198 if(ch == 3) return;
199 if(ch == 4) return;
200 if(ch == 5) return;
201 if(ch == 6) return;
202 if(ch == 7) return;
203 if(ch == 8) return;
204 if(ch == 9) return;
205 if(ch == 10) return;
206 if(ch == 11) return;
207 if(ch == 12) return;
208 if(ch == 13) return;
209 if(ch == 14) return;
210 if(ch == 15) return;
211*/
212 int a;
213 for (a = 0; a < MAX_VOICES; a++)
214 {
215 if (voices[a].ch == ch && voices[a].note == note)
216 break;
217
218 if (!voices[a].isUsed)
219 break;
220 }
221 if (a == MAX_VOICES)
222 {
223// midi_debug("\nVoice kill");
224// midi_debug("\nToo many voices playing at once. No more left");
225// midi_debug("\nVOICE DUMP: ");
226// for(a=0; a<48; a++)
227// midi_debug("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset);
228 lastKill++;
229 if (lastKill == MAX_VOICES)
230 lastKill = 0;
231 a = lastKill;
232// return; /* None available */
233 }
234 voices[a].ch = ch;
235 voices[a].note = note;
236 voices[a].vol = vol;
237 voices[a].cp = 0;
238 voices[a].state = STATE_ATTACK;
239 voices[a].decay = 255;
240
241 setVolScale(a);
242
243 voices[a].loopState=STATE_NONLOOPING;
244 /*
245 * OKAY. Gt = Gus Table value
246 * rf = Root Frequency of wave
247 * SR = sound sampling rate
248 * sr = WAVE sampling rate
249 */
250
251 if (ch != 9)
252 {
253 findDelta(&voices[a], ch, note);
254 /* Turn it on */
255 voices[a].isUsed = true;
256 setPoint(&voices[a], 0);
257 } else
258 {
259 if (drumSet[note] != NULL)
260 {
261 if (note < 35)
262 midi_debug("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
263
264 struct GWaveform * wf = drumSet[note]->waveforms[0];
265 voices[a].wf = wf;
266 voices[a].delta = (((freqtable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
267 if (wf->mode & 28)
268// midi_debug("\nWoah, a drum patch has a loop. Stripping the loop...");
269 wf->mode = wf->mode & (255-28);
270
271 /* Turn it on */
272 voices[a].isUsed = true;
273 setPoint(&voices[a], 0);
274
275 } else
276 {
277/* midi_debug("\nWarning: drum %d does not have a patch defined... Ignoring it", note); */
278 }
279 }
280}
281
282static void releaseNote(int ch, int note)
283{
284 if (ch == 9)
285 return;
286
287 int a;
288 for (a = 0; a < MAX_VOICES; a++)
289 {
290 if (voices[a].ch == ch && voices[a].note == note)
291 {
292 if (voices[a].wf->mode & 28)
293 {
294 setPoint(&voices[a], 3);
295 }
296 }
297 }
298}
299
300static void sendEvent(struct Event * ev)
301{
302 const unsigned char status_low = ev->status & 0x0F;
303 const unsigned char d1 = ev->d1;
304 const unsigned char d2 = ev->d2;
305 switch (ev->status & 0xF0)
306 {
307 case MIDI_CONTROL:
308 switch (d1)
309 {
310 case CTRL_VOLUME:
311 {
312 setVol((status_low), d2);
313 return;
314 }
315 case CTRL_PANNING:
316 {
317 chPan[status_low] = d2;
318 return;
319 }
320 case CTRL_DATAENT_MSB:
321 {
322 /* TODO: Update all deltas. Is this really needed? */
323 if(chLastCtrlMSB[status_low] == REG_PITCHBEND_MSB &&
324 chLastCtrlLSB[status_low] == REG_PITCHBEND_LSB)
325 {
326// midi_debug("Pitch bend depth set to %d\n", d2);
327 chPBDepth[status_low] = d2;
328 }
329 return;
330 }
331
332 case CTRL_NONREG_LSB:
333 {
334 chLastCtrlLSB[status_low] = 0xFF; /* Ignore nonregistered writes */
335 return;
336 }
337
338 case CTRL_NONREG_MSB:
339 {
340 chLastCtrlMSB[status_low] = 0xFF; /* Ignore nonregistered writes */
341 return;
342 }
343
344 case CTRL_REG_LSB:
345 {
346 chLastCtrlLSB[status_low] = d2;
347 return;
348 }
349
350 case CTRL_REG_MSB:
351 {
352 chLastCtrlMSB[status_low] = d2;
353 return;
354 }
355
356 }
357 break;
358
359 case MIDI_PITCHW:
360 setPW((status_low), d2, d1);
361 return;
362
363 case MIDI_NOTE_ON:
364 switch (d2)
365 {
366 case 0: /* Release by vol=0 */
367 releaseNote(status_low, d1);
368 return;
369
370 default:
371 pressNote(status_low, d1, d2);
372 return;
373 }
374
375 case MIDI_NOTE_OFF:
376 releaseNote(status_low, d1);
377 return;
378
379 case MIDI_PRGM:
380 if (status_low != 9)
381 setPatch(status_low, d1);
382 }
383}
384
385void rewindFile(void)
386{
387 int i;
388 for (i = 0; i < mf->numTracks; i++)
389 {
390 mf->tracks[i]->delta = 0;
391 mf->tracks[i]->pos = 0;
392 }
393}
394
395int tick(void) ICODE_ATTR;
396int tick(void)
397{
398 if (mf == NULL)
399 return 0;
400
401 int a, tracksAdv=0;
402 for (a = 0; a < mf->numTracks; a++)
403 {
404 struct Track * tr = mf->tracks[a];
405
406 if (tr == NULL)
407 midi_debug("NULL TRACK: %d", a);
408
409 //BIG DEBUG STATEMENT
410 //midi_debug("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
411
412 if (tr != NULL && (tr->pos < tr->numEvents))
413 {
414 tr->delta++;
415 tracksAdv++;
416 while (getEvent(tr, tr->pos)->delta <= tr->delta)
417 {
418 struct Event * e = getEvent(tr, tr->pos);
419
420 if (e->status != 0xFF)
421 {
422 sendEvent(e);
423 if ((e->status&0xF0) == MIDI_PRGM)
424 {
425/* midi_debug("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); */
426 }
427 }
428 else
429 {
430 if (e->d1 == 0x51)
431 {
432 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
433/* midi_debug("\nMeta-Event: Tempo Set = %d", tempo); */
434 bpm=mf->div*1000000/tempo;
435 number_of_samples=SAMPLE_RATE/bpm;
436
437 }
438 }
439 tr->delta = 0;
440 tr->pos++;
441 if (tr->pos >= (tr->numEvents-1))
442 break;
443 }
444 }
445 }
446
447 samples_this_second += number_of_samples;
448
449 while (samples_this_second >= SAMPLE_RATE)
450 {
451 samples_this_second -= SAMPLE_RATE;
452 playing_time++;
453 }
454
455 if (tracksAdv != 0)
456 return 1;
457 else
458 return 0;
459}
460
461void seekBackward(int nsec)
462{
463 int notes_used, a;
464 int desired_time = playing_time - nsec; /* Rewind 5 sec */
465
466 if (desired_time < 0)
467 desired_time = 0;
468
469 /* Set controllers to default values */
470 resetControllers();
471
472 /* Set the tempo to defalt */
473 bpm = mf->div*1000000/tempo;
474 number_of_samples = SAMPLE_RATE/bpm;
475
476 /* Reset the tracks to start */
477 rewindFile();
478
479 /* Reset the time counter to 0 */
480 playing_time = 0;
481 samples_this_second = 0;
482
483 /* Quickly run through any initial things that occur before notes */
484 do
485 {
486 notes_used = 0;
487 for (a = 0; a < MAX_VOICES; a++)
488 if (voices[a].isUsed)
489 notes_used++;
490 tick();
491 } while (notes_used == 0);
492
493 /* Reset the time counter to 0 */
494 playing_time = 0;
495 samples_this_second = 0;
496
497 /* Tick until goal is reached */
498 while (playing_time < desired_time)
499 tick();
500}
501
502void seekForward(int nsec)
503{
504 int desired_time = playing_time + nsec;
505 while (tick() && playing_time < desired_time);
506}
507