summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/surround.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-10-12 03:12:58 -0400
committerMichael Sevakis <jethead71@rockbox.org>2017-10-12 04:44:55 -0400
commit5eee28e37d78e0679fc5aa8488e5408429153e4c (patch)
tree8b5593c140fcab4d7a40fc1b9c295a412234048e /lib/rbcodec/dsp/surround.c
parentafbae177a16fafbd898925e874fc56d395756d3a (diff)
downloadrockbox-5eee28e37d78e0679fc5aa8488e5408429153e4c.tar.gz
rockbox-5eee28e37d78e0679fc5aa8488e5408429153e4c.zip
Nitpick configuration code in a few DSP filters to fix some bugs
Most importantly is surround shouldn't operate in mono mode. Have it watch and (de)activate itself on relevant format changes as it should. Other changes to better handle buffer allocation failure. PBE was set internally at 100 by default; SBZ. Change-Id: I328e0b674e56751a255eae817d7892d685796b06
Diffstat (limited to 'lib/rbcodec/dsp/surround.c')
-rw-r--r--lib/rbcodec/dsp/surround.c128
1 files changed, 86 insertions, 42 deletions
diff --git a/lib/rbcodec/dsp/surround.c b/lib/rbcodec/dsp/surround.c
index b2995de49f..f3349b34e5 100644
--- a/lib/rbcodec/dsp/surround.c
+++ b/lib/rbcodec/dsp/surround.c
@@ -27,7 +27,6 @@
27#include "dsp_filter.h" 27#include "dsp_filter.h"
28#include "core_alloc.h" 28#include "core_alloc.h"
29 29
30static bool surround_enabled = false;
31static int surround_balance = 0; 30static int surround_balance = 0;
32static bool surround_side_only = false; 31static bool surround_side_only = false;
33static int surround_mix = 100; 32static int surround_mix = 100;
@@ -64,26 +63,25 @@ static int b0_r=0,b0_w=0,
64 cl_r=0,cl_w=0; 63 cl_r=0,cl_w=0;
65static int handle = -1; 64static int handle = -1;
66 65
67static void surround_buffer_alloc(void) 66#define SURROUND_BUFSIZE ((B0_DLY + B2_DLY + BB_DLY + HH_DLY + CL_DLY)*sizeof (int32_t))
68{
69 if (handle > 0)
70 return; /* already-allocated */
71 67
72 unsigned int total_len = B0_DLY + B2_DLY + BB_DLY + HH_DLY + CL_DLY; 68static int surround_buffer_alloc(void)
73 handle = core_alloc("dsp_surround_buffer",sizeof(int32_t) * total_len); 69{
70 handle = core_alloc("dsp_surround_buffer", SURROUND_BUFSIZE);
71 return handle;
72}
74 73
74static void surround_buffer_free(void)
75{
75 if (handle < 0) 76 if (handle < 0)
76 {
77 surround_enabled = false;
78 return; 77 return;
79 } 78
80 memset(core_get_data(handle),0,sizeof(int32_t) * total_len); 79 core_free(handle);
80 handle = -1;
81} 81}
82 82
83static void surround_buffer_get_data(void) 83static void surround_buffer_get_data(void)
84{ 84{
85 if (handle < 0)
86 return;
87 b0 = core_get_data(handle); 85 b0 = core_get_data(handle);
88 b2 = b0 + B0_DLY; 86 b2 = b0 + B0_DLY;
89 bb = b2 + B2_DLY; 87 bb = b2 + B2_DLY;
@@ -93,12 +91,7 @@ static void surround_buffer_get_data(void)
93 91
94static void dsp_surround_flush(void) 92static void dsp_surround_flush(void)
95{ 93{
96 if (!surround_enabled) 94 memset(core_get_data(handle), 0, SURROUND_BUFSIZE);
97 return;
98
99 unsigned int total_len = B0_DLY + B2_DLY + BB_DLY + HH_DLY + CL_DLY;
100 if (handle > 0)
101 memset(core_get_data(handle),0,sizeof(int32_t) * total_len);
102} 95}
103 96
104static void surround_update_filter(unsigned int fout) 97static void surround_update_filter(unsigned int fout)
@@ -116,8 +109,16 @@ void dsp_surround_set_balance(int var)
116 109
117void dsp_surround_side_only(bool var) 110void dsp_surround_side_only(bool var)
118{ 111{
119 dsp_surround_flush(); 112 if (var == surround_side_only)
113 return; /* No setting change */
114
120 surround_side_only = var; 115 surround_side_only = var;
116
117 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
118 if (!dsp_proc_enabled(dsp, DSP_PROC_SURROUND))
119 return;
120
121 dsp_surround_flush();
121} 122}
122 123
123void dsp_surround_mix(int var) 124void dsp_surround_mix(int var)
@@ -127,12 +128,17 @@ void dsp_surround_mix(int var)
127 128
128void dsp_surround_set_cutoff(int frq_l, int frq_h) 129void dsp_surround_set_cutoff(int frq_l, int frq_h)
129{ 130{
131 if (cutoff_l == frq_l && cutoff_h == frq_h)
132 return; /* No settings change */
133
130 cutoff_l = frq_l;/*fx2*/ 134 cutoff_l = frq_l;/*fx2*/
131 cutoff_h = frq_h;/*fx1*/ 135 cutoff_h = frq_h;/*fx1*/
132 136
133 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); 137 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
134 unsigned int fout = dsp_get_output_frequency(dsp); 138 if (!dsp_proc_enabled(dsp, DSP_PROC_SURROUND))
135 surround_update_filter(fout); 139 return;
140
141 surround_update_filter(dsp_get_output_frequency(dsp));
136} 142}
137 143
138static void surround_set_stepsize(int surround_strength) 144static void surround_set_stepsize(int surround_strength)
@@ -163,23 +169,21 @@ void dsp_surround_enable(int var)
163 if (var == surround_strength) 169 if (var == surround_strength)
164 return; /* No setting change */ 170 return; /* No setting change */
165 171
166 bool was_enabled = surround_strength > 0;
167 surround_strength = var; 172 surround_strength = var;
168 surround_set_stepsize(surround_strength);
169 173
174 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
175 bool was_enabled = dsp_proc_enabled(dsp, DSP_PROC_SURROUND);
170 bool now_enabled = var > 0; 176 bool now_enabled = var > 0;
171 177
172 if (was_enabled == now_enabled && !now_enabled) 178 if (was_enabled == now_enabled && !now_enabled)
173 return; /* No change in enabled status */ 179 return; /* No change in enabled status */
174 180
175 if (now_enabled == false && handle > 0) 181 if (now_enabled)
176 { 182 surround_set_stepsize(var);
177 core_free(handle);
178 handle = -1;
179 }
180 surround_enabled = now_enabled;
181 183
182 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); 184 /* If changing status, enable or disable it; if already enabled push
185 additional DSP_PROC_INIT messages with value = 1 to force-update the
186 filters */
183 dsp_proc_enable(dsp, DSP_PROC_SURROUND, now_enabled); 187 dsp_proc_enable(dsp, DSP_PROC_SURROUND, now_enabled);
184} 188}
185 189
@@ -284,42 +288,82 @@ static void surround_process(struct dsp_proc_entry *this,
284 (void)this; 288 (void)this;
285} 289}
286 290
291/* Handle format changes and verify the format compatibility */
292static intptr_t surround_new_format(struct dsp_proc_entry *this,
293 struct dsp_config *dsp,
294 struct sample_format *format)
295{
296 DSP_PRINT_FORMAT(DSP_PROC_SURROUND, *format);
297
298 /* Stereo mode only */
299 bool was_active = dsp_proc_active(dsp, DSP_PROC_SURROUND);
300 bool now_active = format->num_channels > 1;
301 dsp_proc_activate(dsp, DSP_PROC_SURROUND, now_active);
302
303 if (now_active)
304 {
305 if (!was_active)
306 dsp_surround_flush(); /* Going online */
307
308 return PROC_NEW_FORMAT_OK;
309 }
310
311 /* Can't do this. Sleep until next change. */
312 DEBUGF(" DSP_PROC_SURROUND- deactivated\n");
313 return PROC_NEW_FORMAT_DEACTIVATED;
314
315 (void)this;
316}
317
287/* DSP message hook */ 318/* DSP message hook */
288static intptr_t surround_configure(struct dsp_proc_entry *this, 319static intptr_t surround_configure(struct dsp_proc_entry *this,
289 struct dsp_config *dsp, 320 struct dsp_config *dsp,
290 unsigned int setting, 321 unsigned int setting,
291 intptr_t value) 322 intptr_t value)
292{ 323{
293 unsigned int fout = dsp_get_output_frequency(dsp); 324 intptr_t retval = 0;
325
294 switch (setting) 326 switch (setting)
295 { 327 {
296 case DSP_PROC_INIT: 328 case DSP_PROC_INIT:
297 if (value == 0) 329 if (value == 0)
298 { 330 {
331 retval = surround_buffer_alloc();
332 if (retval < 0)
333 break;
334
299 this->process = surround_process; 335 this->process = surround_process;
300 surround_buffer_alloc();
301 dsp_surround_flush();
302 dsp_proc_activate(dsp, DSP_PROC_SURROUND, true);
303 } 336 }
304 else 337 /* else additional forced messages */
305 surround_update_filter(fout); 338
339 surround_update_filter(dsp_get_output_frequency(dsp));
306 break; 340 break;
341
342 case DSP_PROC_CLOSE:
343 /* Being disabled (called also if init fails) */
344 surround_buffer_free();
345 break;
346
307 case DSP_FLUSH: 347 case DSP_FLUSH:
348 /* Discontinuity; clear filters */
308 dsp_surround_flush(); 349 dsp_surround_flush();
309 break; 350 break;
310 case DSP_SET_OUT_FREQUENCY: 351
352 case DSP_SET_OUT_FREQUENCY:
353 /* New output frequency */
311 surround_update_filter(value); 354 surround_update_filter(value);
312 break; 355 break;
313 case DSP_PROC_CLOSE: 356
357 case DSP_PROC_NEW_FORMAT:
358 /* Source buffer format is changing (also sent when first enabled) */
359 retval = surround_new_format(this, dsp, (struct sample_format *)value);
314 break; 360 break;
315 } 361 }
316 362
317 return 1; 363 return retval;
318 (void)dsp;
319} 364}
320 365
321/* Database entry */ 366/* Database entry */
322DSP_PROC_DB_ENTRY( 367DSP_PROC_DB_ENTRY(
323 SURROUND, 368 SURROUND,
324 surround_configure); 369 surround_configure);
325