aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/dsp_cmx.c
diff options
context:
space:
mode:
authorAndreas Eversberg <andreas@eversberg.eu>2008-08-02 16:51:52 -0400
committerKarsten Keil <kkeil@suse.de>2009-01-09 16:44:22 -0500
commit8dd2f36f317569665e454268a2677cfba3e848f1 (patch)
tree62f0d30aa090594648ed21cb9a863e4cc2b4f4fd /drivers/isdn/mISDN/dsp_cmx.c
parent69e656cc16511719a89d83373c48172d3f39bc5f (diff)
mISDN: Add feature via MISDN_CTRL_FILL_EMPTY to fill fifo if empty
This prevents underrun of fifo when filled and in case of an underrun it prevents subsequent underruns due to jitter. Improve dsp, so buffers are kept filled with a certain delay, so moderate jitter will not cause underrun all the time -> the audio quality is highly improved. tones are not interrupted by gaps anymore, except when CPU is stalling or in high load. Signed-off-by: Andreas Eversberg <andreas@eversberg.eu> Signed-off-by: Karsten Keil <kkeil@suse.de>
Diffstat (limited to 'drivers/isdn/mISDN/dsp_cmx.c')
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index c884511e2d49..fc8ea41ae6a2 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1168,11 +1168,18 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1168 dsp->rx_init = 0; 1168 dsp->rx_init = 0;
1169 if (dsp->features.unordered) { 1169 if (dsp->features.unordered) {
1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1171 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1171 if (dsp->cmx_delay)
1172 & CMX_BUFF_MASK; 1172 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1173 & CMX_BUFF_MASK;
1174 else
1175 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
1176 & CMX_BUFF_MASK;
1173 } else { 1177 } else {
1174 dsp->rx_R = 0; 1178 dsp->rx_R = 0;
1175 dsp->rx_W = dsp->cmx_delay; 1179 if (dsp->cmx_delay)
1180 dsp->rx_W = dsp->cmx_delay;
1181 else
1182 dsp->rx_W = dsp_poll >> 1;
1176 } 1183 }
1177 } 1184 }
1178 /* if frame contains time code, write directly */ 1185 /* if frame contains time code, write directly */
@@ -1190,14 +1197,20 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1190 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the " 1197 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
1191 "maximum delay), adjusting read pointer! " 1198 "maximum delay), adjusting read pointer! "
1192 "(inst %s)\n", (u_long)dsp, dsp->name); 1199 "(inst %s)\n", (u_long)dsp, dsp->name);
1193 /* flush buffer */ 1200 /* flush rx buffer and set delay to dsp_poll / 2 */
1194 if (dsp->features.unordered) { 1201 if (dsp->features.unordered) {
1195 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1202 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1196 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1203 if (dsp->cmx_delay)
1197 & CMX_BUFF_MASK; 1204 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1205 & CMX_BUFF_MASK;
1206 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
1207 & CMX_BUFF_MASK;
1198 } else { 1208 } else {
1199 dsp->rx_R = 0; 1209 dsp->rx_R = 0;
1200 dsp->rx_W = dsp->cmx_delay; 1210 if (dsp->cmx_delay)
1211 dsp->rx_W = dsp->cmx_delay;
1212 else
1213 dsp->rx_W = dsp_poll >> 1;
1201 } 1214 }
1202 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); 1215 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1203 } 1216 }
@@ -1360,8 +1373,11 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
1360 t = (t+1) & CMX_BUFF_MASK; 1373 t = (t+1) & CMX_BUFF_MASK;
1361 r = (r+1) & CMX_BUFF_MASK; 1374 r = (r+1) & CMX_BUFF_MASK;
1362 } 1375 }
1363 if (r != rr) 1376 if (r != rr) {
1377 printk(KERN_DEBUG "%s: buffer empty\n",
1378 __func__);
1364 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK); 1379 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
1380 }
1365 /* -> if echo is enabled */ 1381 /* -> if echo is enabled */
1366 } else { 1382 } else {
1367 /* 1383 /*
@@ -1704,9 +1720,10 @@ dsp_cmx_send(void *arg)
1704 } 1720 }
1705 /* 1721 /*
1706 * remove rx_delay only if we have delay AND we 1722 * remove rx_delay only if we have delay AND we
1707 * have not preset cmx_delay 1723 * have not preset cmx_delay AND
1724 * the delay is greater dsp_poll
1708 */ 1725 */
1709 if (delay && !dsp->cmx_delay) { 1726 if (delay > dsp_poll && !dsp->cmx_delay) {
1710 if (dsp_debug & DEBUG_DSP_CMX) 1727 if (dsp_debug & DEBUG_DSP_CMX)
1711 printk(KERN_DEBUG 1728 printk(KERN_DEBUG
1712 "%s lowest rx_delay of %d bytes for" 1729 "%s lowest rx_delay of %d bytes for"
@@ -1714,7 +1731,8 @@ dsp_cmx_send(void *arg)
1714 __func__, delay, 1731 __func__, delay,
1715 dsp->name); 1732 dsp->name);
1716 r = dsp->rx_R; 1733 r = dsp->rx_R;
1717 rr = (r + delay) & CMX_BUFF_MASK; 1734 rr = (r + delay - (dsp_poll >> 1))
1735 & CMX_BUFF_MASK;
1718 /* delete rx-data */ 1736 /* delete rx-data */
1719 while (r != rr) { 1737 while (r != rr) {
1720 p[r] = dsp_silence; 1738 p[r] = dsp_silence;
@@ -1736,7 +1754,7 @@ dsp_cmx_send(void *arg)
1736 * remove delay only if we have delay AND we 1754 * remove delay only if we have delay AND we
1737 * have enabled tx_dejitter 1755 * have enabled tx_dejitter
1738 */ 1756 */
1739 if (delay && dsp->tx_dejitter) { 1757 if (delay > dsp_poll && dsp->tx_dejitter) {
1740 if (dsp_debug & DEBUG_DSP_CMX) 1758 if (dsp_debug & DEBUG_DSP_CMX)
1741 printk(KERN_DEBUG 1759 printk(KERN_DEBUG
1742 "%s lowest tx_delay of %d bytes for" 1760 "%s lowest tx_delay of %d bytes for"
@@ -1744,7 +1762,8 @@ dsp_cmx_send(void *arg)
1744 __func__, delay, 1762 __func__, delay,
1745 dsp->name); 1763 dsp->name);
1746 r = dsp->tx_R; 1764 r = dsp->tx_R;
1747 rr = (r + delay) & CMX_BUFF_MASK; 1765 rr = (r + delay - (dsp_poll >> 1))
1766 & CMX_BUFF_MASK;
1748 /* delete tx-data */ 1767 /* delete tx-data */
1749 while (r != rr) { 1768 while (r != rr) {
1750 q[r] = dsp_silence; 1769 q[r] = dsp_silence;
@@ -1797,14 +1816,13 @@ dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
1797 ww = dsp->tx_R; 1816 ww = dsp->tx_R;
1798 p = dsp->tx_buff; 1817 p = dsp->tx_buff;
1799 d = skb->data; 1818 d = skb->data;
1800 space = ww-w; 1819 space = (ww - w - 1) & CMX_BUFF_MASK;
1801 if (space <= 0)
1802 space += CMX_BUFF_SIZE;
1803 /* write-pointer should not overrun nor reach read pointer */ 1820 /* write-pointer should not overrun nor reach read pointer */
1804 if (space-1 < skb->len) 1821 if (space < skb->len) {
1805 /* write to the space we have left */ 1822 /* write to the space we have left */
1806 ww = (ww - 1) & CMX_BUFF_MASK; 1823 ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
1807 else 1824 printk(KERN_DEBUG "%s: buffer overflow\n", __func__);
1825 } else
1808 /* write until all byte are copied */ 1826 /* write until all byte are copied */
1809 ww = (w + skb->len) & CMX_BUFF_MASK; 1827 ww = (w + skb->len) & CMX_BUFF_MASK;
1810 dsp->tx_W = ww; 1828 dsp->tx_W = ww;