summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2011-10-05 04:44:56 +0000
committerJeffrey Goode <jeffg7@gmail.com>2011-10-05 04:44:56 +0000
commita604345ae11bd7aae977c49bf6bb058f40b970a7 (patch)
treed13b9b48579918a1f79a8b5758df6fb21f651008
parentb683874e9870658053fedf6ef776b500426c6b86 (diff)
downloadrockbox-a604345ae11bd7aae977c49bf6bb058f40b970a7.tar.gz
rockbox-a604345ae11bd7aae977c49bf6bb058f40b970a7.zip
Clean up compressor setting code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30715 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dsp.c138
-rw-r--r--apps/dsp.h3
-rw-r--r--apps/settings.c6
-rw-r--r--apps/settings_list.c6
4 files changed, 70 insertions, 83 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index 3f1eb75200..aab1e17022 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -133,15 +133,6 @@ struct eq_state
133 /* 10ch */ 133 /* 10ch */
134}; 134};
135 135
136struct compressor_menu
137{
138 int threshold; /* dB - from menu */
139 bool auto_gain; /* 0 = off, 1 = auto */
140 int ratio; /* from menu */
141 bool soft_knee; /* 0 = hard knee, 1 = soft knee */
142 int release; /* samples - from menu */
143};
144
145/* Include header with defines which functions are implemented in assembly 136/* Include header with defines which functions are implemented in assembly
146 code for the target */ 137 code for the target */
147#include <dsp_asm.h> 138#include <dsp_asm.h>
@@ -260,13 +251,12 @@ static int resample_buf_count = SMALL_RESAMPLE_BUF_COUNT;
260static int32_t *resample_buf[2] = { small_resample_buf[0], small_resample_buf[1] }; 251static int32_t *resample_buf[2] = { small_resample_buf[0], small_resample_buf[1] };
261 252
262/* compressor */ 253/* compressor */
263static struct compressor_menu c_menu;
264static int32_t comp_rel_slope IBSS_ATTR; /* S7.24 format */ 254static int32_t comp_rel_slope IBSS_ATTR; /* S7.24 format */
265static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */ 255static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */
266static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */ 256static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */
267static int32_t release_gain IBSS_ATTR; /* S7.24 format */ 257static int32_t release_gain IBSS_ATTR; /* S7.24 format */
268#define UNITY (1L << 24) /* unity gain in S7.24 format */ 258#define UNITY (1L << 24) /* unity gain in S7.24 format */
269static void compressor_process(int count, int32_t *buf[]); 259static void compressor_process(int count, int32_t *buf[]);
270 260
271 261
272/* Clip sample to signed 16 bit range */ 262/* Clip sample to signed 16 bit range */
@@ -1607,55 +1597,61 @@ void dsp_set_replaygain(void)
1607 1597
1608/** SET COMPRESSOR 1598/** SET COMPRESSOR
1609 * Called by the menu system to configure the compressor process */ 1599 * Called by the menu system to configure the compressor process */
1610void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio, 1600void dsp_set_compressor(void)
1611 int c_knee, int c_release) 1601{
1612{ 1602 static int curr_set[5];
1613 bool changed = false; 1603 int new_set[5] = {
1614 bool active = (c_threshold < 0); 1604 global_settings.compressor_threshold,
1615 bool new_auto_gain = (c_gain == 1); 1605 global_settings.compressor_makeup_gain,
1616 const int comp_ratio[] = {2, 4, 6, 10, 0}; 1606 global_settings.compressor_ratio,
1617 int new_ratio = comp_ratio[c_ratio]; 1607 global_settings.compressor_knee,
1618 bool new_knee = (c_knee == 1); 1608 global_settings.compressor_release_time};
1619 int new_release = c_release * NATIVE_FREQUENCY / 1000;
1620 1609
1621 if (c_menu.threshold != c_threshold) 1610 /* make menu values useful */
1622 { 1611 int threshold = new_set[0];
1623 changed = true; 1612 bool auto_gain = (new_set[1] == 1);
1624 c_menu.threshold = c_threshold; 1613 const int comp_ratios[] = {2, 4, 6, 10, 0};
1625 logf(" Compressor Threshold: %d dB\tEnabled: %s", 1614 int ratio = comp_ratios[new_set[2]];
1626 c_menu.threshold, active ? "Yes" : "No"); 1615 bool soft_knee = (new_set[3] == 1);
1627 } 1616 int release = new_set[4] * NATIVE_FREQUENCY / 1000;
1628 1617
1629 if (c_menu.auto_gain != new_auto_gain) 1618 bool changed = false;
1630 { 1619 bool active = (threshold < 0);
1631 changed = true; 1620
1632 c_menu.auto_gain = new_auto_gain; 1621 int i;
1633 logf(" Compressor Makeup Gain: %s", 1622 for (i = 0; i < 5; i++)
1634 c_menu.auto_gain ? "Auto" : "Off");
1635 }
1636
1637 if (c_menu.ratio != new_ratio)
1638 {
1639 changed = true;
1640 c_menu.ratio = new_ratio;
1641 if (c_menu.ratio)
1642 { logf(" Compressor Ratio: %d:1", c_menu.ratio); }
1643 else
1644 { logf(" Compressor Ratio: Limit"); }
1645 }
1646
1647 if (c_menu.soft_knee != new_knee)
1648 {
1649 changed = true;
1650 c_menu.soft_knee = new_knee;
1651 logf(" Compressor Knee: %s", c_menu.soft_knee==1?"Soft":"Hard");
1652 }
1653
1654 if (c_menu.release != new_release)
1655 { 1623 {
1656 changed = true; 1624 if (curr_set[i] != new_set[i])
1657 c_menu.release = new_release; 1625 {
1658 logf(" Compressor Release: %d", c_menu.release); 1626 changed = true;
1627 curr_set[i] = new_set[i];
1628
1629#if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
1630 switch (i)
1631 {
1632 case 0:
1633 logf(" Compressor Threshold: %d dB\tEnabled: %s",
1634 threshold, active ? "Yes" : "No");
1635 break;
1636 case 1:
1637 logf(" Compressor Makeup Gain: %s",
1638 auto_gain ? "Auto" : "Off");
1639 break;
1640 case 2:
1641 if (ratio)
1642 { logf(" Compressor Ratio: %d:1", ratio); }
1643 else
1644 { logf(" Compressor Ratio: Limit"); }
1645 break;
1646 case 3:
1647 logf(" Compressor Knee: %s", soft_knee?"Soft":"Hard");
1648 break;
1649 case 4:
1650 logf(" Compressor Release: %d", release);
1651 break;
1652 }
1653#endif
1654 }
1659 } 1655 }
1660 1656
1661 if (changed && active) 1657 if (changed && active)
@@ -1685,17 +1681,17 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
1685 [3] = 0 db input 1681 [3] = 0 db input
1686 [4] = ~+12db input (2 bits clipping overhead) */ 1682 [4] = ~+12db input (2 bits clipping overhead) */
1687 1683
1688 db_curve[1].db = c_menu.threshold << 16; 1684 db_curve[1].db = threshold << 16;
1689 if (c_menu.soft_knee) 1685 if (soft_knee)
1690 { 1686 {
1691 /* bottom of knee is 3dB below the threshold for soft knee*/ 1687 /* bottom of knee is 3dB below the threshold for soft knee*/
1692 db_curve[0].db = db_curve[1].db - (3 << 16); 1688 db_curve[0].db = db_curve[1].db - (3 << 16);
1693 /* top of knee is 3dB above the threshold for soft knee */ 1689 /* top of knee is 3dB above the threshold for soft knee */
1694 db_curve[2].db = db_curve[1].db + (3 << 16); 1690 db_curve[2].db = db_curve[1].db + (3 << 16);
1695 if (c_menu.ratio) 1691 if (ratio)
1696 /* offset = -3db * (ratio - 1) / ratio */ 1692 /* offset = -3db * (ratio - 1) / ratio */
1697 db_curve[2].offset = (int32_t)((long long)(-3 << 16) 1693 db_curve[2].offset = (int32_t)((long long)(-3 << 16)
1698 * (c_menu.ratio - 1) / c_menu.ratio); 1694 * (ratio - 1) / ratio);
1699 else 1695 else
1700 /* offset = -3db for hard limit */ 1696 /* offset = -3db for hard limit */
1701 db_curve[2].offset = (-3 << 16); 1697 db_curve[2].offset = (-3 << 16);
@@ -1703,26 +1699,26 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
1703 else 1699 else
1704 { 1700 {
1705 /* bottom of knee is at the threshold for hard knee */ 1701 /* bottom of knee is at the threshold for hard knee */
1706 db_curve[0].db = c_menu.threshold << 16; 1702 db_curve[0].db = threshold << 16;
1707 /* top of knee is at the threshold for hard knee */ 1703 /* top of knee is at the threshold for hard knee */
1708 db_curve[2].db = c_menu.threshold << 16; 1704 db_curve[2].db = threshold << 16;
1709 db_curve[2].offset = 0; 1705 db_curve[2].offset = 0;
1710 } 1706 }
1711 1707
1712 /* Calculate 0db and ~+12db offsets */ 1708 /* Calculate 0db and ~+12db offsets */
1713 db_curve[4].db = 0xC0A8C; /* db of 2 bits clipping */ 1709 db_curve[4].db = 0xC0A8C; /* db of 2 bits clipping */
1714 if (c_menu.ratio) 1710 if (ratio)
1715 { 1711 {
1716 /* offset = threshold * (ratio - 1) / ratio */ 1712 /* offset = threshold * (ratio - 1) / ratio */
1717 db_curve[3].offset = (int32_t)((long long)(c_menu.threshold << 16) 1713 db_curve[3].offset = (int32_t)((long long)(threshold << 16)
1718 * (c_menu.ratio - 1) / c_menu.ratio); 1714 * (ratio - 1) / ratio);
1719 db_curve[4].offset = (int32_t)((long long)-db_curve[4].db 1715 db_curve[4].offset = (int32_t)((long long)-db_curve[4].db
1720 * (c_menu.ratio - 1) / c_menu.ratio) + db_curve[3].offset; 1716 * (ratio - 1) / ratio) + db_curve[3].offset;
1721 } 1717 }
1722 else 1718 else
1723 { 1719 {
1724 /* offset = threshold for hard limit */ 1720 /* offset = threshold for hard limit */
1725 db_curve[3].offset = (c_menu.threshold << 16); 1721 db_curve[3].offset = (threshold << 16);
1726 db_curve[4].offset = -db_curve[4].db + db_curve[3].offset; 1722 db_curve[4].offset = -db_curve[4].db + db_curve[3].offset;
1727 } 1723 }
1728 1724
@@ -1744,7 +1740,7 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
1744 1740
1745 /* if soft knee and below top of knee, 1741 /* if soft knee and below top of knee,
1746 interpolate along soft knee slope */ 1742 interpolate along soft knee slope */
1747 else if (c_menu.soft_knee && (this_db <= db_curve[2].db)) 1743 else if (soft_knee && (this_db <= db_curve[2].db))
1748 comp_curve[i] = fp_factor(fp_mul( 1744 comp_curve[i] = fp_factor(fp_mul(
1749 ((this_db - db_curve[0].db) / 6), 1745 ((this_db - db_curve[0].db) / 6),
1750 db_curve[2].offset, 16), 16) << 8; 1746 db_curve[2].offset, 16), 16) << 8;
@@ -1787,12 +1783,12 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
1787#endif 1783#endif
1788 1784
1789 /* if using auto peak, then makeup gain is max offset - .1dB headroom */ 1785 /* if using auto peak, then makeup gain is max offset - .1dB headroom */
1790 comp_makeup_gain = c_menu.auto_gain ? 1786 comp_makeup_gain = auto_gain ?
1791 fp_factor(-(db_curve[3].offset) - 0x199A, 16) << 8 : UNITY; 1787 fp_factor(-(db_curve[3].offset) - 0x199A, 16) << 8 : UNITY;
1792 logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY); 1788 logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY);
1793 1789
1794 /* calculate per-sample gain change a rate of 10db over release time */ 1790 /* calculate per-sample gain change a rate of 10db over release time */
1795 comp_rel_slope = 0xAF0BB2 / c_menu.release; 1791 comp_rel_slope = 0xAF0BB2 / release;
1796 logf("Release slope:\t%.6f", (float)comp_rel_slope / UNITY); 1792 logf("Release slope:\t%.6f", (float)comp_rel_slope / UNITY);
1797 1793
1798 release_gain = UNITY; 1794 release_gain = UNITY;
diff --git a/apps/dsp.h b/apps/dsp.h
index 092a99f052..c42e712a5a 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -82,7 +82,6 @@ int32_t sound_get_pitch(void);
82void dsp_set_timestretch(int32_t percent); 82void dsp_set_timestretch(int32_t percent);
83int32_t dsp_get_timestretch(void); 83int32_t dsp_get_timestretch(void);
84int dsp_callback(int msg, intptr_t param); 84int dsp_callback(int msg, intptr_t param);
85void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio, 85void dsp_set_compressor(void);
86 int c_knee, int c_release);
87 86
88#endif 87#endif
diff --git a/apps/settings.c b/apps/settings.c
index 14217ed1ae..a6986068fa 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -989,11 +989,7 @@ void settings_apply(bool read_disk)
989#ifdef HAVE_PITCHSCREEN 989#ifdef HAVE_PITCHSCREEN
990 dsp_timestretch_enable(global_settings.timestretch_enabled); 990 dsp_timestretch_enable(global_settings.timestretch_enabled);
991#endif 991#endif
992 dsp_set_compressor(global_settings.compressor_threshold, 992 dsp_set_compressor();
993 global_settings.compressor_makeup_gain,
994 global_settings.compressor_ratio,
995 global_settings.compressor_knee,
996 global_settings.compressor_release_time);
997#endif 993#endif
998 994
999#ifdef HAVE_SPDIF_POWER 995#ifdef HAVE_SPDIF_POWER
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 2f452e6218..eb62b9b975 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -385,11 +385,7 @@ static void crossfeed_cross_set(int val)
385static void compressor_set(int val) 385static void compressor_set(int val)
386{ 386{
387 (void)val; 387 (void)val;
388 dsp_set_compressor(global_settings.compressor_threshold, 388 dsp_set_compressor();
389 global_settings.compressor_makeup_gain,
390 global_settings.compressor_ratio,
391 global_settings.compressor_knee,
392 global_settings.compressor_release_time);
393} 389}
394 390
395static const char* db_format(char* buffer, size_t buffer_size, int value, 391static const char* db_format(char* buffer, size_t buffer_size, int value,