No bufclosing of handles after track change
[Rockbox.git] / firmware / sound.c
blob37ca27b95da52097ef7492904821e149a9c2a835
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 * Copyright (C) 2007 by Christian Gmeiner
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include "config.h"
23 #include "sound.h"
24 #include "logf.h"
25 #ifndef SIMULATOR
26 #include "i2c.h"
27 #include "mas.h"
28 #if CONFIG_CPU == PNX0101
29 #include "pnx0101.h"
30 #endif
31 #include "dac.h"
32 #include "system.h"
33 #if CONFIG_CODEC == SWCODEC
34 #include "pcm.h"
35 #endif
36 #endif
38 #if CONFIG_CODEC == MAS3507D /* volume/balance/treble/bass interdependency */
39 #define VOLUME_MIN -780
40 #define VOLUME_MAX 180
41 #elif !defined(VOLUME_MIN) && !defined(VOLUME_MAX)
42 #define VOLUME_MIN -400
43 #define VOLUME_MAX 600
44 #endif
46 /* volume/balance/treble/bass interdependency main part */
47 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
49 #ifndef SIMULATOR
50 extern bool audio_is_initialized;
52 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
53 extern unsigned long shadow_io_control_main;
54 extern unsigned shadow_codec_reg0;
55 #endif
56 #endif /* SIMULATOR */
58 #ifdef SIMULATOR
59 /* dummy for sim */
60 const struct sound_settings_info audiohw_settings[] = {
61 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
62 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
63 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
64 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
65 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
66 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
67 #if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380) || defined(HAVE_TLV320)\
68 || defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731)
69 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
70 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
71 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
72 #endif
74 #endif
76 const char *sound_unit(int setting)
78 return audiohw_settings[setting].unit;
81 int sound_numdecimals(int setting)
83 return audiohw_settings[setting].numdecimals;
86 int sound_steps(int setting)
88 return audiohw_settings[setting].steps;
91 int sound_min(int setting)
93 return audiohw_settings[setting].minval;
96 int sound_max(int setting)
98 return audiohw_settings[setting].maxval;
101 int sound_default(int setting)
103 return audiohw_settings[setting].defaultval;
106 sound_set_type* sound_get_fn(int setting)
108 sound_set_type* result = NULL;
110 switch (setting) {
111 case SOUND_VOLUME:
112 result = sound_set_volume;
113 break;
115 case SOUND_BASS:
116 result = sound_set_bass;
117 break;
119 case SOUND_TREBLE:
120 result = sound_set_treble;
121 break;
123 case SOUND_BALANCE:
124 result = sound_set_balance;
125 break;
127 case SOUND_CHANNELS:
128 result = sound_set_channels;
129 break;
131 case SOUND_STEREO_WIDTH:
132 result = sound_set_stereo_width;
133 break;
135 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
136 case SOUND_LOUDNESS:
137 result = sound_set_loudness;
138 break;
140 case SOUND_AVC:
141 result = sound_set_avc;
142 break;
144 case SOUND_MDB_STRENGTH:
145 result = sound_set_mdb_strength;
146 break;
148 case SOUND_MDB_HARMONICS:
149 result = sound_set_mdb_harmonics;
150 break;
152 case SOUND_MDB_CENTER:
153 result = sound_set_mdb_center;
154 break;
156 case SOUND_MDB_SHAPE:
157 result = sound_set_mdb_shape;
158 break;
160 case SOUND_MDB_ENABLE:
161 result = sound_set_mdb_enable;
162 break;
164 case SOUND_SUPERBASS:
165 result = sound_set_superbass;
166 break;
167 #endif
170 return result;
173 #if CONFIG_CODEC == SWCODEC
174 /* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
175 enum {
176 DSP_CALLBACK_SET_PRESCALE = 0,
177 DSP_CALLBACK_SET_BASS,
178 DSP_CALLBACK_SET_TREBLE,
179 DSP_CALLBACK_SET_CHANNEL_CONFIG,
180 DSP_CALLBACK_SET_STEREO_WIDTH
183 static int (*dsp_callback)(int, intptr_t) = NULL;
185 void sound_set_dsp_callback(int (*func)(int, intptr_t))
187 dsp_callback = func;
189 #endif
191 #ifndef SIMULATOR
192 #if CONFIG_CODEC == MAS3507D /* volume/balance/treble/bass interdependency */
194 static const unsigned int bass_table[] =
196 0x9e400, /* -15dB */
197 0xa2800, /* -14dB */
198 0xa7400, /* -13dB */
199 0xac400, /* -12dB */
200 0xb1800, /* -11dB */
201 0xb7400, /* -10dB */
202 0xbd400, /* -9dB */
203 0xc3c00, /* -8dB */
204 0xca400, /* -7dB */
205 0xd1800, /* -6dB */
206 0xd8c00, /* -5dB */
207 0xe0400, /* -4dB */
208 0xe8000, /* -3dB */
209 0xefc00, /* -2dB */
210 0xf7c00, /* -1dB */
212 0x800, /* 1dB */
213 0x10000, /* 2dB */
214 0x17c00, /* 3dB */
215 0x1f800, /* 4dB */
216 0x27000, /* 5dB */
217 0x2e400, /* 6dB */
218 0x35800, /* 7dB */
219 0x3c000, /* 8dB */
220 0x42800, /* 9dB */
221 0x48800, /* 10dB */
222 0x4e400, /* 11dB */
223 0x53800, /* 12dB */
224 0x58800, /* 13dB */
225 0x5d400, /* 14dB */
226 0x61800 /* 15dB */
229 static const unsigned int treble_table[] =
231 0xb2c00, /* -15dB */
232 0xbb400, /* -14dB */
233 0xc1800, /* -13dB */
234 0xc6c00, /* -12dB */
235 0xcbc00, /* -11dB */
236 0xd0400, /* -10dB */
237 0xd5000, /* -9dB */
238 0xd9800, /* -8dB */
239 0xde000, /* -7dB */
240 0xe2800, /* -6dB */
241 0xe7e00, /* -5dB */
242 0xec000, /* -4dB */
243 0xf0c00, /* -3dB */
244 0xf5c00, /* -2dB */
245 0xfac00, /* -1dB */
247 0x5400, /* 1dB */
248 0xac00, /* 2dB */
249 0x10400, /* 3dB */
250 0x16000, /* 4dB */
251 0x1c000, /* 5dB */
252 0x22400, /* 6dB */
253 0x28400, /* 7dB */
254 0x2ec00, /* 8dB */
255 0x35400, /* 9dB */
256 0x3c000, /* 10dB */
257 0x42c00, /* 11dB */
258 0x49c00, /* 12dB */
259 0x51800, /* 13dB */
260 0x58400, /* 14dB */
261 0x5f800 /* 15dB */
264 static const unsigned int prescale_table[] =
266 0x80000, /* 0db */
267 0x8e000, /* 1dB */
268 0x9a400, /* 2dB */
269 0xa5800, /* 3dB */
270 0xaf400, /* 4dB */
271 0xb8000, /* 5dB */
272 0xbfc00, /* 6dB */
273 0xc6c00, /* 7dB */
274 0xcd000, /* 8dB */
275 0xd25c0, /* 9dB */
276 0xd7800, /* 10dB */
277 0xdc000, /* 11dB */
278 0xdfc00, /* 12dB */
279 0xe3400, /* 13dB */
280 0xe6800, /* 14dB */
281 0xe9400 /* 15dB */
284 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
285 static int tenthdb2reg(int db)
287 if (db < -540) /* 3 dB steps */
288 return (db + 780) / 30;
289 else /* 1.5 dB steps */
290 return (db + 660) / 15;
292 #endif
294 #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
295 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
296 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
297 || defined(HAVE_AS3514)
299 /* all values in tenth of dB MAS3507D UDA1380 */
300 int current_volume = 0; /* -780..+180 -840.. 0 */
301 int current_balance = 0; /* -960..+960 -840..+840 */
302 int current_treble = 0; /* -150..+150 0.. +60 */
303 int current_bass = 0; /* -150..+150 0..+240 */
305 static void set_prescaled_volume(void)
307 int prescale = 0;
308 int l, r;
310 /* The WM codecs listed don't have suitable prescaler functionality, so we let
311 * the prescaler stay at 0 for these unless SW tone controls are in use */
312 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
313 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751))
315 prescale = MAX(current_bass, current_treble);
316 if (prescale < 0)
317 prescale = 0; /* no need to prescale if we don't boost
318 bass or treble */
320 /* Gain up the analog volume to compensate the prescale gain reduction,
321 * but if this would push the volume over the top, reduce prescaling
322 * instead (might cause clipping). */
323 if (current_volume + prescale > VOLUME_MAX)
324 prescale = VOLUME_MAX - current_volume;
325 #endif
327 #if defined(HAVE_SW_TONE_CONTROLS)
328 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
329 #elif CONFIG_CODEC == MAS3507D
330 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
331 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8758)
332 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
333 #endif
335 if (current_volume == VOLUME_MIN)
336 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
338 l = r = current_volume + prescale;
340 if (current_balance > 0)
342 l -= current_balance;
343 if (l < VOLUME_MIN)
344 l = VOLUME_MIN;
346 if (current_balance < 0)
348 r += current_balance;
349 if (r < VOLUME_MIN)
350 r = VOLUME_MIN;
353 #if CONFIG_CODEC == MAS3507D
354 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
355 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
356 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
357 || defined(HAVE_AS3514)
358 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
359 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
360 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
361 #endif
363 #elif defined(HAVE_TLV320)
364 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
365 #endif
367 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
368 #endif /* !SIMULATOR */
370 #if CONFIG_CODEC != SWCODEC
371 int channel_configuration = SOUND_CHAN_STEREO;
372 int stereo_width = 100;
373 #endif
375 #ifndef SIMULATOR
377 #if CONFIG_CODEC != SWCODEC
378 static void set_channel_config(void)
380 /* default values: stereo */
381 unsigned long val_ll = 0x80000;
382 unsigned long val_lr = 0;
383 unsigned long val_rl = 0;
384 unsigned long val_rr = 0x80000;
386 switch(channel_configuration)
388 /* case SOUND_CHAN_STEREO unnecessary */
390 case SOUND_CHAN_MONO:
391 val_ll = 0xc0000;
392 val_lr = 0xc0000;
393 val_rl = 0xc0000;
394 val_rr = 0xc0000;
395 break;
397 case SOUND_CHAN_CUSTOM:
399 /* fixed point variables (matching MAS internal format)
400 integer part: upper 13 bits (inlcuding sign)
401 fractional part: lower 19 bits */
402 long fp_width, fp_straight, fp_cross;
404 fp_width = (stereo_width << 19) / 100;
405 if (stereo_width <= 100)
407 fp_straight = - ((1<<19) + fp_width) / 2;
408 fp_cross = fp_straight + fp_width;
410 else
412 /* straight = - (1 + width) / (2 * width) */
413 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
414 fp_cross = (1<<19) + fp_straight;
416 val_ll = val_rr = fp_straight & 0xfffff;
417 val_lr = val_rl = fp_cross & 0xfffff;
419 break;
421 case SOUND_CHAN_MONO_LEFT:
422 val_ll = 0x80000;
423 val_lr = 0x80000;
424 val_rl = 0;
425 val_rr = 0;
426 break;
428 case SOUND_CHAN_MONO_RIGHT:
429 val_ll = 0;
430 val_lr = 0;
431 val_rl = 0x80000;
432 val_rr = 0x80000;
433 break;
435 case SOUND_CHAN_KARAOKE:
436 val_ll = 0xc0000;
437 val_lr = 0x40000;
438 val_rl = 0x40000;
439 val_rr = 0xc0000;
440 break;
443 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
444 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
445 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
446 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
447 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
448 #elif CONFIG_CODEC == MAS3507D
449 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
450 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
451 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
452 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
453 #endif
456 #endif /* CONFIG_CODEC != SWCODEC */
458 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
459 unsigned long mdb_shape_shadow = 0;
460 unsigned long loudness_shadow = 0;
461 #endif
463 void sound_set_volume(int value)
465 if(!audio_is_initialized)
466 return;
467 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
468 unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8;
469 mas_codec_writereg(0x10, tmp);
470 #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
471 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
472 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
473 || defined(HAVE_AS3514)
474 current_volume = value * 10; /* tenth of dB */
475 set_prescaled_volume();
476 #elif CONFIG_CPU == PNX0101
477 int tmp = (60 - value * 4) & 0xff;
478 CODECVOL = tmp | (tmp << 8);
479 #endif
482 void sound_set_balance(int value)
484 if(!audio_is_initialized)
485 return;
486 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
487 unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8;
488 mas_codec_writereg(0x11, tmp);
489 #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 \
490 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
491 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
492 || defined(HAVE_AS3514)
493 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
494 set_prescaled_volume();
495 #elif CONFIG_CPU == PNX0101
496 /* TODO: implement for iFP */
497 (void)value;
498 #endif
501 void sound_set_bass(int value)
503 if(!audio_is_initialized)
504 return;
505 #if defined(HAVE_SW_TONE_CONTROLS)
506 current_bass = value * 10;
507 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
508 set_prescaled_volume();
509 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
510 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
511 mas_codec_writereg(0x14, tmp);
512 #elif CONFIG_CODEC == MAS3507D
513 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
514 current_bass = value * 10;
515 set_prescaled_volume();
516 #elif defined(HAVE_WM8751)
517 current_bass = value;
518 audiohw_set_bass(value);
519 set_prescaled_volume();
520 #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \
521 || defined HAVE_WM8731 || defined(HAVE_WM8721)
522 current_bass = value * 10;
523 audiohw_set_bass(value);
524 set_prescaled_volume();
525 #elif CONFIG_CPU == PNX0101
526 /* TODO: implement for iFP */
527 (void)value;
528 #endif
531 void sound_set_treble(int value)
533 if(!audio_is_initialized)
534 return;
535 #if defined(HAVE_SW_TONE_CONTROLS)
536 current_treble = value * 10;
537 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
538 set_prescaled_volume();
539 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
540 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
541 mas_codec_writereg(0x15, tmp);
542 #elif CONFIG_CODEC == MAS3507D
543 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
544 current_treble = value * 10;
545 set_prescaled_volume();
546 #elif defined(HAVE_WM8751)
547 audiohw_set_treble(value);
548 current_treble = value;
549 set_prescaled_volume();
550 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \
551 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
552 audiohw_set_treble(value);
553 current_treble = value * 10;
554 set_prescaled_volume();
555 #elif CONFIG_CPU == PNX0101
556 /* TODO: implement for iFP */
557 (void)value;
558 #endif
561 void sound_set_channels(int value)
563 #if CONFIG_CODEC == SWCODEC
564 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
565 #else
566 if(!audio_is_initialized)
567 return;
568 channel_configuration = value;
569 set_channel_config();
570 #endif
573 void sound_set_stereo_width(int value)
575 #if CONFIG_CODEC == SWCODEC
576 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
577 #else
578 if(!audio_is_initialized)
579 return;
580 stereo_width = value;
581 if (channel_configuration == SOUND_CHAN_CUSTOM)
582 set_channel_config();
583 #endif
586 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
587 void sound_set_loudness(int value)
589 if(!audio_is_initialized)
590 return;
591 loudness_shadow = (loudness_shadow & 0x04) |
592 (MAX(MIN(value * 4, 0x44), 0) << 8);
593 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
596 void sound_set_avc(int value)
598 if(!audio_is_initialized)
599 return;
600 int tmp;
601 switch (value) {
602 case 1: /* 20ms */
603 tmp = (0x1 << 8) | (0x8 << 12);
604 break;
605 case 2: /* 2s */
606 tmp = (0x2 << 8) | (0x8 << 12);
607 break;
608 case 3: /* 4s */
609 tmp = (0x4 << 8) | (0x8 << 12);
610 break;
611 case 4: /* 8s */
612 tmp = (0x8 << 8) | (0x8 << 12);
613 break;
614 case -1: /* turn off and then turn on again to decay quickly */
615 tmp = mas_codec_readreg(MAS_REG_KAVC);
616 mas_codec_writereg(MAS_REG_KAVC, 0);
617 break;
618 default: /* off */
619 tmp = 0;
620 break;
622 mas_codec_writereg(MAS_REG_KAVC, tmp);
625 void sound_set_mdb_strength(int value)
627 if(!audio_is_initialized)
628 return;
629 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
632 void sound_set_mdb_harmonics(int value)
634 if(!audio_is_initialized)
635 return;
636 int tmp = value * 127 / 100;
637 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
640 void sound_set_mdb_center(int value)
642 if(!audio_is_initialized)
643 return;
644 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
647 void sound_set_mdb_shape(int value)
649 if(!audio_is_initialized)
650 return;
651 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
652 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
655 void sound_set_mdb_enable(int value)
657 if(!audio_is_initialized)
658 return;
659 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
660 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
663 void sound_set_superbass(int value)
665 if(!audio_is_initialized)
666 return;
667 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
668 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
670 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
672 #else /* SIMULATOR */
673 int sim_volume;
674 void sound_set_volume(int value)
676 /* 128 is SDL_MIX_MAXVOLUME */
677 sim_volume = 128 * (value - VOLUME_MIN / 10) / (VOLUME_RANGE / 10);
680 void sound_set_balance(int value)
682 (void)value;
685 void sound_set_bass(int value)
687 (void)value;
690 void sound_set_treble(int value)
692 (void)value;
695 void sound_set_channels(int value)
697 (void)value;
700 void sound_set_stereo_width(int value)
702 (void)value;
705 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
706 void sound_set_loudness(int value)
708 (void)value;
711 void sound_set_avc(int value)
713 (void)value;
716 void sound_set_mdb_strength(int value)
718 (void)value;
721 void sound_set_mdb_harmonics(int value)
723 (void)value;
726 void sound_set_mdb_center(int value)
728 (void)value;
731 void sound_set_mdb_shape(int value)
733 (void)value;
736 void sound_set_mdb_enable(int value)
738 (void)value;
741 void sound_set_superbass(int value)
743 (void)value;
745 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
746 #endif /* SIMULATOR */
748 void sound_set(int setting, int value)
750 sound_set_type* sound_set_val = sound_get_fn(setting);
751 if (sound_set_val)
752 sound_set_val(value);
755 #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731)) || defined(SIMULATOR)
756 int sound_val2phys(int setting, int value)
758 #if CONFIG_CODEC == MAS3587F
759 int result = 0;
761 switch(setting)
763 case SOUND_LEFT_GAIN:
764 case SOUND_RIGHT_GAIN:
765 result = (value - 2) * 15;
766 break;
768 case SOUND_MIC_GAIN:
769 result = value * 15 + 210;
770 break;
772 default:
773 result = value;
774 break;
776 return result;
777 #elif defined(HAVE_UDA1380)
778 int result = 0;
780 switch(setting)
782 case SOUND_LEFT_GAIN:
783 case SOUND_RIGHT_GAIN:
784 case SOUND_MIC_GAIN:
785 result = value * 5; /* (1/2) * 10 */
786 break;
788 default:
789 result = value;
790 break;
792 return result;
793 #elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
794 int result = 0;
796 switch(setting)
798 case SOUND_LEFT_GAIN:
799 case SOUND_RIGHT_GAIN:
800 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
801 break;
803 case SOUND_MIC_GAIN:
804 result = value * 200; /* 0 or 20 dB */
805 break;
807 default:
808 result = value;
809 break;
811 return result;
812 #elif defined(HAVE_AS3514)
813 /* This is here for the sim only and the audio driver has its own */
814 int result;
816 switch(setting)
818 case SOUND_LEFT_GAIN:
819 case SOUND_RIGHT_GAIN:
820 case SOUND_MIC_GAIN:
821 result = (value - 23) * 15;
822 break;
824 default:
825 result = value;
826 break;
829 return result;
830 #else
831 (void)setting;
832 return value;
833 #endif
835 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
837 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
838 #ifndef SIMULATOR
839 /* This function works by telling the decoder that we have another
840 crystal frequency than we actually have. It will adjust its internal
841 parameters and the result is that the audio is played at another pitch.
843 The pitch value is in tenths of percent.
845 static int last_pitch = 1000;
847 void sound_set_pitch(int pitch)
849 unsigned long val;
851 if (pitch != last_pitch)
853 /* Calculate the new (bogus) frequency */
854 val = 18432 * 1000 / pitch;
856 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
858 /* We must tell the MAS that the frequency has changed.
859 * This will unfortunately cause a short silence. */
860 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
862 last_pitch = pitch;
866 int sound_get_pitch(void)
868 return last_pitch;
870 #else /* SIMULATOR */
871 void sound_set_pitch(int pitch)
873 (void)pitch;
876 int sound_get_pitch(void)
878 return 1000;
880 #endif /* SIMULATOR */
881 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */