summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2005-08-11 18:56:20 +0000
committerMagnus Holmgren <magnushol@gmail.com>2005-08-11 18:56:20 +0000
commit5a8eac1a5a7daa1f90af82e6d687e6c559a0d3e1 (patch)
tree34be24d921135551a46ec0c695866988f488c7c3
parenteab21c6cb56c7584290a15768e1412baed6e73a0 (diff)
downloadrockbox-5a8eac1a5a7daa1f90af82e6d687e6c559a0d3e1.tar.gz
rockbox-5a8eac1a5a7daa1f90af82e6d687e6c559a0d3e1.zip
Added pre-amp setting for files with ReplayGain information.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7303 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dsp.c31
-rw-r--r--apps/lang/english.lang12
-rw-r--r--apps/settings.c15
-rw-r--r--apps/settings.h4
-rw-r--r--apps/settings_menu.c56
-rw-r--r--apps/sound_menu.c2
-rw-r--r--firmware/export/replaygain.h1
-rw-r--r--firmware/replaygain.c12
8 files changed, 100 insertions, 33 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index 21effc5da3..701ffb4e55 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -23,13 +23,14 @@
23#include "playback.h" 23#include "playback.h"
24#include "system.h" 24#include "system.h"
25#include "settings.h" 25#include "settings.h"
26#include "replaygain.h"
26#include "debug.h" 27#include "debug.h"
27 28
28/* The "dither" code to convert the 24-bit samples produced by libmad was 29/* The "dither" code to convert the 24-bit samples produced by libmad was
29 * taken from the coolplayer project - coolplayer.sourceforge.net 30 * taken from the coolplayer project - coolplayer.sourceforge.net
30 */ 31 */
31 32
32/* 16-bit samples are scaled based on these constants. The shift should be 33/* 16-bit samples are scaled based on these constants. The shift should be
33 * no more than 15. 34 * no more than 15.
34 */ 35 */
35#define WORD_SHIFT 12 36#define WORD_SHIFT 12
@@ -336,7 +337,7 @@ static inline long clip_sample(long sample)
336 return sample; 337 return sample;
337} 338}
338 339
339/* The "dither" code to convert the 24-bit samples produced by libmad was 340/* The "dither" code to convert the 24-bit samples produced by libmad was
340 * taken from the coolplayer project - coolplayer.sourceforge.net 341 * taken from the coolplayer project - coolplayer.sourceforge.net
341 */ 342 */
342 343
@@ -386,15 +387,15 @@ static void apply_gain(long* src[], int count)
386 long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2]; 387 long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2];
387 long gain = dsp.replaygain; 388 long gain = dsp.replaygain;
388 long i; 389 long i;
389 390
390 src[0] = d0; 391 src[0] = d0;
391 src[1] = d1; 392 src[1] = d1;
392 393
393 for (i = 0; i < count; i++) 394 for (i = 0; i < count; i++)
394 { 395 {
395 *d0++ = FRACMUL_8(*s0++, gain); 396 *d0++ = FRACMUL_8(*s0++, gain);
396 } 397 }
397 398
398 if (src [0] != src [1]) 399 if (src [0] != src [1])
399 { 400 {
400 for (i = 0; i < count; i++) 401 for (i = 0; i < count; i++)
@@ -639,7 +640,7 @@ void dsp_set_replaygain(bool always)
639 long gain = 0; 640 long gain = 0;
640 641
641 dsp.new_gain = false; 642 dsp.new_gain = false;
642 643
643 if (global_settings.replaygain || global_settings.replaygain_noclip) 644 if (global_settings.replaygain || global_settings.replaygain_noclip)
644 { 645 {
645 long peak; 646 long peak;
@@ -648,28 +649,36 @@ void dsp_set_replaygain(bool always)
648 { 649 {
649 gain = (global_settings.replaygain_track || !dsp.album_gain) 650 gain = (global_settings.replaygain_track || !dsp.album_gain)
650 ? dsp.track_gain : dsp.album_gain; 651 ? dsp.track_gain : dsp.album_gain;
652
653 if (global_settings.replaygain_preamp)
654 {
655 long preamp = get_replaygain_int(
656 global_settings.replaygain_preamp * 10);
657
658 gain = (long) ((((int64_t) gain * preamp)) >> 24);
659 }
651 } 660 }
652 661
653 peak = (global_settings.replaygain_track || !dsp.album_peak) 662 peak = (global_settings.replaygain_track || !dsp.album_peak)
654 ? dsp.track_peak : dsp.album_peak; 663 ? dsp.track_peak : dsp.album_peak;
655 664
656 if (gain == 0) 665 if (gain == 0)
657 { 666 {
658 /* So that noclip can work even with no gain information. */ 667 /* So that noclip can work even with no gain information. */
659 gain = DEFAULT_REPLAYGAIN; 668 gain = DEFAULT_REPLAYGAIN;
660 } 669 }
661 670
662 if (global_settings.replaygain_noclip && (peak != 0) 671 if (global_settings.replaygain_noclip && (peak != 0)
663 && ((((int64_t) gain * peak) >> 24) >= DEFAULT_REPLAYGAIN)) 672 && ((((int64_t) gain * peak) >> 24) >= DEFAULT_REPLAYGAIN))
664 { 673 {
665 gain = (((int64_t) DEFAULT_REPLAYGAIN << 24) / peak); 674 gain = (((int64_t) DEFAULT_REPLAYGAIN << 24) / peak);
666 } 675 }
667 676
668 if (gain == DEFAULT_REPLAYGAIN) 677 if (gain == DEFAULT_REPLAYGAIN)
669 { 678 {
670 /* Nothing to do, disable processing. */ 679 /* Nothing to do, disable processing. */
671 gain = 0; 680 gain = 0;
672 681
673 } 682 }
674 } 683 }
675 684
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 3137ff7ed7..a11da030b4 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -3244,3 +3244,15 @@ desc: in settings_menu, option to enable reversal of hebrew/arabic text
3244eng: "BiDi Hebrew/Arabic" 3244eng: "BiDi Hebrew/Arabic"
3245voice "" 3245voice ""
3246new: 3246new:
3247
3248id: LANG_REPLAYGAIN_PREAMP
3249desc: in browse_id3
3250eng: "Pre-amp"
3251voice "Preamp"
3252new:
3253
3254id: LANG_UNIT_DB
3255desc: in browse_id3
3256eng: "dB"
3257voice ""
3258new:
diff --git a/apps/settings.c b/apps/settings.c
index 63e7a3b9d9..295a32f16d 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -431,6 +431,7 @@ static const struct bit_entry hd_bits[] =
431 {1, S_O(replaygain), false, "replaygain", off_on }, 431 {1, S_O(replaygain), false, "replaygain", off_on },
432 {1, S_O(replaygain_track), false, "replaygain type", "track,album" }, 432 {1, S_O(replaygain_track), false, "replaygain type", "track,album" },
433 {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on }, 433 {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
434 {8, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
434#endif 435#endif
435 436
436 /* If values are just added to the end, no need to bump the version. */ 437 /* If values are just added to the end, no need to bump the version. */
@@ -1388,7 +1389,8 @@ bool set_int(const char* string,
1388 void (*function)(int), 1389 void (*function)(int),
1389 int step, 1390 int step,
1390 int min, 1391 int min,
1391 int max ) 1392 int max,
1393 void (*formatter)(char*, int, int, const char*) )
1392{ 1394{
1393 bool done = false; 1395 bool done = false;
1394 int button; 1396 int button;
@@ -1407,7 +1409,16 @@ bool set_int(const char* string,
1407 1409
1408 while (!done) { 1410 while (!done) {
1409 char str[32]; 1411 char str[32];
1410 snprintf(str,sizeof str,"%d %s ", *variable, unit); 1412
1413 if (formatter)
1414 {
1415 formatter(str, sizeof str, *variable, unit);
1416 }
1417 else
1418 {
1419 snprintf(str,sizeof str,"%d %s ", *variable, unit);
1420 }
1421
1411 lcd_puts(0, 1, str); 1422 lcd_puts(0, 1, str);
1412#ifdef HAVE_LCD_BITMAP 1423#ifdef HAVE_LCD_BITMAP
1413 status_draw(true); 1424 status_draw(true);
diff --git a/apps/settings.h b/apps/settings.h
index ff121868cb..055b893082 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -334,6 +334,7 @@ struct user_settings
334 bool replaygain; /* enable replaygain */ 334 bool replaygain; /* enable replaygain */
335 bool replaygain_track; /* true for track gain, false for album gain */ 335 bool replaygain_track; /* true for track gain, false for album gain */
336 bool replaygain_noclip; /* scale to prevent clips */ 336 bool replaygain_noclip; /* scale to prevent clips */
337 int replaygain_preamp; /* scale replaygained tracks by this */
337#endif 338#endif
338}; 339};
339 340
@@ -366,7 +367,8 @@ bool set_bool(const char* string, bool* variable );
366bool set_option(const char* string, void* variable, enum optiontype type, 367bool set_option(const char* string, void* variable, enum optiontype type,
367 const struct opt_items* options, int numoptions, void (*function)(int)); 368 const struct opt_items* options, int numoptions, void (*function)(int));
368bool set_int(const char* string, const char* unit, int voice_unit, int* variable, 369bool set_int(const char* string, const char* unit, int voice_unit, int* variable,
369 void (*function)(int), int step, int min, int max ); 370 void (*function)(int), int step, int min, int max,
371 void (*formatter)(char*, int, int, const char*) );
370bool set_time_screen(const char* string, struct tm *tm); 372bool set_time_screen(const char* string, struct tm *tm);
371int read_line(int fd, char* buffer, int buffer_size); 373int read_line(int fd, char* buffer, int buffer_size);
372void set_file(char* filename, char* setting, int maxlen); 374void set_file(char* filename, char* setting, int maxlen);
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index fadbb11f3e..57b4cc897e 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -95,7 +95,7 @@ static bool remote_contrast(void)
95 return set_int( str(LANG_CONTRAST), "", UNIT_INT, 95 return set_int( str(LANG_CONTRAST), "", UNIT_INT,
96 &global_settings.remote_contrast, 96 &global_settings.remote_contrast,
97 lcd_remote_set_contrast, 1, MIN_CONTRAST_SETTING, 97 lcd_remote_set_contrast, 1, MIN_CONTRAST_SETTING,
98 MAX_CONTRAST_SETTING ); 98 MAX_CONTRAST_SETTING, NULL );
99} 99}
100 100
101static bool remote_invert(void) 101static bool remote_invert(void)
@@ -235,7 +235,7 @@ static bool contrast(void)
235 return set_int( str(LANG_CONTRAST), "", UNIT_INT, 235 return set_int( str(LANG_CONTRAST), "", UNIT_INT,
236 &global_settings.contrast, 236 &global_settings.contrast,
237 lcd_set_contrast, 1, MIN_CONTRAST_SETTING, 237 lcd_set_contrast, 1, MIN_CONTRAST_SETTING,
238 MAX_CONTRAST_SETTING ); 238 MAX_CONTRAST_SETTING, NULL );
239} 239}
240 240
241#ifdef HAVE_LCD_BITMAP 241#ifdef HAVE_LCD_BITMAP
@@ -322,7 +322,7 @@ static bool peak_meter_fps_menu(void) {
322 bool retval = false; 322 bool retval = false;
323 retval = set_int( "Refresh rate", "/s", UNIT_PER_SEC, 323 retval = set_int( "Refresh rate", "/s", UNIT_PER_SEC,
324 &peak_meter_fps, 324 &peak_meter_fps,
325 NULL, 1, 5, 40); 325 NULL, 1, 5, 40, NULL);
326 return retval; 326 return retval;
327} 327}
328#endif /* PM_DEBUG */ 328#endif /* PM_DEBUG */
@@ -420,7 +420,7 @@ static bool peak_meter_release(void) {
420 retval = set_int( str(LANG_PM_RELEASE), str(LANG_PM_UNITS_PER_READ), 420 retval = set_int( str(LANG_PM_RELEASE), str(LANG_PM_UNITS_PER_READ),
421 LANG_PM_UNITS_PER_READ, 421 LANG_PM_UNITS_PER_READ,
422 &global_settings.peak_meter_release, 422 &global_settings.peak_meter_release,
423 NULL, 1, 1, 0x7e); 423 NULL, 1, 1, 0x7e, NULL);
424 424
425 peak_meter_init_times(global_settings.peak_meter_release, 425 peak_meter_init_times(global_settings.peak_meter_release,
426 global_settings.peak_meter_hold, 426 global_settings.peak_meter_hold,
@@ -488,7 +488,7 @@ static bool peak_meter_min(void) {
488 int min = -global_settings.peak_meter_min; 488 int min = -global_settings.peak_meter_min;
489 489
490 retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB, 490 retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB,
491 &min, NULL, 1, -89, range_max); 491 &min, NULL, 1, -89, range_max, NULL);
492 492
493 global_settings.peak_meter_min = - min; 493 global_settings.peak_meter_min = - min;
494 } 494 }
@@ -499,7 +499,7 @@ static bool peak_meter_min(void) {
499 499
500 retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT, 500 retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT,
501 &min, NULL, 501 &min, NULL,
502 1, 0, global_settings.peak_meter_max - 1); 502 1, 0, global_settings.peak_meter_max - 1, NULL);
503 503
504 global_settings.peak_meter_min = (unsigned char)min; 504 global_settings.peak_meter_min = (unsigned char)min;
505 } 505 }
@@ -522,7 +522,7 @@ static bool peak_meter_max(void) {
522 int max = -global_settings.peak_meter_max;; 522 int max = -global_settings.peak_meter_max;;
523 523
524 retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB, 524 retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB,
525 &max, NULL, 1, range_min, 0); 525 &max, NULL, 1, range_min, 0, NULL);
526 526
527 global_settings.peak_meter_max = - max; 527 global_settings.peak_meter_max = - max;
528 528
@@ -534,7 +534,7 @@ static bool peak_meter_max(void) {
534 534
535 retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT, 535 retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT,
536 &max, NULL, 536 &max, NULL,
537 1, global_settings.peak_meter_min + 1, 100); 537 1, global_settings.peak_meter_min + 1, 100, NULL);
538 538
539 global_settings.peak_meter_max = (unsigned char)max; 539 global_settings.peak_meter_max = (unsigned char)max;
540 } 540 }
@@ -765,7 +765,7 @@ static bool scroll_speed(void)
765{ 765{
766 return set_int(str(LANG_SCROLL), "", UNIT_INT, 766 return set_int(str(LANG_SCROLL), "", UNIT_INT,
767 &global_settings.scroll_speed, 767 &global_settings.scroll_speed,
768 &lcd_scroll_speed, 1, 0, 15 ); 768 &lcd_scroll_speed, 1, 0, 15, NULL );
769} 769}
770 770
771 771
@@ -774,7 +774,7 @@ static bool scroll_delay(void)
774 int dummy = global_settings.scroll_delay * (HZ/10); 774 int dummy = global_settings.scroll_delay * (HZ/10);
775 int rc = set_int(str(LANG_SCROLL_DELAY), "ms", UNIT_MS, 775 int rc = set_int(str(LANG_SCROLL_DELAY), "ms", UNIT_MS,
776 &dummy, 776 &dummy,
777 &lcd_scroll_delay, 100, 0, 2500 ); 777 &lcd_scroll_delay, 100, 0, 2500, NULL );
778 global_settings.scroll_delay = dummy / (HZ/10); 778 global_settings.scroll_delay = dummy / (HZ/10);
779 return rc; 779 return rc;
780} 780}
@@ -784,7 +784,7 @@ static bool scroll_step(void)
784{ 784{
785 return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", UNIT_PIXEL, 785 return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", UNIT_PIXEL,
786 &global_settings.scroll_step, 786 &global_settings.scroll_step,
787 &lcd_scroll_step, 1, 1, LCD_WIDTH ); 787 &lcd_scroll_step, 1, 1, LCD_WIDTH, NULL );
788} 788}
789#endif 789#endif
790 790
@@ -792,7 +792,7 @@ static bool bidir_limit(void)
792{ 792{
793 return set_int(str(LANG_BIDIR_SCROLL), "%", UNIT_PERCENT, 793 return set_int(str(LANG_BIDIR_SCROLL), "%", UNIT_PERCENT,
794 &global_settings.bidir_limit, 794 &global_settings.bidir_limit,
795 &lcd_bidir_scroll, 25, 0, 200 ); 795 &lcd_bidir_scroll, 25, 0, 200, NULL );
796} 796}
797 797
798#ifdef HAVE_LCD_CHARCELLS 798#ifdef HAVE_LCD_CHARCELLS
@@ -816,7 +816,7 @@ static bool jump_scroll_delay(void)
816 int dummy = global_settings.jump_scroll_delay * (HZ/10); 816 int dummy = global_settings.jump_scroll_delay * (HZ/10);
817 int rc = set_int(str(LANG_JUMP_SCROLL_DELAY), "ms", UNIT_MS, 817 int rc = set_int(str(LANG_JUMP_SCROLL_DELAY), "ms", UNIT_MS,
818 &dummy, 818 &dummy,
819 &lcd_jump_scroll_delay, 100, 0, 2500 ); 819 &lcd_jump_scroll_delay, 100, 0, 2500, NULL );
820 global_settings.jump_scroll_delay = dummy / (HZ/10); 820 global_settings.jump_scroll_delay = dummy / (HZ/10);
821 return rc; 821 return rc;
822} 822}
@@ -831,7 +831,7 @@ static bool battery_capacity(void)
831 return set_int(str(LANG_BATTERY_CAPACITY), "mAh", UNIT_MAH, 831 return set_int(str(LANG_BATTERY_CAPACITY), "mAh", UNIT_MAH,
832 &global_settings.battery_capacity, 832 &global_settings.battery_capacity,
833 &set_battery_capacity, 50, BATTERY_CAPACITY_MIN, 833 &set_battery_capacity, 50, BATTERY_CAPACITY_MIN,
834 BATTERY_CAPACITY_MAX ); 834 BATTERY_CAPACITY_MAX, NULL );
835} 835}
836 836
837#if BATTERY_TYPES_COUNT > 1 837#if BATTERY_TYPES_COUNT > 1
@@ -895,7 +895,7 @@ static bool spindown(void)
895{ 895{
896 return set_int(str(LANG_SPINDOWN), "s", UNIT_SEC, 896 return set_int(str(LANG_SPINDOWN), "s", UNIT_SEC,
897 &global_settings.disk_spindown, 897 &global_settings.disk_spindown,
898 ata_spindown, 1, 3, 254 ); 898 ata_spindown, 1, 3, 254, NULL );
899} 899}
900 900
901#ifdef HAVE_ATA_POWER_OFF 901#ifdef HAVE_ATA_POWER_OFF
@@ -921,14 +921,14 @@ static bool max_files_in_dir(void)
921{ 921{
922 return set_int(str(LANG_MAX_FILES_IN_DIR), "", UNIT_INT, 922 return set_int(str(LANG_MAX_FILES_IN_DIR), "", UNIT_INT,
923 &global_settings.max_files_in_dir, 923 &global_settings.max_files_in_dir,
924 NULL, 50, 50, 10000 ); 924 NULL, 50, 50, 10000, NULL );
925} 925}
926 926
927static bool max_files_in_playlist(void) 927static bool max_files_in_playlist(void)
928{ 928{
929 return set_int(str(LANG_MAX_FILES_IN_PLAYLIST), "", UNIT_INT, 929 return set_int(str(LANG_MAX_FILES_IN_PLAYLIST), "", UNIT_INT,
930 &global_settings.max_files_in_playlist, 930 &global_settings.max_files_in_playlist,
931 NULL, 1000, 1000, 20000 ); 931 NULL, 1000, 1000, 20000, NULL );
932} 932}
933 933
934#if CONFIG_HWCODEC == MASNONE 934#if CONFIG_HWCODEC == MASNONE
@@ -957,7 +957,7 @@ static bool buffer_margin(void)
957{ 957{
958 return set_int(str(LANG_MP3BUFFER_MARGIN), "s", UNIT_SEC, 958 return set_int(str(LANG_MP3BUFFER_MARGIN), "s", UNIT_SEC,
959 &global_settings.buffer_margin, 959 &global_settings.buffer_margin,
960 audio_set_buffer_margin, 1, 0, 7 ); 960 audio_set_buffer_margin, 1, 0, 7, NULL );
961} 961}
962#endif 962#endif
963 963
@@ -1232,6 +1232,25 @@ static bool replaygain_noclip(void)
1232 return result; 1232 return result;
1233} 1233}
1234 1234
1235void replaygain_preamp_format(char* buffer, int buffer_size, int value,
1236 const char* unit)
1237{
1238 int v = abs(value);
1239
1240 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "",
1241 v / 10, v % 10, unit);
1242}
1243
1244static bool replaygain_preamp(void)
1245{
1246 bool result = set_int(str(LANG_REPLAYGAIN_PREAMP), str(LANG_UNIT_DB),
1247 UNIT_DB, &global_settings.replaygain_preamp, NULL, 1, -120, 120,
1248 replaygain_preamp_format);
1249
1250 dsp_set_replaygain(true);
1251 return result;
1252}
1253
1235static bool replaygain_settings_menu(void) 1254static bool replaygain_settings_menu(void)
1236{ 1255{
1237 int m; 1256 int m;
@@ -1241,6 +1260,7 @@ static bool replaygain_settings_menu(void)
1241 { ID2P(LANG_REPLAYGAIN_ENABLE), replaygain }, 1260 { ID2P(LANG_REPLAYGAIN_ENABLE), replaygain },
1242 { ID2P(LANG_REPLAYGAIN_NOCLIP), replaygain_noclip }, 1261 { ID2P(LANG_REPLAYGAIN_NOCLIP), replaygain_noclip },
1243 { ID2P(LANG_REPLAYGAIN_MODE), replaygain_mode }, 1262 { ID2P(LANG_REPLAYGAIN_MODE), replaygain_mode },
1263 { ID2P(LANG_REPLAYGAIN_PREAMP), replaygain_preamp },
1244 }; 1264 };
1245 1265
1246 m=menu_init( items, sizeof(items) / sizeof(*items), NULL, 1266 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 1b19593b6f..0c298b091f 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -292,7 +292,7 @@ static bool recquality(void)
292{ 292{
293 return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, 293 return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
294 &global_settings.rec_quality, 294 &global_settings.rec_quality,
295 NULL, 1, 0, 7 ); 295 NULL, 1, 0, 7, NULL );
296} 296}
297 297
298static bool receditable(void) 298static bool receditable(void)
diff --git a/firmware/export/replaygain.h b/firmware/export/replaygain.h
index e96a7f907a..c29d4b6921 100644
--- a/firmware/export/replaygain.h
+++ b/firmware/export/replaygain.h
@@ -22,6 +22,7 @@
22 22
23#include "id3.h" 23#include "id3.h"
24 24
25long get_replaygain_int(long int_gain);
25long get_replaygain(const char* str); 26long get_replaygain(const char* str);
26long get_replaypeak(const char* str); 27long get_replaypeak(const char* str);
27long parse_replaygain(const char* key, const char* value, 28long parse_replaygain(const char* key, const char* value,
diff --git a/firmware/replaygain.c b/firmware/replaygain.c
index 542eee6101..a21336013b 100644
--- a/firmware/replaygain.c
+++ b/firmware/replaygain.c
@@ -305,6 +305,18 @@ static long convert_gain(long gain)
305 return gain; 305 return gain;
306} 306}
307 307
308long get_replaygain_int(long int_gain)
309{
310 long gain = 0;
311
312 if (int_gain)
313 {
314 gain = convert_gain(int_gain * FP_ONE / 100);
315 }
316
317 return gain;
318}
319
308long get_replaygain(const char* str) 320long get_replaygain(const char* str)
309{ 321{
310 long gain = 0; 322 long gain = 0;