Use sized data types for audio data in the pcm buffer. Speed up the clipping routine.
[Rockbox.git] / firmware / sound.c
blob9cb4c28f32435aacb2bbb46a17723f8ed64b5322
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
193 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
194 static int tenthdb2reg(int db)
196 if (db < -540) /* 3 dB steps */
197 return (db + 780) / 30;
198 else /* 1.5 dB steps */
199 return (db + 660) / 15;
201 #endif
203 #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
204 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
205 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
206 || defined(HAVE_AS3514)
208 /* all values in tenth of dB MAS3507D UDA1380 */
209 int current_volume = 0; /* -780..+180 -840.. 0 */
210 int current_balance = 0; /* -960..+960 -840..+840 */
211 int current_treble = 0; /* -150..+150 0.. +60 */
212 int current_bass = 0; /* -150..+150 0..+240 */
214 static void set_prescaled_volume(void)
216 int prescale = 0;
217 int l, r;
219 /* The WM codecs listed don't have suitable prescaler functionality, so we let
220 * the prescaler stay at 0 for these unless SW tone controls are in use */
221 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
222 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751))
224 prescale = MAX(current_bass, current_treble);
225 if (prescale < 0)
226 prescale = 0; /* no need to prescale if we don't boost
227 bass or treble */
229 /* Gain up the analog volume to compensate the prescale gain reduction,
230 * but if this would push the volume over the top, reduce prescaling
231 * instead (might cause clipping). */
232 if (current_volume + prescale > VOLUME_MAX)
233 prescale = VOLUME_MAX - current_volume;
234 #endif
236 #if defined(HAVE_SW_TONE_CONTROLS)
237 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
238 #elif CONFIG_CODEC == MAS3507D
239 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
240 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8758)
241 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
242 #endif
244 if (current_volume == VOLUME_MIN)
245 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
247 l = r = current_volume + prescale;
249 if (current_balance > 0)
251 l -= current_balance;
252 if (l < VOLUME_MIN)
253 l = VOLUME_MIN;
255 if (current_balance < 0)
257 r += current_balance;
258 if (r < VOLUME_MIN)
259 r = VOLUME_MIN;
262 #if CONFIG_CODEC == MAS3507D
263 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
264 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
265 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
266 || defined(HAVE_AS3514)
267 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
268 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
269 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
270 #endif
272 #elif defined(HAVE_TLV320)
273 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
274 #endif
276 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
277 #endif /* !SIMULATOR */
279 #if CONFIG_CODEC != SWCODEC
280 int channel_configuration = SOUND_CHAN_STEREO;
281 int stereo_width = 100;
282 #endif
284 #ifndef SIMULATOR
286 #if CONFIG_CODEC != SWCODEC
287 static void set_channel_config(void)
289 /* default values: stereo */
290 unsigned long val_ll = 0x80000;
291 unsigned long val_lr = 0;
292 unsigned long val_rl = 0;
293 unsigned long val_rr = 0x80000;
295 switch(channel_configuration)
297 /* case SOUND_CHAN_STEREO unnecessary */
299 case SOUND_CHAN_MONO:
300 val_ll = 0xc0000;
301 val_lr = 0xc0000;
302 val_rl = 0xc0000;
303 val_rr = 0xc0000;
304 break;
306 case SOUND_CHAN_CUSTOM:
308 /* fixed point variables (matching MAS internal format)
309 integer part: upper 13 bits (inlcuding sign)
310 fractional part: lower 19 bits */
311 long fp_width, fp_straight, fp_cross;
313 fp_width = (stereo_width << 19) / 100;
314 if (stereo_width <= 100)
316 fp_straight = - ((1<<19) + fp_width) / 2;
317 fp_cross = fp_straight + fp_width;
319 else
321 /* straight = - (1 + width) / (2 * width) */
322 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
323 fp_cross = (1<<19) + fp_straight;
325 val_ll = val_rr = fp_straight & 0xfffff;
326 val_lr = val_rl = fp_cross & 0xfffff;
328 break;
330 case SOUND_CHAN_MONO_LEFT:
331 val_ll = 0x80000;
332 val_lr = 0x80000;
333 val_rl = 0;
334 val_rr = 0;
335 break;
337 case SOUND_CHAN_MONO_RIGHT:
338 val_ll = 0;
339 val_lr = 0;
340 val_rl = 0x80000;
341 val_rr = 0x80000;
342 break;
344 case SOUND_CHAN_KARAOKE:
345 val_ll = 0xc0000;
346 val_lr = 0x40000;
347 val_rl = 0x40000;
348 val_rr = 0xc0000;
349 break;
352 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
353 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
354 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
355 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
356 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
357 #elif CONFIG_CODEC == MAS3507D
358 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
359 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
360 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
361 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
362 #endif
365 #endif /* CONFIG_CODEC != SWCODEC */
367 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
368 unsigned long mdb_shape_shadow = 0;
369 unsigned long loudness_shadow = 0;
370 #endif
372 void sound_set_volume(int value)
374 if(!audio_is_initialized)
375 return;
376 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
377 unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8;
378 mas_codec_writereg(0x10, tmp);
379 #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
380 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
381 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
382 || defined(HAVE_AS3514)
383 current_volume = value * 10; /* tenth of dB */
384 set_prescaled_volume();
385 #elif CONFIG_CPU == PNX0101
386 int tmp = (60 - value * 4) & 0xff;
387 CODECVOL = tmp | (tmp << 8);
388 #endif
391 void sound_set_balance(int value)
393 if(!audio_is_initialized)
394 return;
395 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
396 unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8;
397 mas_codec_writereg(0x11, tmp);
398 #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 \
399 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
400 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
401 || defined(HAVE_AS3514)
402 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
403 set_prescaled_volume();
404 #elif CONFIG_CPU == PNX0101
405 /* TODO: implement for iFP */
406 (void)value;
407 #endif
410 void sound_set_bass(int value)
412 if(!audio_is_initialized)
413 return;
414 #if defined(HAVE_SW_TONE_CONTROLS)
415 current_bass = value * 10;
416 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
417 set_prescaled_volume();
418 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
419 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
420 mas_codec_writereg(0x14, tmp);
421 #elif CONFIG_CODEC == MAS3507D
422 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
423 current_bass = value * 10;
424 set_prescaled_volume();
425 #elif defined(HAVE_WM8751)
426 current_bass = value;
427 audiohw_set_bass(value);
428 set_prescaled_volume();
429 #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \
430 || defined HAVE_WM8731 || defined(HAVE_WM8721)
431 current_bass = value * 10;
432 audiohw_set_bass(value);
433 set_prescaled_volume();
434 #elif CONFIG_CPU == PNX0101
435 /* TODO: implement for iFP */
436 (void)value;
437 #endif
440 void sound_set_treble(int value)
442 if(!audio_is_initialized)
443 return;
444 #if defined(HAVE_SW_TONE_CONTROLS)
445 current_treble = value * 10;
446 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
447 set_prescaled_volume();
448 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
449 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
450 mas_codec_writereg(0x15, tmp);
451 #elif CONFIG_CODEC == MAS3507D
452 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
453 current_treble = value * 10;
454 set_prescaled_volume();
455 #elif defined(HAVE_WM8751)
456 audiohw_set_treble(value);
457 current_treble = value;
458 set_prescaled_volume();
459 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \
460 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
461 audiohw_set_treble(value);
462 current_treble = value * 10;
463 set_prescaled_volume();
464 #elif CONFIG_CPU == PNX0101
465 /* TODO: implement for iFP */
466 (void)value;
467 #endif
470 void sound_set_channels(int value)
472 #if CONFIG_CODEC == SWCODEC
473 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
474 #else
475 if(!audio_is_initialized)
476 return;
477 channel_configuration = value;
478 set_channel_config();
479 #endif
482 void sound_set_stereo_width(int value)
484 #if CONFIG_CODEC == SWCODEC
485 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
486 #else
487 if(!audio_is_initialized)
488 return;
489 stereo_width = value;
490 if (channel_configuration == SOUND_CHAN_CUSTOM)
491 set_channel_config();
492 #endif
495 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
496 void sound_set_loudness(int value)
498 if(!audio_is_initialized)
499 return;
500 loudness_shadow = (loudness_shadow & 0x04) |
501 (MAX(MIN(value * 4, 0x44), 0) << 8);
502 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
505 void sound_set_avc(int value)
507 if(!audio_is_initialized)
508 return;
509 int tmp;
510 switch (value) {
511 case 1: /* 20ms */
512 tmp = (0x1 << 8) | (0x8 << 12);
513 break;
514 case 2: /* 2s */
515 tmp = (0x2 << 8) | (0x8 << 12);
516 break;
517 case 3: /* 4s */
518 tmp = (0x4 << 8) | (0x8 << 12);
519 break;
520 case 4: /* 8s */
521 tmp = (0x8 << 8) | (0x8 << 12);
522 break;
523 case -1: /* turn off and then turn on again to decay quickly */
524 tmp = mas_codec_readreg(MAS_REG_KAVC);
525 mas_codec_writereg(MAS_REG_KAVC, 0);
526 break;
527 default: /* off */
528 tmp = 0;
529 break;
531 mas_codec_writereg(MAS_REG_KAVC, tmp);
534 void sound_set_mdb_strength(int value)
536 if(!audio_is_initialized)
537 return;
538 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
541 void sound_set_mdb_harmonics(int value)
543 if(!audio_is_initialized)
544 return;
545 int tmp = value * 127 / 100;
546 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
549 void sound_set_mdb_center(int value)
551 if(!audio_is_initialized)
552 return;
553 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
556 void sound_set_mdb_shape(int value)
558 if(!audio_is_initialized)
559 return;
560 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
561 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
564 void sound_set_mdb_enable(int value)
566 if(!audio_is_initialized)
567 return;
568 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
569 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
572 void sound_set_superbass(int value)
574 if(!audio_is_initialized)
575 return;
576 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
577 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
579 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
581 #else /* SIMULATOR */
582 int sim_volume;
583 void sound_set_volume(int value)
585 /* 128 is SDL_MIX_MAXVOLUME */
586 sim_volume = 128 * (value - VOLUME_MIN / 10) / (VOLUME_RANGE / 10);
589 void sound_set_balance(int value)
591 (void)value;
594 void sound_set_bass(int value)
596 (void)value;
599 void sound_set_treble(int value)
601 (void)value;
604 void sound_set_channels(int value)
606 (void)value;
609 void sound_set_stereo_width(int value)
611 (void)value;
614 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
615 void sound_set_loudness(int value)
617 (void)value;
620 void sound_set_avc(int value)
622 (void)value;
625 void sound_set_mdb_strength(int value)
627 (void)value;
630 void sound_set_mdb_harmonics(int value)
632 (void)value;
635 void sound_set_mdb_center(int value)
637 (void)value;
640 void sound_set_mdb_shape(int value)
642 (void)value;
645 void sound_set_mdb_enable(int value)
647 (void)value;
650 void sound_set_superbass(int value)
652 (void)value;
654 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
655 #endif /* SIMULATOR */
657 void sound_set(int setting, int value)
659 sound_set_type* sound_set_val = sound_get_fn(setting);
660 if (sound_set_val)
661 sound_set_val(value);
664 #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731)) || defined(SIMULATOR)
665 int sound_val2phys(int setting, int value)
667 #if CONFIG_CODEC == MAS3587F
668 int result = 0;
670 switch(setting)
672 case SOUND_LEFT_GAIN:
673 case SOUND_RIGHT_GAIN:
674 result = (value - 2) * 15;
675 break;
677 case SOUND_MIC_GAIN:
678 result = value * 15 + 210;
679 break;
681 default:
682 result = value;
683 break;
685 return result;
686 #elif defined(HAVE_UDA1380)
687 int result = 0;
689 switch(setting)
691 case SOUND_LEFT_GAIN:
692 case SOUND_RIGHT_GAIN:
693 case SOUND_MIC_GAIN:
694 result = value * 5; /* (1/2) * 10 */
695 break;
697 default:
698 result = value;
699 break;
701 return result;
702 #elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
703 int result = 0;
705 switch(setting)
707 case SOUND_LEFT_GAIN:
708 case SOUND_RIGHT_GAIN:
709 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
710 break;
712 case SOUND_MIC_GAIN:
713 result = value * 200; /* 0 or 20 dB */
714 break;
716 default:
717 result = value;
718 break;
720 return result;
721 #elif defined(HAVE_AS3514)
722 /* This is here for the sim only and the audio driver has its own */
723 int result;
725 switch(setting)
727 case SOUND_LEFT_GAIN:
728 case SOUND_RIGHT_GAIN:
729 case SOUND_MIC_GAIN:
730 result = (value - 23) * 15;
731 break;
733 default:
734 result = value;
735 break;
738 return result;
739 #else
740 (void)setting;
741 return value;
742 #endif
744 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
746 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
747 #ifndef SIMULATOR
748 /* This function works by telling the decoder that we have another
749 crystal frequency than we actually have. It will adjust its internal
750 parameters and the result is that the audio is played at another pitch.
752 The pitch value is in tenths of percent.
754 static int last_pitch = 1000;
756 void sound_set_pitch(int pitch)
758 unsigned long val;
760 if (pitch != last_pitch)
762 /* Calculate the new (bogus) frequency */
763 val = 18432 * 1000 / pitch;
765 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
767 /* We must tell the MAS that the frequency has changed.
768 * This will unfortunately cause a short silence. */
769 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
771 last_pitch = pitch;
775 int sound_get_pitch(void)
777 return last_pitch;
779 #else /* SIMULATOR */
780 void sound_set_pitch(int pitch)
782 (void)pitch;
785 int sound_get_pitch(void)
787 return 1000;
789 #endif /* SIMULATOR */
790 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */