comparison src/audio/SDL_audiocvt.c @ 2716:f8f68f47285a

Final merge of Google Summer of Code 2008 work... Audio Ideas - Resampling and Pitch Shifting by Aaron Wishnick, mentored by Ryan C. Gordon
author Sam Lantinga <slouken@libsdl.org>
date Mon, 25 Aug 2008 15:08:59 +0000
parents 3ee59c43d784
children 2768bd7281e0
comparison
equal deleted inserted replaced
2715:336b604ec15b 2716:f8f68f47285a
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 #include <math.h>
23 24
24 /* Functions for audio drivers to perform runtime conversion of audio format */ 25 /* Functions for audio drivers to perform runtime conversion of audio format */
25 26
26 #include "SDL_audio.h" 27 #include "SDL_audio.h"
27 #include "SDL_audio_c.h" 28 #include "SDL_audio_c.h"
29
30 #define DEBUG_CONVERT
31
32 /* These are fractional multiplication routines. That is, their inputs
33 are two numbers in the range [-1, 1) and the result falls in that
34 same range. The output is the same size as the inputs, i.e.
35 32-bit x 32-bit = 32-bit.
36 */
37
38 /* We hope here that the right shift includes sign extension */
39 #ifdef SDL_HAS_64BIT_Type
40 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
41 #else
42 /* If we don't have the 64-bit type, do something more complicated. See http://www.8052.com/mul16.phtml or http://www.cs.uaf.edu/~cs301/notes/Chapter5/node5.html */
43 #define SDL_FixMpy32(a, b) ((((Sint64)a * (Sint64)b) >> 31) & 0xffffffff)
44 #endif
45 #define SDL_FixMpy16(a, b) ((((Sint32)a * (Sint32)b) >> 14) & 0xffff)
46 #define SDL_FixMpy8(a, b) ((((Sint16)a * (Sint16)b) >> 7) & 0xff)
47 /* This macro just makes the floating point filtering code not have to be a special case. */
48 #define SDL_FloatMpy(a, b) (a * b)
49
50 /* These macros take floating point numbers in the range [-1.0f, 1.0f) and
51 represent them as fixed-point numbers in that same range. There's no
52 checking that the floating point argument is inside the appropriate range.
53 */
54
55 #define SDL_Make_1_7(a) (Sint8)(a * 128.0f)
56 #define SDL_Make_1_15(a) (Sint16)(a * 32768.0f)
57 #define SDL_Make_1_31(a) (Sint32)(a * 2147483648.0f)
58 #define SDL_Make_2_6(a) (Sint8)(a * 64.0f)
59 #define SDL_Make_2_14(a) (Sint16)(a * 16384.0f)
60 #define SDL_Make_2_30(a) (Sint32)(a * 1073741824.0f)
28 61
29 /* Effectively mix right and left channels into a single channel */ 62 /* Effectively mix right and left channels into a single channel */
30 static void SDLCALL 63 static void SDLCALL
31 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) 64 SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
32 { 65 {
1307 } 1340 }
1308 1341
1309 return 0; /* no conversion necessary. */ 1342 return 0; /* no conversion necessary. */
1310 } 1343 }
1311 1344
1345 /* Generate the necessary IIR lowpass coefficients for resampling.
1346 Assume that the SDL_AudioCVT struct is already set up with
1347 the correct values for len_mult and len_div, and use the
1348 type of dst_format. Also assume the buffer is allocated.
1349 Note the buffer needs to be 6 units long.
1350 For now, use RBJ's cookbook coefficients. It might be more
1351 optimal to create a Butterworth filter, but this is more difficult.
1352 */
1353 int
1354 SDL_BuildIIRLowpass(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1355 {
1356 float fc; /* cutoff frequency */
1357 float coeff[6]; /* floating point iir coefficients b0, b1, b2, a0, a1, a2 */
1358 float scale;
1359 float w0, alpha, cosw0;
1360 int i;
1361
1362 /* The higher Q is, the higher CUTOFF can be. Need to find a good balance to avoid aliasing */
1363 static const float Q = 5.0f;
1364 static const float CUTOFF = 0.4f;
1365
1366 fc = (cvt->len_mult >
1367 cvt->len_div) ? CUTOFF / (float) cvt->len_mult : CUTOFF /
1368 (float) cvt->len_div;
1369
1370 w0 = 2.0f * M_PI * fc;
1371 cosw0 = cosf(w0);
1372 alpha = sin(w0) / (2.0f * Q);
1373
1374 /* Compute coefficients, normalizing by a0 */
1375 scale = 1.0f / (1.0f + alpha);
1376
1377 coeff[0] = (1.0f - cosw0) / 2.0f * scale;
1378 coeff[1] = (1.0f - cosw0) * scale;
1379 coeff[2] = coeff[0];
1380
1381 coeff[3] = 1.0f; /* a0 is normalized to 1 */
1382 coeff[4] = -2.0f * cosw0 * scale;
1383 coeff[5] = (1.0f - alpha) * scale;
1384
1385 /* Copy the coefficients to the struct. If necessary, convert coefficients to fixed point, using the range (-2.0, 2.0) */
1386 #define convert_fixed(type, fix) { \
1387 type *cvt_coeff = (type *)cvt->coeff; \
1388 for(i = 0; i < 6; ++i) { \
1389 cvt_coeff[i] = fix(coeff[i]); \
1390 } \
1391 }
1392
1393 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1394 float *cvt_coeff = (float *) cvt->coeff;
1395 for (i = 0; i < 6; ++i) {
1396 cvt_coeff[i] = coeff[i];
1397 }
1398 } else {
1399 switch (SDL_AUDIO_BITSIZE(format)) {
1400 case 8:
1401 convert_fixed(Uint8, SDL_Make_2_6);
1402 break;
1403 case 16:
1404 convert_fixed(Uint16, SDL_Make_2_14);
1405 break;
1406 case 32:
1407 convert_fixed(Uint32, SDL_Make_2_30);
1408 break;
1409 }
1410 }
1411
1412 #ifdef DEBUG_CONVERT
1413 #define debug_iir(type) { \
1414 type *cvt_coeff = (type *)cvt->coeff; \
1415 for(i = 0; i < 6; ++i) { \
1416 printf("coeff[%u] = %f = 0x%x\n", i, coeff[i], cvt_coeff[i]); \
1417 } \
1418 }
1419 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1420 float *cvt_coeff = (float *) cvt->coeff;
1421 for (i = 0; i < 6; ++i) {
1422 printf("coeff[%u] = %f = %f\n", i, coeff[i], cvt_coeff[i]);
1423 }
1424 } else {
1425 switch (SDL_AUDIO_BITSIZE(format)) {
1426 case 8:
1427 debug_iir(Uint8);
1428 break;
1429 case 16:
1430 debug_iir(Uint16);
1431 break;
1432 case 32:
1433 debug_iir(Uint32);
1434 break;
1435 }
1436 }
1437 #undef debug_iir
1438 #endif
1439
1440 /* Initialize the state buffer to all zeroes, and set initial position */
1441 memset(cvt->state_buf, 0, 4 * SDL_AUDIO_BITSIZE(format) / 4);
1442 cvt->state_pos = 0;
1443 #undef convert_fixed
1444 }
1445
1446 /* Apply the lowpass IIR filter to the given SDL_AudioCVT struct */
1447 /* This was implemented because it would be much faster than the fir filter,
1448 but it doesn't seem to have a steep enough cutoff so we'd need several
1449 cascaded biquads, which probably isn't a great idea. Therefore, this
1450 function can probably be discarded.
1451 */
1452 static void
1453 SDL_FilterIIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1454 {
1455 Uint32 i, n;
1456
1457 /* TODO: Check that n is calculated right */
1458 n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
1459
1460 /* Note that the coefficients are 2_x and the input is 1_x. Do we need to shift left at the end here? The right shift temp = buf[n] >> 1 needs to depend on whether the type is signed or not for sign extension. */
1461 /* cvt->state_pos = 1: state[0] = x_n-1, state[1] = x_n-2, state[2] = y_n-1, state[3] - y_n-2 */
1462 #define iir_fix(type, mult) {\
1463 type *coeff = (type *)cvt->coeff; \
1464 type *state = (type *)cvt->state_buf; \
1465 type *buf = (type *)cvt->buf; \
1466 type temp; \
1467 for(i = 0; i < n; ++i) { \
1468 temp = buf[i] >> 1; \
1469 if(cvt->state_pos) { \
1470 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
1471 state[1] = temp; \
1472 state[3] = buf[i]; \
1473 cvt->state_pos = 0; \
1474 } else { \
1475 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[1]) + mult(coeff[2], state[0]) - mult(coeff[4], state[3]) - mult(coeff[5], state[2]); \
1476 state[0] = temp; \
1477 state[2] = buf[i]; \
1478 cvt->state_pos = 1; \
1479 } \
1480 } \
1481 }
1482 /* Need to test to see if the previous method or this one is faster */
1483 /*#define iir_fix(type, mult) {\
1484 type *coeff = (type *)cvt->coeff; \
1485 type *state = (type *)cvt->state_buf; \
1486 type *buf = (type *)cvt->buf; \
1487 type temp; \
1488 for(i = 0; i < n; ++i) { \
1489 temp = buf[i] >> 1; \
1490 buf[i] = mult(coeff[0], temp) + mult(coeff[1], state[0]) + mult(coeff[2], state[1]) - mult(coeff[4], state[2]) - mult(coeff[5], state[3]); \
1491 state[1] = state[0]; \
1492 state[0] = temp; \
1493 state[3] = state[2]; \
1494 state[2] = buf[i]; \
1495 } \
1496 }*/
1497
1498 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1499 float *coeff = (float *) cvt->coeff;
1500 float *state = (float *) cvt->state_buf;
1501 float *buf = (float *) cvt->buf;
1502 float temp;
1503
1504 for (i = 0; i < n; ++i) {
1505 /* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a[2] * y[n-2] */
1506 temp = buf[i];
1507 if (cvt->state_pos) {
1508 buf[i] =
1509 coeff[0] * buf[n] + coeff[1] * state[0] +
1510 coeff[2] * state[1] - coeff[4] * state[2] -
1511 coeff[5] * state[3];
1512 state[1] = temp;
1513 state[3] = buf[i];
1514 cvt->state_pos = 0;
1515 } else {
1516 buf[i] =
1517 coeff[0] * buf[n] + coeff[1] * state[1] +
1518 coeff[2] * state[0] - coeff[4] * state[3] -
1519 coeff[5] * state[2];
1520 state[0] = temp;
1521 state[2] = buf[i];
1522 cvt->state_pos = 1;
1523 }
1524 }
1525 } else {
1526 /* Treat everything as signed! */
1527 switch (SDL_AUDIO_BITSIZE(format)) {
1528 case 8:
1529 iir_fix(Sint8, SDL_FixMpy8);
1530 break;
1531 case 16:
1532 iir_fix(Sint16, SDL_FixMpy16);
1533 break;
1534 case 32:
1535 iir_fix(Sint32, SDL_FixMpy32);
1536 break;
1537 }
1538 }
1539 #undef iir_fix
1540 }
1541
1542 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct.
1543 */
1544 static void
1545 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1546 {
1547 int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
1548 int m = cvt->len_sinc;
1549 int i, j;
1550
1551 /*
1552 Note: We can make a big optimization here by taking advantage
1553 of the fact that the signal is zero stuffed, so we can do
1554 significantly fewer multiplications and additions. However, this
1555 depends on the zero stuffing ratio, so it may not pay off. This would
1556 basically be a polyphase filter.
1557 */
1558 /* One other way to do this fast is to look at the fir filter from a different angle:
1559 After we zero stuff, we have input of all zeroes, except for every len_mult
1560 sample. If we choose a sinc length equal to len_mult, then the fir filter becomes
1561 much more simple: we're just taking a windowed sinc, shifting it to start at each
1562 len_mult sample, and scaling it by the value of that sample. If we do this, then
1563 we don't even need to worry about the sample histories, and the inner loop here is
1564 unnecessary. This probably sacrifices some quality but could really speed things up as well.
1565 */
1566 /* We only calculate the values of samples which are 0 (mod len_div) because
1567 those are the only ones used. All the other ones are discarded in the
1568 third step of resampling. This is a huge speedup. As a warning, though,
1569 if for some reason this is used elsewhere where there are no samples discarded,
1570 the output will not be corrrect if len_div is not 1. To make this filter a
1571 generic FIR filter, simply remove the if statement "if(i % cvt->len_div == 0)"
1572 around the inner loop so that every sample is processed.
1573 */
1574 /* This is basically just a FIR filter. i.e. for input x_n and m coefficients,
1575 y_n = x_n*sinc_0 + x_(n-1)*sinc_1 + x_(n-2)*sinc_2 + ... + x_(n-m+1)*sinc_(m-1)
1576 */
1577 #define filter_sinc(type, mult) { \
1578 type *sinc = (type *)cvt->coeff; \
1579 type *state = (type *)cvt->state_buf; \
1580 type *buf = (type *)cvt->buf; \
1581 for(i = 0; i < n; ++i) { \
1582 state[cvt->state_pos] = buf[i]; \
1583 buf[i] = 0; \
1584 if( i % cvt->len_div == 0 ) { \
1585 for(j = 0; j < m; ++j) { \
1586 buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
1587 } \
1588 }\
1589 cvt->state_pos = (cvt->state_pos + 1) % m; \
1590 } \
1591 }
1592
1593 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1594 filter_sinc(float, SDL_FloatMpy);
1595 } else {
1596 switch (SDL_AUDIO_BITSIZE(format)) {
1597 case 8:
1598 filter_sinc(Sint8, SDL_FixMpy8);
1599 break;
1600 case 16:
1601 filter_sinc(Sint16, SDL_FixMpy16);
1602 break;
1603 case 32:
1604 filter_sinc(Sint32, SDL_FixMpy32);
1605 break;
1606 }
1607 }
1608
1609 #undef filter_sinc
1610
1611 }
1612
1613 /* Generate the necessary windowed sinc filter for resampling.
1614 Assume that the SDL_AudioCVT struct is already set up with
1615 the correct values for len_mult and len_div, and use the
1616 type of dst_format. Also assume the buffer is allocated.
1617 Note the buffer needs to be m+1 units long.
1618 */
1619 int
1620 SDL_BuildWindowedSinc(SDL_AudioCVT * cvt, SDL_AudioFormat format,
1621 unsigned int m)
1622 {
1623 float fScale; /* scale factor for fixed point */
1624 float *fSinc; /* floating point sinc buffer, to be converted to fixed point */
1625 float fc; /* cutoff frequency */
1626 float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two;
1627 float norm_sum, norm_fact;
1628 unsigned int i;
1629
1630 /* Check that the buffer is allocated */
1631 if (cvt->coeff == NULL) {
1632 return -1;
1633 }
1634
1635 /* Set the length */
1636 cvt->len_sinc = m + 1;
1637
1638 /* Allocate the floating point windowed sinc. */
1639 fSinc = (float *) malloc((m + 1) * sizeof(float));
1640 if (fSinc == NULL) {
1641 return -1;
1642 }
1643
1644 /* Set up the filter parameters */
1645 fc = (cvt->len_mult >
1646 cvt->len_div) ? 0.5f / (float) cvt->len_mult : 0.5f /
1647 (float) cvt->len_div;
1648 #ifdef DEBUG_CONVERT
1649 printf("Lowpass cutoff frequency = %f\n", fc);
1650 #endif
1651 two_pi_fc = 2.0f * M_PI * fc;
1652 two_pi_over_m = 2.0f * M_PI / (float) m;
1653 four_pi_over_m = 2.0f * two_pi_over_m;
1654 m_over_two = (float) m / 2.0f;
1655 norm_sum = 0.0f;
1656
1657 for (i = 0; i <= m; ++i) {
1658 if (i == m / 2) {
1659 fSinc[i] = two_pi_fc;
1660 } else {
1661 fSinc[i] =
1662 sinf(two_pi_fc * ((float) i - m_over_two)) / ((float) i -
1663 m_over_two);
1664 /* Apply blackman window */
1665 fSinc[i] *=
1666 0.42f - 0.5f * cosf(two_pi_over_m * (float) i) +
1667 0.08f * cosf(four_pi_over_m * (float) i);
1668 }
1669 norm_sum += fabs(fSinc[i]);
1670 }
1671
1672 norm_fact = 1.0f / norm_sum;
1673
1674 #define convert_fixed(type, fix) { \
1675 type *dst = (type *)cvt->coeff; \
1676 for( i = 0; i <= m; ++i ) { \
1677 dst[i] = fix(fSinc[i] * norm_fact); \
1678 } \
1679 }
1680
1681 /* If we're using floating point, we only need to normalize */
1682 if (SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
1683 float *fDest = (float *) cvt->coeff;
1684 for (i = 0; i <= m; ++i) {
1685 fDest[i] = fSinc[i] * norm_fact;
1686 }
1687 } else {
1688 switch (SDL_AUDIO_BITSIZE(format)) {
1689 case 8:
1690 convert_fixed(Uint8, SDL_Make_1_7);
1691 break;
1692 case 16:
1693 convert_fixed(Uint16, SDL_Make_1_15);
1694 break;
1695 case 32:
1696 convert_fixed(Uint32, SDL_Make_1_31);
1697 break;
1698 }
1699 }
1700
1701 /* Initialize the state buffer to all zeroes, and set initial position */
1702 memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
1703 cvt->state_pos = 0;
1704
1705 /* Clean up */
1706 #undef convert_fixed
1707 free(fSinc);
1708 }
1709
1710 /* This is used to reduce the resampling ratio */
1711 inline int
1712 SDL_GCD(int a, int b)
1713 {
1714 int temp;
1715 while (b != 0) {
1716 temp = a % b;
1717 a = b;
1718 b = temp;
1719 }
1720 return a;
1721 }
1722
1723 /* Perform proper resampling. This is pretty slow but it's the best-sounding method. */
1724 static void SDLCALL
1725 SDL_Resample(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1726 {
1727 int i, j;
1728
1729 #ifdef DEBUG_CONVERT
1730 printf("Converting audio rate via proper resampling (mono)\n");
1731 #endif
1732
1733 #define zerostuff_mono(type) { \
1734 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
1735 type *dst = (type *) (cvt->buf + (cvt->len_cvt * cvt->len_mult)); \
1736 for (i = cvt->len_cvt / sizeof (type); i; --i) { \
1737 src--; \
1738 dst[-1] = src[0]; \
1739 for( j = -cvt->len_mult; j < -1; ++j ) { \
1740 dst[j] = 0; \
1741 } \
1742 dst -= cvt->len_mult; \
1743 } \
1744 }
1745
1746 #define discard_mono(type) { \
1747 const type *src = (const type *) (cvt->buf); \
1748 type *dst = (type *) (cvt->buf); \
1749 for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
1750 dst[0] = src[0]; \
1751 src += cvt->len_div; \
1752 ++dst; \
1753 } \
1754 }
1755
1756 /* Step 1: Zero stuff the conversion buffer. This upsamples by a factor of len_mult,
1757 creating aliasing at frequencies above the original nyquist frequency.
1758 */
1759 #ifdef DEBUG_CONVERT
1760 printf("Zero-stuffing by a factor of %u\n", cvt->len_mult);
1761 #endif
1762 switch (SDL_AUDIO_BITSIZE(format)) {
1763 case 8:
1764 zerostuff_mono(Uint8);
1765 break;
1766 case 16:
1767 zerostuff_mono(Uint16);
1768 break;
1769 case 32:
1770 zerostuff_mono(Uint32);
1771 break;
1772 }
1773
1774 cvt->len_cvt *= cvt->len_mult;
1775
1776 /* Step 2: Use a windowed sinc FIR filter (lowpass filter) to remove the alias
1777 frequencies. This is the slow part.
1778 */
1779 SDL_FilterFIR(cvt, format);
1780
1781 /* Step 3: Now downsample by discarding samples. */
1782
1783 #ifdef DEBUG_CONVERT
1784 printf("Discarding samples by a factor of %u\n", cvt->len_div);
1785 #endif
1786 switch (SDL_AUDIO_BITSIZE(format)) {
1787 case 8:
1788 discard_mono(Uint8);
1789 break;
1790 case 16:
1791 discard_mono(Uint16);
1792 break;
1793 case 32:
1794 discard_mono(Uint32);
1795 break;
1796 }
1797
1798 #undef zerostuff_mono
1799 #undef discard_mono
1800
1801 cvt->len_cvt /= cvt->len_div;
1802
1803 if (cvt->filters[++cvt->filter_index]) {
1804 cvt->filters[cvt->filter_index] (cvt, format);
1805 }
1806 }
1312 1807
1313 1808
1314 /* Creates a set of audio filters to convert from one format to another. 1809 /* Creates a set of audio filters to convert from one format to another.
1315 Returns -1 if the format conversion is not supported, 0 if there's 1810 Returns -1 if the format conversion is not supported, 0 if there's
1316 no conversion needed, or 1 if the audio filter is set up. 1811 no conversion needed, or 1 if the audio filter is set up.
1397 /* Uh oh.. */ ; 1892 /* Uh oh.. */ ;
1398 } 1893 }
1399 } 1894 }
1400 1895
1401 /* Do rate conversion */ 1896 /* Do rate conversion */
1897 if (src_rate != dst_rate) {
1898 int rate_gcd;
1899 rate_gcd = SDL_GCD(src_rate, dst_rate);
1900 cvt->len_mult = dst_rate / rate_gcd;
1901 cvt->len_div = src_rate / rate_gcd;
1902 cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div;
1903 cvt->filters[cvt->filter_index++] = SDL_Resample;
1904 SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
1905 }
1906
1907 /*
1402 cvt->rate_incr = 0.0; 1908 cvt->rate_incr = 0.0;
1403 if ((src_rate / 100) != (dst_rate / 100)) { 1909 if ((src_rate / 100) != (dst_rate / 100)) {
1404 Uint32 hi_rate, lo_rate; 1910 Uint32 hi_rate, lo_rate;
1405 int len_mult; 1911 int len_mult;
1406 double len_ratio; 1912 double len_ratio;
1446 default: 1952 default:
1447 return -1; 1953 return -1;
1448 } 1954 }
1449 len_mult = 2; 1955 len_mult = 2;
1450 len_ratio = 2.0; 1956 len_ratio = 2.0;
1451 } 1957 }*/
1452 /* If hi_rate = lo_rate*2^x then conversion is easy */ 1958 /* If hi_rate = lo_rate*2^x then conversion is easy */
1453 while (((lo_rate * 2) / 100) <= (hi_rate / 100)) { 1959 /* while (((lo_rate * 2) / 100) <= (hi_rate / 100)) {
1454 cvt->filters[cvt->filter_index++] = rate_cvt; 1960 cvt->filters[cvt->filter_index++] = rate_cvt;
1455 cvt->len_mult *= len_mult; 1961 cvt->len_mult *= len_mult;
1456 lo_rate *= 2; 1962 lo_rate *= 2;
1457 cvt->len_ratio *= len_ratio; 1963 cvt->len_ratio *= len_ratio;
1458 } 1964 } */
1459 /* We may need a slow conversion here to finish up */ 1965 /* We may need a slow conversion here to finish up */
1460 if ((lo_rate / 100) != (hi_rate / 100)) { 1966 /* if ((lo_rate / 100) != (hi_rate / 100)) {
1461 #if 1 1967 #if 1 */
1462 /* The problem with this is that if the input buffer is 1968 /* The problem with this is that if the input buffer is
1463 say 1K, and the conversion rate is say 1.1, then the 1969 say 1K, and the conversion rate is say 1.1, then the
1464 output buffer is 1.1K, which may not be an acceptable 1970 output buffer is 1.1K, which may not be an acceptable
1465 buffer size for the audio driver (not a power of 2) 1971 buffer size for the audio driver (not a power of 2)
1466 */ 1972 */
1467 /* For now, punt and hope the rate distortion isn't great. 1973 /* For now, punt and hope the rate distortion isn't great.
1468 */ 1974 */
1469 #else 1975 /*#else
1470 if (src_rate < dst_rate) { 1976 if (src_rate < dst_rate) {
1471 cvt->rate_incr = (double) lo_rate / hi_rate; 1977 cvt->rate_incr = (double) lo_rate / hi_rate;
1472 cvt->len_mult *= 2; 1978 cvt->len_mult *= 2;
1473 cvt->len_ratio /= cvt->rate_incr; 1979 cvt->len_ratio /= cvt->rate_incr;
1474 } else { 1980 } else {
1476 cvt->len_ratio *= cvt->rate_incr; 1982 cvt->len_ratio *= cvt->rate_incr;
1477 } 1983 }
1478 cvt->filters[cvt->filter_index++] = SDL_RateSLOW; 1984 cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
1479 #endif 1985 #endif
1480 } 1986 }
1481 } 1987 }*/
1482 1988
1483 /* Set up the filter information */ 1989 /* Set up the filter information */
1484 if (cvt->filter_index != 0) { 1990 if (cvt->filter_index != 0) {
1485 cvt->needed = 1; 1991 cvt->needed = 1;
1486 cvt->src_format = src_fmt; 1992 cvt->src_format = src_fmt;
1490 cvt->filters[cvt->filter_index] = NULL; 1996 cvt->filters[cvt->filter_index] = NULL;
1491 } 1997 }
1492 return (cvt->needed); 1998 return (cvt->needed);
1493 } 1999 }
1494 2000
2001 #undef SDL_FixMpy8
2002 #undef SDL_FixMpy16
2003 #undef SDL_FixMpy32
2004 #undef SDL_FloatMpy
2005 #undef SDL_Make_1_7
2006 #undef SDL_Make_1_15
2007 #undef SDL_Make_1_31
2008 #undef SDL_Make_2_6
2009 #undef SDL_Make_2_14
2010 #undef SDL_Make_2_30
2011
1495 /* vi: set ts=4 sw=4 expandtab: */ 2012 /* vi: set ts=4 sw=4 expandtab: */