Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

plugins: midi: remove HW_SAMPR_CAPS usage

Change-Id: Ie4962cf6d4f2f9078fa348f8f6f638cfbc0047a5

authored by

mojyack and committed by
Solomon Peachy
9c708e38 e923b354

+75 -82
+55 -3
apps/plugins/midi/midiplay.c
··· 381 381 382 382 struct MIDIfile * mf IBSS_ATTR; 383 383 384 + int sample_rate IBSS_ATTR; 385 + int max_voices IBSS_ATTR; 384 386 int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */ 385 387 int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */ 386 388 int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */ ··· 490 492 *size = samples_in_buf*sizeof(int32_t); 491 493 } 492 494 495 + static const struct mixer_play_cbs mixer_cbs = { 496 + .get_more = get_more, 497 + /* TODO: update sample_rate and max_voices on sampr_changed() */ 498 + }; 499 + 500 + UNUSED_ATTR static int find_min_sampr_ge_22(void) 501 + { 502 + const struct pcm_sink_caps* caps = rb->pcm_current_sink_caps(); 503 + int ret = caps->samprs[0]; 504 + for (size_t i = 1; i < caps->num_samprs; i += 1) 505 + { 506 + /* caps->samprs is in descending order */ 507 + if (caps->samprs[i] >= SAMPR_22) 508 + ret = caps->samprs[i]; 509 + else 510 + break; 511 + } 512 + return ret; 513 + } 514 + 493 515 static int midimain(const void * filename) 494 516 { 495 517 int a, notes_used, vol; 496 518 bool is_playing = true; /* false = paused */ 497 519 520 + /* decide sample_rate and max_voices */ 521 + #if defined(SIMULATOR) /* Simulator requires 44100Hz, and we can afford to use more voices */ || \ 522 + (CONFIG_PLATFORM & PLATFORM_HOSTED) /* All hosted targets have CPU to spare */ || \ 523 + defined(CPU_MIPS) /* All MIPS targets are pretty fast */ 524 + sample_rate = SAMPR_44; 525 + max_voices = 48; 526 + #elif defined(CPU_PP) 527 + /* Some of the pp based targets can't handle too many voices 528 + mainly because they have to use 44100Hz sample rate, this could be 529 + improved to increase max_voices for targets that can do 22kHz */ 530 + sample_rate = find_min_sampr_ge_22(); 531 + max_voices = sample_rate == SAMPR_22 ? 24 : 16; 532 + #elif defined(CPU_ARM) 533 + /* ARMv4 targets are slow, but treat everything else as fast */ 534 + #if (ARM_ARCH >= 6) 535 + sample_rate = SAMPR_44; 536 + max_voices = 32; 537 + #elif (ARM_ARCH >= 5) 538 + sample_rate = find_min_sampr_ge_22(); 539 + max_voices = 32; 540 + #else /* ie v4 */ 541 + sample_rate = find_min_sampr_ge_22(); 542 + max_voices = sample_rate == SAMPR_22 ? 24 : 16; 543 + #endif 544 + #else /* !CPU_ARM */ 545 + /* Treat everything else as slow */ 546 + sample_rate = find_min_sampr_ge_22(); 547 + max_voices = sample_rate == SAMPR_22 ? 24 : 16; 548 + #endif 549 + 498 550 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) 499 551 rb->cpu_boost(true); 500 552 #endif ··· 537 589 rb->dsp_set_timestretch(PITCH_SPEED_100); 538 590 #endif 539 591 rb->dsp_configure(dsp, DSP_SET_SAMPLE_DEPTH, 22); 540 - rb->dsp_configure(dsp, DSP_SET_FREQUENCY, SAMPLE_RATE); /* 44100 22050 11025 */ 592 + rb->dsp_configure(dsp, DSP_SET_FREQUENCY, sample_rate); /* 44100 22050 11025 */ 541 593 rb->dsp_configure(dsp, DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); 542 594 543 595 /* ··· 553 605 midi_debug("Okay, starting sequencing"); 554 606 555 607 bpm = mf->div*1000000/tempo; 556 - number_of_samples = SAMPLE_RATE/bpm; 608 + number_of_samples = sample_rate/bpm; 557 609 558 610 /* Skip over any junk in the beginning of the file, so start playing */ 559 611 /* after the first note event */ 560 612 do 561 613 { 562 614 notes_used = 0; 563 - for (a = 0; a < MAX_VOICES; a++) 615 + for (a = 0; a < max_voices; a++) 564 616 if (voices[a].isUsed) 565 617 notes_used++; 566 618 tick();
+1 -1
apps/plugins/midi/midiutil.c
··· 35 35 struct GPatch * patchSet[128]; 36 36 struct GPatch * drumSet[128]; 37 37 38 - struct SynthObject voices[MAX_VOICES] IBSS_ATTR; 38 + struct SynthObject voices[48] IBSS_ATTR; 39 39 40 40 static void *alloc(int size) 41 41 {
+3 -62
apps/plugins/midi/midiutil.h
··· 27 27 #define NBUF 2 28 28 #define MAX_SAMPLES 512 29 29 30 - #ifdef SIMULATOR 31 - 32 - /* Simulator requires 44100Hz, and we can afford to use more voices */ 33 - #define SAMPLE_RATE SAMPR_44 34 - #define MAX_VOICES 48 35 - 36 - #elif (CONFIG_PLATFORM & PLATFORM_HOSTED) 37 - 38 - /* All hosted targets have CPU to spare */ 39 - #define MAX_VOICES 48 40 - #define SAMPLE_RATE SAMPR_44 41 - 42 - #elif defined(CPU_PP) 43 - 44 - /* Some of the pp based targets can't handle too many voices 45 - mainly because they have to use 44100Hz sample rate, this could be 46 - improved to increase MAX_VOICES for targets that can do 22kHz */ 47 - #define SAMPLE_RATE HW_SAMPR_MIN_GE_22 48 - #if HW_SAMPR_CAPS & SAMPR_CAP_22 49 - #define MAX_VOICES 24 /* General MIDI minimum */ 50 - #else 51 - #define MAX_VOICES 16 52 - #endif 53 - 54 - #elif defined(CPU_MIPS) 55 - 56 - /* All MIPS targets are pretty fast */ 57 - #define MAX_VOICES 48 58 - #define SAMPLE_RATE SAMPR_44 59 - 60 - #elif defined(CPU_ARM) 61 - 62 - /* ARMv4 targets are slow, but treat everything else as fast */ 63 - 64 - #if (ARM_ARCH >= 6) 65 - #define MAX_VOICES 32 66 - #define SAMPLE_RATE SAMPR_44 67 - #elif (ARM_ARCH >= 5) 68 - #define MAX_VOICES 32 69 - #define SAMPLE_RATE HW_SAMPR_MIN_GE_22 70 - #else /* ie v4 */ 71 - #define SAMPLE_RATE HW_SAMPR_MIN_GE_22 72 - #if HW_SAMPR_CAPS & SAMPR_CAP_22 73 - #define MAX_VOICES 24 /* General MIDI minimum */ 74 - #else 75 - #define MAX_VOICES 16 76 - #endif 77 - #endif /* ARM_ARCH < 5*/ 78 - 79 - #else /* !CPU_ARM */ 80 - 81 - /* Treat everything else as slow */ 82 - #define SAMPLE_RATE HW_SAMPR_MIN_GE_22 83 - #if HW_SAMPR_CAPS & SAMPR_CAP_22 84 - #define MAX_VOICES 24 /* General MIDI minimum */ 85 - #else 86 - #define MAX_VOICES 16 87 - #endif 88 - 89 - #endif /* Wrap it up. */ 90 - 91 30 #define BYTE unsigned char 92 31 93 32 /* Data chunk ID types, returned by readID() */ ··· 189 128 #define malloc(n) my_malloc(n) 190 129 void * my_malloc(int size); 191 130 192 - extern struct SynthObject voices[MAX_VOICES]; 131 + extern struct SynthObject voices[48]; /* 48: maximum possible max_voices */ 193 132 194 133 extern int chVol[16]; /* Channel volume */ 195 134 extern int chPan[16]; /* Channel panning */ ··· 207 146 208 147 extern struct MIDIfile * mf; 209 148 149 + extern int sample_rate; 150 + extern int max_voices; 210 151 extern int number_of_samples; 211 152 extern int playing_time IBSS_ATTR; 212 153 extern int samples_this_second IBSS_ATTR;
+13 -13
apps/plugins/midi/sequencer.c
··· 65 65 66 66 /* If channel volume changes, we need to recalculate the volume scale */ 67 67 /* factor for all voices active on this channel */ 68 - for (a = 0; a < MAX_VOICES; a++) 68 + for (a = 0; a < max_voices; a++) 69 69 if (voices[a].ch == ch) 70 70 setVolScale(a); 71 71 } ··· 156 156 delta = (((freqtable[note+chPBNoteOffset[ch]]))); /* anywhere from 8000 to 8000000 */ 157 157 delta = delta * wf->sampRate; /* approx 20000 - 44000 but can vary with tuning */ 158 158 delta = (delta * chPBFractBend[ch]); /* approx 60000 - 70000 */ 159 - delta = delta / (SAMPLE_RATE); /* 44100 or 22050 */ 159 + delta = delta / (sample_rate); /* 44100 or 22050 */ 160 160 delta = delta / (wf->rootFreq); /* anywhere from 8000 to 8000000 */ 161 161 162 162 /* Pitch bend is encoded as a fractional of 16 bits, hence the 16 */ ··· 167 167 static inline void computeDeltas(int ch) 168 168 { 169 169 int a; 170 - for (a = 0; a < MAX_VOICES; a++) 170 + for (a = 0; a < max_voices; a++) 171 171 { 172 172 if (voices[a].isUsed && voices[a].ch == ch) 173 173 { ··· 210 210 if(ch == 15) return; 211 211 */ 212 212 int a; 213 - for (a = 0; a < MAX_VOICES; a++) 213 + for (a = 0; a < max_voices; a++) 214 214 { 215 215 if (voices[a].ch == ch && voices[a].note == note) 216 216 break; ··· 218 218 if (!voices[a].isUsed) 219 219 break; 220 220 } 221 - if (a == MAX_VOICES) 221 + if (a == max_voices) 222 222 { 223 223 // midi_debug("\nVoice kill"); 224 224 // midi_debug("\nToo many voices playing at once. No more left"); ··· 226 226 // for(a=0; a<48; a++) 227 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 228 lastKill++; 229 - if (lastKill == MAX_VOICES) 229 + if (lastKill == max_voices) 230 230 lastKill = 0; 231 231 a = lastKill; 232 232 // return; /* None available */ ··· 263 263 264 264 struct GWaveform * wf = drumSet[note]->waveforms[0]; 265 265 voices[a].wf = wf; 266 - voices[a].delta = (((freqtable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); 266 + voices[a].delta = (((freqtable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / sample_rate); 267 267 if (wf->mode & 28) 268 268 // midi_debug("\nWoah, a drum patch has a loop. Stripping the loop..."); 269 269 wf->mode = wf->mode & (255-28); ··· 285 285 return; 286 286 287 287 int a; 288 - for (a = 0; a < MAX_VOICES; a++) 288 + for (a = 0; a < max_voices; a++) 289 289 { 290 290 if (voices[a].ch == ch && voices[a].note == note) 291 291 { ··· 432 432 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); 433 433 /* midi_debug("\nMeta-Event: Tempo Set = %d", tempo); */ 434 434 bpm=mf->div*1000000/tempo; 435 - number_of_samples=SAMPLE_RATE/bpm; 435 + number_of_samples=sample_rate/bpm; 436 436 437 437 } 438 438 } ··· 446 446 447 447 samples_this_second += number_of_samples; 448 448 449 - while (samples_this_second >= SAMPLE_RATE) 449 + while (samples_this_second >= sample_rate) 450 450 { 451 - samples_this_second -= SAMPLE_RATE; 451 + samples_this_second -= sample_rate; 452 452 playing_time++; 453 453 } 454 454 ··· 471 471 472 472 /* Set the tempo to defalt */ 473 473 bpm = mf->div*1000000/tempo; 474 - number_of_samples = SAMPLE_RATE/bpm; 474 + number_of_samples = sample_rate/bpm; 475 475 476 476 /* Reset the tracks to start */ 477 477 rewindFile(); ··· 484 484 do 485 485 { 486 486 notes_used = 0; 487 - for (a = 0; a < MAX_VOICES; a++) 487 + for (a = 0; a < max_voices; a++) 488 488 if (voices[a].isUsed) 489 489 notes_used++; 490 490 tick();
+3 -3
apps/plugins/midi/synth.c
··· 46 46 void resetControllers() 47 47 { 48 48 int a=0; 49 - for(a=0; a<MAX_VOICES; a++) 49 + for(a=0; a<max_voices; a++) 50 50 { 51 51 voices[a].cp=0; 52 52 voices[a].vol=0; ··· 448 448 size_t synthSamples(int32_t *buf_ptr, size_t num_samples) ICODE_ATTR; 449 449 size_t synthSamples(int32_t *buf_ptr, size_t num_samples) 450 450 { 451 - unsigned int i; 451 + int i; 452 452 struct SynthObject *voicept; 453 453 size_t nsamples = MIN(num_samples, MAX_SAMPLES); 454 454 455 455 rb->memset(buf_ptr, 0, nsamples * 2 * sizeof(int32_t)); 456 456 457 - for(i=0; i < MAX_VOICES; i++) 457 + for(i=0; i < max_voices; i++) 458 458 { 459 459 voicept=&voices[i]; 460 460 if(voicept->isUsed)