diff options
author | Nils Wallménius <nils@rockbox.org> | 2012-05-06 12:22:09 +0200 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-05-07 10:29:07 +0200 |
commit | 3f61caa0cd7e818416be08778f356efd54e596fb (patch) | |
tree | 9f0ca1be9d8cd4f0a2dcd8a3a7c20657925de21e /lib/rbcodec/dsp/tdspeed.c | |
parent | 51a73d81cda6136f901e8d56f4720dc28edf648a (diff) | |
download | rockbox-3f61caa0cd7e818416be08778f356efd54e596fb.tar.gz rockbox-3f61caa0cd7e818416be08778f356efd54e596fb.zip |
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>
Diffstat (limited to 'lib/rbcodec/dsp/tdspeed.c')
-rw-r--r-- | lib/rbcodec/dsp/tdspeed.c | 148 |
1 files changed, 42 insertions, 106 deletions
diff --git a/lib/rbcodec/dsp/tdspeed.c b/lib/rbcodec/dsp/tdspeed.c index 82b6b0ea95..ea1013e049 100644 --- a/lib/rbcodec/dsp/tdspeed.c +++ b/lib/rbcodec/dsp/tdspeed.c | |||
@@ -20,15 +20,17 @@ | |||
20 | * KIND, either express or implied. | 20 | * KIND, either express or implied. |
21 | * | 21 | * |
22 | ****************************************************************************/ | 22 | ****************************************************************************/ |
23 | #include "platform.h" | ||
23 | #include "config.h" | 24 | #include "config.h" |
24 | #include "system.h" | ||
25 | #include "sound.h" | 25 | #include "sound.h" |
26 | #include "core_alloc.h" | 26 | #include "core_alloc.h" |
27 | #include "dsp-util.h" | 27 | #include "dsp-util.h" |
28 | #include "dsp_proc_entry.h" | 28 | #include "dsp_proc_entry.h" |
29 | #include "tdspeed.h" | 29 | #include "tdspeed.h" |
30 | 30 | ||
31 | #ifndef assert | ||
31 | #define assert(cond) | 32 | #define assert(cond) |
33 | #endif | ||
32 | 34 | ||
33 | #define TIMESTRETCH_SET_FACTOR (DSP_PROC_SETTING+DSP_PROC_TIMESTRETCH) | 35 | #define TIMESTRETCH_SET_FACTOR (DSP_PROC_SETTING+DSP_PROC_TIMESTRETCH) |
34 | 36 | ||
@@ -39,6 +41,7 @@ | |||
39 | #define MAX_INPUTCOUNT 512 /* Max input count so dst doesn't overflow */ | 41 | #define MAX_INPUTCOUNT 512 /* Max input count so dst doesn't overflow */ |
40 | #define FIXED_BUFCOUNT 3072 /* 48KHz factor 3.0 */ | 42 | #define FIXED_BUFCOUNT 3072 /* 48KHz factor 3.0 */ |
41 | #define FIXED_OUTBUFCOUNT 4096 | 43 | #define FIXED_OUTBUFCOUNT 4096 |
44 | #define NBUFFERS 4 | ||
42 | 45 | ||
43 | enum tdspeed_ops | 46 | enum tdspeed_ops |
44 | { | 47 | { |
@@ -64,8 +67,13 @@ static struct tdspeed_state_s | |||
64 | int32_t *ovl_buff[2]; /* overlap buffer (L+R) */ | 67 | int32_t *ovl_buff[2]; /* overlap buffer (L+R) */ |
65 | } tdspeed_state; | 68 | } tdspeed_state; |
66 | 69 | ||
67 | static int handles[4] = { 0, 0, 0, 0 }; | 70 | static int32_t *buffers[NBUFFERS] = { NULL, NULL, NULL, NULL }; |
68 | static int32_t *buffers[4] = { 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 | #define overlap_buffer (&buffers[0]) | 78 | #define overlap_buffer (&buffers[0]) |
71 | #define outbuf (&buffers[2]) | 79 | #define outbuf (&buffers[2]) |
@@ -74,107 +82,6 @@ static int32_t *buffers[4] = { NULL, NULL, NULL, NULL }; | |||
74 | /* Processed buffer passed out to later stages */ | 82 | /* Processed buffer passed out to later stages */ |
75 | static struct dsp_buffer dsp_outbuf; | 83 | static struct dsp_buffer dsp_outbuf; |
76 | 84 | ||
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 | |||
178 | /* Discard all data */ | 85 | /* Discard all data */ |
179 | static void tdspeed_flush(void) | 86 | static void tdspeed_flush(void) |
180 | { | 87 | { |
@@ -650,7 +557,7 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this, | |||
650 | break; | 557 | break; |
651 | 558 | ||
652 | case DSP_PROC_INIT: | 559 | case DSP_PROC_INIT: |
653 | if (!tdspeed_alloc_buffers()) | 560 | if (!tdspeed_alloc_buffers(buffers, buffer_sizes, NBUFFERS)) |
654 | return -1; /* fail the init */ | 561 | return -1; /* fail the init */ |
655 | 562 | ||
656 | st->this = this; | 563 | st->this = this; |
@@ -664,7 +571,7 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this, | |||
664 | st->this = NULL; | 571 | st->this = NULL; |
665 | st->factor = PITCH_SPEED_100; | 572 | st->factor = PITCH_SPEED_100; |
666 | dsp_outbuf.remcount = 0; | 573 | dsp_outbuf.remcount = 0; |
667 | tdspeed_free_buffers(); | 574 | tdspeed_free_buffers(buffers, NBUFFERS); |
668 | break; | 575 | break; |
669 | 576 | ||
670 | case TIMESTRETCH_SET_FACTOR: | 577 | case TIMESTRETCH_SET_FACTOR: |
@@ -680,6 +587,35 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this, | |||
680 | (void)value; | 587 | (void)value; |
681 | } | 588 | } |
682 | 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; | ||
617 | } | ||
618 | |||
683 | /* Database entry */ | 619 | /* Database entry */ |
684 | DSP_PROC_DB_ENTRY(TIMESTRETCH, | 620 | DSP_PROC_DB_ENTRY(TIMESTRETCH, |
685 | tdspeed_configure); | 621 | tdspeed_configure); |