diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-06-19 23:33:23 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-06-19 23:33:23 +0000 |
commit | 12a0e221de7ae39b221f38fe5cd8165440a79d2e (patch) | |
tree | 1bf2f60f5c212c30d28778887ff4294d8d51ce61 /firmware/sound.c | |
parent | 2c28390972fd55e61e34055e2c412c03ea981371 (diff) | |
download | rockbox-12a0e221de7ae39b221f38fe5cd8165440a79d2e.tar.gz rockbox-12a0e221de7ae39b221f38fe5cd8165440a79d2e.zip |
iriver: Prescale the digital volume when boosting treble/bass by decreasing the mixer volume.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6770 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/sound.c')
-rw-r--r-- | firmware/sound.c | 128 |
1 files changed, 60 insertions, 68 deletions
diff --git a/firmware/sound.c b/firmware/sound.c index 51244f90ac..9cac7cbd02 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -229,7 +229,10 @@ int sound_default(int setting) | |||
229 | } | 229 | } |
230 | 230 | ||
231 | #ifndef SIMULATOR | 231 | #ifndef SIMULATOR |
232 | #if CONFIG_HWCODEC == MAS3507D | 232 | #if CONFIG_HWCODEC == MAS3507D /* volume/balance/treble/bass interdependency */ |
233 | #define VOLUME_MIN -780 | ||
234 | #define VOLUME_MAX 180 | ||
235 | |||
233 | static const unsigned int bass_table[] = | 236 | static const unsigned int bass_table[] = |
234 | { | 237 | { |
235 | 0x9e400, /* -15dB */ | 238 | 0x9e400, /* -15dB */ |
@@ -320,61 +323,21 @@ static const unsigned int prescale_table[] = | |||
320 | 0xe9400 /* 15dB */ | 323 | 0xe9400 /* 15dB */ |
321 | }; | 324 | }; |
322 | 325 | ||
323 | /* all values in tenth of dB */ | 326 | /* convert tenth of dB volume to dac3550 register value */ |
324 | int current_volume = 0; /* -780..+180 */ | ||
325 | int current_balance = 0; /* -960..+960 */ | ||
326 | int current_treble = 0; /* -150..+150 */ | ||
327 | int current_bass = 0; /* -150..+150 */ | ||
328 | |||
329 | /* convert tenth of dB volume to register value */ | ||
330 | static int tenthdb2reg(int db) { | 327 | static int tenthdb2reg(int db) { |
331 | if (db < -540) | 328 | if (db < -540) |
332 | return (db + 780) / 30; | 329 | return (db + 780) / 30; |
333 | else | 330 | else |
334 | return (db + 660) / 15; | 331 | return (db + 660) / 15; |
335 | } | 332 | } |
333 | #endif | ||
336 | 334 | ||
337 | static void set_prescaled_volume(void) | 335 | #ifdef HAVE_UDA1380 /* volume/balance/treble/bass interdependency */ |
338 | { | 336 | #define VOLUME_MIN -840 |
339 | int prescale; | 337 | #define VOLUME_MAX 0 |
340 | int l, r; | ||
341 | |||
342 | prescale = MAX(current_bass, current_treble); | ||
343 | if (prescale < 0) | ||
344 | prescale = 0; /* no need to prescale if we don't boost | ||
345 | bass or treble */ | ||
346 | |||
347 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
348 | |||
349 | /* gain up the analog volume to compensate the prescale reduction gain, | ||
350 | * but limit to +18 dB (the maximum the DAC can do */ | ||
351 | if (current_volume + prescale > 180) | ||
352 | prescale = 180 - current_volume; | ||
353 | l = r = current_volume + prescale; | ||
354 | |||
355 | if (current_balance > 0) | ||
356 | { | ||
357 | l -= current_balance; | ||
358 | if (l < -780) | ||
359 | l = -780; | ||
360 | } | ||
361 | if (current_balance < 0) | ||
362 | { | ||
363 | r += current_balance; | ||
364 | if (r < -780) | ||
365 | r = -780; | ||
366 | } | ||
367 | |||
368 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
369 | } | ||
370 | #elif CONFIG_HWCODEC == MASNONE | ||
371 | #ifdef HAVE_UDA1380 /* iriver H1x0 + H3x0 */ | ||
372 | /* all values in tenth of dB */ | ||
373 | int current_volume = 0; /* -840..0 */ | ||
374 | int current_balance = 0; /* -840..+840 */ | ||
375 | 338 | ||
376 | /* convert tenth of dB volume to register value */ | 339 | /* convert tenth of dB volume to master volume register value */ |
377 | static int tenthdb2reg(int db) { | 340 | static int tenthdb2master(int db) { |
378 | if (db < -720) /* 1.5 dB steps */ | 341 | if (db < -720) /* 1.5 dB steps */ |
379 | return (2940 - db) / 15; | 342 | return (2940 - db) / 15; |
380 | else if (db < -660) /* 0.75 dB steps */ | 343 | else if (db < -660) /* 0.75 dB steps */ |
@@ -384,30 +347,61 @@ static int tenthdb2reg(int db) { | |||
384 | else /* 0.25 dB steps */ | 347 | else /* 0.25 dB steps */ |
385 | return -db * 2 / 5; | 348 | return -db * 2 / 5; |
386 | } | 349 | } |
350 | #endif | ||
351 | |||
352 | #if (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 | ||
353 | /* volume/balance/treble/bass interdependency main part */ | ||
354 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) | ||
355 | |||
356 | /* all values in tenth of dB MAS3507D UDA1380 */ | ||
357 | int current_volume = 0; /* -780..+180 -840.. 0 */ | ||
358 | int current_balance = 0; /* -960..+960 -840..+840 */ | ||
359 | int current_treble = 0; /* -150..+150 0.. +60 */ | ||
360 | int current_bass = 0; /* -150..+150 0..+240 */ | ||
387 | 361 | ||
388 | static void set_volume(void) | 362 | static void set_prescaled_volume(void) |
389 | { | 363 | { |
364 | int prescale; | ||
390 | int l, r; | 365 | int l, r; |
391 | 366 | ||
392 | l = r = current_volume; | 367 | prescale = MAX(current_bass, current_treble); |
368 | if (prescale < 0) | ||
369 | prescale = 0; /* no need to prescale if we don't boost | ||
370 | bass or treble */ | ||
371 | |||
372 | #if CONFIG_HWCODEC == MAS3507D | ||
373 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
374 | #else /* UDA1380 */ | ||
375 | uda1380_set_mixer_vol(prescale*2/5, prescale*2/5); | ||
376 | /* The needed range of 0..-24 dB is fortunately linear */ | ||
377 | #endif | ||
378 | |||
379 | /* gain up the analog volume to compensate the prescale gain reduction, | ||
380 | * but limit to the possible maximum */ | ||
381 | if (current_volume + prescale > VOLUME_MAX) | ||
382 | prescale = VOLUME_MAX - current_volume; | ||
383 | l = r = current_volume + prescale; | ||
393 | 384 | ||
394 | if (current_balance > 0) | 385 | if (current_balance > 0) |
395 | { | 386 | { |
396 | l -= current_balance; | 387 | l -= current_balance; |
397 | if (l < -840) | 388 | if (l < VOLUME_MIN) |
398 | l = -840; | 389 | l = VOLUME_MIN; |
399 | } | 390 | } |
400 | if (current_balance < 0) | 391 | if (current_balance < 0) |
401 | { | 392 | { |
402 | r += current_balance; | 393 | r += current_balance; |
403 | if (r < -840) | 394 | if (r < VOLUME_MIN) |
404 | r = -840; | 395 | r = VOLUME_MIN; |
405 | } | 396 | } |
406 | 397 | ||
407 | uda1380_setvol(tenthdb2reg(l), tenthdb2reg(r)); | 398 | #if CONFIG_HWCODEC == MAS3507D |
408 | } | 399 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
400 | #else /* UDA1380 */ | ||
401 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | ||
409 | #endif | 402 | #endif |
410 | #endif /* MASNONE */ | 403 | } |
404 | #endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */ | ||
411 | #endif /* !SIMULATOR */ | 405 | #endif /* !SIMULATOR */ |
412 | 406 | ||
413 | int channel_configuration = SOUND_CHAN_STEREO; | 407 | int channel_configuration = SOUND_CHAN_STEREO; |
@@ -516,12 +510,9 @@ void sound_set(int setting, int value) | |||
516 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 510 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
517 | tmp = 0x7f00 * value / 100; | 511 | tmp = 0x7f00 * value / 100; |
518 | mas_codec_writereg(0x10, tmp & 0xff00); | 512 | mas_codec_writereg(0x10, tmp & 0xff00); |
519 | #elif CONFIG_HWCODEC == MAS3507D | 513 | #elif (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 |
520 | current_volume = -780 + (value * 960 / 100); /* tenth of dB */ | 514 | current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100); |
521 | set_prescaled_volume(); | 515 | set_prescaled_volume(); /* tenth of dB */ |
522 | #elif defined(HAVE_UDA1380) | ||
523 | current_volume = -840 + (value * 840 / 100); /* tenth of dB */ | ||
524 | set_volume(); | ||
525 | #endif | 516 | #endif |
526 | break; | 517 | break; |
527 | 518 | ||
@@ -529,12 +520,9 @@ void sound_set(int setting, int value) | |||
529 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 520 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
530 | tmp = ((value * 127 / 100) & 0xff) << 8; | 521 | tmp = ((value * 127 / 100) & 0xff) << 8; |
531 | mas_codec_writereg(0x11, tmp & 0xff00); | 522 | mas_codec_writereg(0x11, tmp & 0xff00); |
532 | #elif CONFIG_HWCODEC == MAS3507D | 523 | #elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380 |
533 | current_balance = value * 960 / 100; /* tenth of dB */ | 524 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ |
534 | set_prescaled_volume(); | 525 | set_prescaled_volume(); |
535 | #elif defined(HAVE_UDA1380) | ||
536 | current_balance = value * 840 / 100; /* tenth of dB */ | ||
537 | set_volume(); | ||
538 | #endif | 526 | #endif |
539 | break; | 527 | break; |
540 | 528 | ||
@@ -548,6 +536,8 @@ void sound_set(int setting, int value) | |||
548 | set_prescaled_volume(); | 536 | set_prescaled_volume(); |
549 | #elif defined(HAVE_UDA1380) | 537 | #elif defined(HAVE_UDA1380) |
550 | uda1380_set_bass(value >> 1); | 538 | uda1380_set_bass(value >> 1); |
539 | current_bass = value * 10; | ||
540 | set_prescaled_volume(); | ||
551 | #endif | 541 | #endif |
552 | break; | 542 | break; |
553 | 543 | ||
@@ -561,6 +551,8 @@ void sound_set(int setting, int value) | |||
561 | set_prescaled_volume(); | 551 | set_prescaled_volume(); |
562 | #elif defined(HAVE_UDA1380) | 552 | #elif defined(HAVE_UDA1380) |
563 | uda1380_set_treble(value >> 1); | 553 | uda1380_set_treble(value >> 1); |
554 | current_treble = value * 10; | ||
555 | set_prescaled_volume(); | ||
564 | #endif | 556 | #endif |
565 | break; | 557 | break; |
566 | 558 | ||