A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

rbcodec: abstract tdspeed buffer allocation

Move code dealing with rockbox specific buflib allocations into a
rockbox specific file and implement buffer allocation with
malloc/free for warble/stand alone lib.
Based on patch by Sean Bartell.

Change-Id: I8cb85dad5890fbd34c1bb26abbb89c0b0f6b55cf
Reviewed-on: http://gerrit.rockbox.org/144
Tested-by: Nils Wallménius <nils@rockbox.org>
Reviewed-by: Michael Sevakis <jethead71@rockbox.org>
Reviewed-by: Nils Wallménius <nils@rockbox.org>

+173 -110
+1
apps/SOURCES
··· 26 26 menus/eq_menu.c 27 27 buffering.c 28 28 voice_thread.c 29 + rbcodec_helpers.c 29 30 #else /* !SWCODEC */ 30 31 mpeg.c 31 32 #endif
+102
apps/rbcodec_helpers.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2006 by Nicolas Pitre <nico@cam.org> 11 + * Copyright (C) 2006-2007 by Stéphane Doyon <s.doyon@videotron.ca> 12 + * Copyright (C) 2012 Michael Sevakis 13 + * 14 + * This program is free software; you can redistribute it and/or 15 + * modify it under the terms of the GNU General Public License 16 + * as published by the Free Software Foundation; either version 2 17 + * of the License, or (at your option) any later version. 18 + * 19 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 + * KIND, either express or implied. 21 + * 22 + ****************************************************************************/ 23 + 24 + #include "platform.h" 25 + #include "dsp_core.h" 26 + #include "core_alloc.h" 27 + #include "tdspeed.h" 28 + 29 + static int handles[4] = { 0, 0, 0, 0 }; 30 + 31 + static int move_callback(int handle, void *current, void *new) 32 + { 33 + #if 0 34 + /* Should not currently need to block this since DSP loop completes an 35 + iteration before yielding and begins again at its input buffer */ 36 + if (dsp_is_busy(tdspeed_state.dsp)) 37 + return BUFLIB_CB_CANNOT_MOVE; /* DSP processing in progress */ 38 + #endif 39 + 40 + for (unsigned int i = 0; i < ARRAYLEN(handles); i++) 41 + { 42 + if (handle != handles[i]) 43 + continue; 44 + 45 + tdspeed_move(i, current, new); 46 + break; 47 + } 48 + 49 + return BUFLIB_CB_OK; 50 + } 51 + 52 + static struct buflib_callbacks ops = 53 + { 54 + .move_callback = move_callback, 55 + .shrink_callback = NULL, 56 + }; 57 + 58 + /* Allocate timestretch buffers */ 59 + bool tdspeed_alloc_buffers(int32_t **buffers, const int *buf_s, int nbuf) 60 + { 61 + static const char *buffer_names[4] = { 62 + "tdspeed ovl L", 63 + "tdspeed ovl R", 64 + "tdspeed out L", 65 + "tdspeed out R" 66 + }; 67 + 68 + for (int i = 0; i < nbuf; i++) 69 + { 70 + if (handles[i] <= 0) 71 + { 72 + handles[i] = core_alloc_ex(buffer_names[i], buf_s[i], &ops); 73 + 74 + if (handles[i] <= 0) 75 + return false; 76 + } 77 + 78 + if (buffers[i] == NULL) 79 + { 80 + buffers[i] = core_get_data(handles[i]); 81 + 82 + if (buffers[i] == NULL) 83 + return false; 84 + } 85 + } 86 + 87 + return true; 88 + } 89 + 90 + /* Free timestretch buffers */ 91 + void tdspeed_free_buffers(int32_t **buffers, int nbuf) 92 + { 93 + for (int i = 0; i < nbuf; i++) 94 + { 95 + if (handles[i] > 0) 96 + core_free(handles[i]); 97 + 98 + handles[i] = 0; 99 + buffers[i] = NULL; 100 + } 101 + } 102 +
+4
apps/rbcodecplatform.h
··· 31 31 #include "dsp-util.h" 32 32 #define HAVE_CLIP_SAMPLE_16 33 33 #endif 34 + 35 + bool tdspeed_alloc_buffers(int32_t **buffers, const int *buf_s, int nbuf); 36 + void tdspeed_free_buffers(int32_t **buffers, int nbuf); 37 + 34 38 #endif 35 39
+42 -106
lib/rbcodec/dsp/tdspeed.c
··· 20 20 * KIND, either express or implied. 21 21 * 22 22 ****************************************************************************/ 23 + #include "platform.h" 23 24 #include "config.h" 24 - #include "system.h" 25 25 #include "sound.h" 26 26 #include "core_alloc.h" 27 27 #include "dsp-util.h" 28 28 #include "dsp_proc_entry.h" 29 29 #include "tdspeed.h" 30 30 31 + #ifndef assert 31 32 #define assert(cond) 33 + #endif 32 34 33 35 #define TIMESTRETCH_SET_FACTOR (DSP_PROC_SETTING+DSP_PROC_TIMESTRETCH) 34 36 ··· 39 41 #define MAX_INPUTCOUNT 512 /* Max input count so dst doesn't overflow */ 40 42 #define FIXED_BUFCOUNT 3072 /* 48KHz factor 3.0 */ 41 43 #define FIXED_OUTBUFCOUNT 4096 44 + #define NBUFFERS 4 42 45 43 46 enum tdspeed_ops 44 47 { ··· 64 67 int32_t *ovl_buff[2]; /* overlap buffer (L+R) */ 65 68 } tdspeed_state; 66 69 67 - static int handles[4] = { 0, 0, 0, 0 }; 68 - static int32_t *buffers[4] = { NULL, NULL, NULL, NULL }; 70 + static int32_t *buffers[NBUFFERS] = { NULL, NULL, NULL, NULL }; 71 + static const int buffer_sizes[NBUFFERS] = { 72 + FIXED_BUFCOUNT * sizeof(int32_t), 73 + FIXED_BUFCOUNT * sizeof(int32_t), 74 + FIXED_OUTBUFCOUNT * sizeof(int32_t), 75 + FIXED_OUTBUFCOUNT * sizeof(int32_t) 76 + }; 69 77 70 78 #define overlap_buffer (&buffers[0]) 71 79 #define outbuf (&buffers[2]) ··· 73 81 74 82 /* Processed buffer passed out to later stages */ 75 83 static struct dsp_buffer dsp_outbuf; 76 - 77 - static int move_callback(int handle, void *current, void *new) 78 - { 79 - #if 0 80 - /* Should not currently need to block this since DSP loop completes an 81 - iteration before yielding and begins again at its input buffer */ 82 - if (dsp_is_busy(tdspeed_state.dsp)) 83 - return BUFLIB_CB_CANNOT_MOVE; /* DSP processing in progress */ 84 - #endif 85 - 86 - ptrdiff_t shift = (int32_t *)new - (int32_t *)current; 87 - int32_t **p32 = dsp_outbuf.p32; 88 - 89 - for (unsigned int i = 0; i < ARRAYLEN(handles); i++) 90 - { 91 - if (handle != handles[i]) 92 - continue; 93 - 94 - switch (i) 95 - { 96 - case 0: case 1: 97 - /* moving overlap (input) buffers */ 98 - tdspeed_state.ovl_buff[i] = new; 99 - break; 100 - 101 - case 2: 102 - /* moving outbuf left channel and dsp_outbuf.p32[0] */ 103 - if (p32[0] == p32[1]) 104 - p32[1] += shift; /* mono mode */ 105 - 106 - p32[0] += shift; 107 - break; 108 - 109 - case 3: 110 - /* moving outbuf right channel and dsp_outbuf.p32[1] */ 111 - p32[1] += shift; 112 - break; 113 - } 114 - 115 - buffers[i] = new; 116 - break; 117 - } 118 - 119 - return BUFLIB_CB_OK; 120 - } 121 - 122 - static struct buflib_callbacks ops = 123 - { 124 - .move_callback = move_callback, 125 - .shrink_callback = NULL, 126 - }; 127 - 128 - /* Allocate timestretch buffers */ 129 - static bool tdspeed_alloc_buffers(void) 130 - { 131 - static const struct 132 - { 133 - const char *name; 134 - size_t size; 135 - } bufdefs[4] = 136 - { 137 - { "tdspeed ovl L", FIXED_BUFCOUNT * sizeof(int32_t) }, 138 - { "tdspeed ovl R", FIXED_BUFCOUNT * sizeof(int32_t) }, 139 - { "tdspeed out L", FIXED_OUTBUFCOUNT * sizeof(int32_t) }, 140 - { "tdspeed out R", FIXED_OUTBUFCOUNT * sizeof(int32_t) }, 141 - }; 142 - 143 - for (unsigned int i = 0; i < ARRAYLEN(bufdefs); i++) 144 - { 145 - if (handles[i] <= 0) 146 - { 147 - handles[i] = core_alloc_ex(bufdefs[i].name, bufdefs[i].size, &ops); 148 - 149 - if (handles[i] <= 0) 150 - return false; 151 - } 152 - 153 - if (buffers[i] == NULL) 154 - { 155 - buffers[i] = core_get_data(handles[i]); 156 - 157 - if (buffers[i] == NULL) 158 - return false; 159 - } 160 - } 161 - 162 - return true; 163 - } 164 - 165 - /* Free timestretch buffers */ 166 - static void tdspeed_free_buffers(void) 167 - { 168 - for (unsigned int i = 0; i < ARRAYLEN(handles); i++) 169 - { 170 - if (handles[i] > 0) 171 - core_free(handles[i]); 172 - 173 - handles[i] = 0; 174 - buffers[i] = NULL; 175 - } 176 - } 177 84 178 85 /* Discard all data */ 179 86 static void tdspeed_flush(void) ··· 650 557 break; 651 558 652 559 case DSP_PROC_INIT: 653 - if (!tdspeed_alloc_buffers()) 560 + if (!tdspeed_alloc_buffers(buffers, buffer_sizes, NBUFFERS)) 654 561 return -1; /* fail the init */ 655 562 656 563 st->this = this; ··· 664 571 st->this = NULL; 665 572 st->factor = PITCH_SPEED_100; 666 573 dsp_outbuf.remcount = 0; 667 - tdspeed_free_buffers(); 574 + tdspeed_free_buffers(buffers, NBUFFERS); 668 575 break; 669 576 670 577 case TIMESTRETCH_SET_FACTOR: ··· 678 585 679 586 return 1; 680 587 (void)value; 588 + } 589 + 590 + void tdspeed_move(int i, void* current, void* new) 591 + { 592 + ptrdiff_t shift = (int32_t *)new - (int32_t *)current; 593 + int32_t **p32 = dsp_outbuf.p32; 594 + 595 + switch (i) 596 + { 597 + case 0: case 1: 598 + /* moving overlap (input) buffers */ 599 + tdspeed_state.ovl_buff[i] = new; 600 + break; 601 + 602 + case 2: 603 + /* moving outbuf left channel and dsp_outbuf.p32[0] */ 604 + if (p32[0] == p32[1]) 605 + p32[1] += shift; /* mono mode */ 606 + 607 + p32[0] += shift; 608 + break; 609 + 610 + case 3: 611 + /* moving outbuf right channel and dsp_outbuf.p32[1] */ 612 + p32[1] += shift; 613 + break; 614 + } 615 + 616 + buffers[i] = new; 681 617 } 682 618 683 619 /* Database entry */
+1
lib/rbcodec/dsp/tdspeed.h
··· 39 39 void dsp_set_timestretch(int32_t percent); 40 40 int32_t dsp_get_timestretch(void); 41 41 bool dsp_timestretch_available(void); 42 + void tdspeed_move(int i, void* current, void* new); 42 43 43 44 #endif /* _TDSPEED_H */
+23
lib/rbcodec/rbcodecplatform-unix.h
··· 74 74 #endif 75 75 #endif 76 76 */ 77 + 78 + static inline bool tdspeed_alloc_buffers(int32_t **buffers, 79 + const int *buf_s, int nbuf) 80 + { 81 + int i; 82 + for (i = 0; i < nbuf; i++) 83 + { 84 + buffers[i] = malloc(buf_s[i]); 85 + if (!buffers[i]) 86 + return false; 87 + } 88 + return true; 89 + } 90 + 91 + static inline void tdspeed_free_buffers(int32_t **buffers, int nbuf) 92 + { 93 + int i; 94 + for (i = 0; i < nbuf; i++) 95 + { 96 + free(buffers[i]); 97 + } 98 + } 99 + 77 100 #endif
-2
lib/rbcodec/test/SOURCES
··· 1 1 warble.c 2 - ../../../firmware/buflib.c 3 - ../../../firmware/core_alloc.c 4 2 ../../../firmware/common/strlcpy.c 5 3 ../../../firmware/common/unicode.c 6 4 ../../../firmware/common/structec.c
-2
lib/rbcodec/test/warble.c
··· 33 33 #include <unistd.h> 34 34 #include "buffering.h" /* TYPE_PACKET_AUDIO */ 35 35 #include "codecs.h" 36 - #include "core_alloc.h" /* core_allocator_init */ 37 36 #include "dsp_core.h" 38 37 #include "metadata.h" 39 38 #include "settings.h" ··· 851 850 } 852 851 } 853 852 854 - core_allocator_init(); 855 853 if (argc == optind + 2) { 856 854 write_init(argv[optind + 1]); 857 855 } else if (argc == optind + 1) {