comparison src/audio/SDL_audiocvt.c @ 2881:c8d203ef4335

More resampling fixes.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 19 Dec 2008 09:15:59 +0000
parents 3c2f56e433a8
children 11626a53e7bc
comparison
equal deleted inserted replaced
2880:3c2f56e433a8 2881:c8d203ef4335
1547 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct. 1547 /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct.
1548 */ 1548 */
1549 static void 1549 static void
1550 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format) 1550 SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format)
1551 { 1551 {
1552 int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format); 1552 /* !!! FIXME: (n) is incorrect, or my allocation of state_buf is wrong. */
1553 const int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
1553 int m = cvt->len_sinc; 1554 int m = cvt->len_sinc;
1554 int i, j; 1555 int i, j;
1555 1556
1556 /* 1557 /*
1557 Note: We can make a big optimization here by taking advantage 1558 Note: We can make a big optimization here by taking advantage
1629 float fc; /* cutoff frequency */ 1630 float fc; /* cutoff frequency */
1630 float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two; 1631 float two_pi_fc, two_pi_over_m, four_pi_over_m, m_over_two;
1631 float norm_sum, norm_fact; 1632 float norm_sum, norm_fact;
1632 unsigned int i; 1633 unsigned int i;
1633 1634
1634 /* Check that the buffer is allocated */
1635 if (cvt->coeff == NULL) {
1636 return -1;
1637 }
1638
1639 /* Set the length */ 1635 /* Set the length */
1640 cvt->len_sinc = m + 1; 1636 cvt->len_sinc = m + 1;
1641 1637
1642 /* Allocate the floating point windowed sinc. */ 1638 /* Allocate the floating point windowed sinc. */
1643 fSinc = SDL_stack_alloc(float, (m + 1)); 1639 fSinc = SDL_stack_alloc(float, (m + 1));
1681 dst[i] = fix(fSinc[i] * norm_fact); \ 1677 dst[i] = fix(fSinc[i] * norm_fact); \
1682 } \ 1678 } \
1683 } 1679 }
1684 1680
1685 /* !!! FIXME: this memory leaks. */ 1681 /* !!! FIXME: this memory leaks. */
1686 cvt->coeff = (Uint8 *) SDL_malloc((SDL_AUDIO_BITSIZE(format) / 8) * m); 1682 cvt->coeff = (Uint8 *) SDL_malloc((SDL_AUDIO_BITSIZE(format) / 8) * (m+1));
1687 if (cvt->coeff == NULL) { 1683 if (cvt->coeff == NULL) {
1688 return -1; 1684 return -1;
1689 } 1685 }
1690 1686
1691 /* If we're using floating point, we only need to normalize */ 1687 /* If we're using floating point, we only need to normalize */
1707 break; 1703 break;
1708 } 1704 }
1709 } 1705 }
1710 1706
1711 /* Initialize the state buffer to all zeroes, and set initial position */ 1707 /* Initialize the state buffer to all zeroes, and set initial position */
1708 /* !!! FIXME: this memory leaks. */
1709 cvt->state_buf = (Uint8 *) SDL_malloc(cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
1710 if (cvt->state_buf == NULL) {
1711 return -1;
1712 }
1712 SDL_memset(cvt->state_buf, 0, 1713 SDL_memset(cvt->state_buf, 0,
1713 cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4); 1714 cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
1714 cvt->state_pos = 0; 1715 cvt->state_pos = 0;
1715 1716
1716 /* Clean up */ 1717 /* Clean up */
1742 #ifdef DEBUG_CONVERT 1743 #ifdef DEBUG_CONVERT
1743 printf("Converting audio rate via proper resampling (mono)\n"); 1744 printf("Converting audio rate via proper resampling (mono)\n");
1744 #endif 1745 #endif
1745 1746
1746 #define zerostuff_mono(type) { \ 1747 #define zerostuff_mono(type) { \
1747 const type *src = (const type *) (cvt->buf + cvt->len_cvt); \ 1748 const type *src = (const type *) (cvt->buf + cvt->len); \
1748 type *dst = (type *) (cvt->buf + (cvt->len_cvt * cvt->len_mult)); \ 1749 type *dst = (type *) (cvt->buf + (cvt->len * cvt->len_mult)); \
1749 for (i = cvt->len_cvt / sizeof (type); i; --i) { \ 1750 for (i = cvt->len / sizeof (type); i; --i) { \
1750 src--; \ 1751 src--; \
1751 dst[-1] = src[0]; \ 1752 dst[-1] = src[0]; \
1752 for( j = -cvt->len_mult; j < -1; ++j ) { \ 1753 for( j = -cvt->len_mult; j < -1; ++j ) { \
1753 dst[j] = 0; \ 1754 dst[j] = 0; \
1754 } \ 1755 } \
1912 rate_gcd = SDL_GCD(src_rate, dst_rate); 1913 rate_gcd = SDL_GCD(src_rate, dst_rate);
1913 cvt->len_mult = dst_rate / rate_gcd; 1914 cvt->len_mult = dst_rate / rate_gcd;
1914 cvt->len_div = src_rate / rate_gcd; 1915 cvt->len_div = src_rate / rate_gcd;
1915 cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div; 1916 cvt->len_ratio = (double) cvt->len_mult / (double) cvt->len_div;
1916 cvt->filters[cvt->filter_index++] = SDL_Resample; 1917 cvt->filters[cvt->filter_index++] = SDL_Resample;
1918 /* !!! FIXME: check return value. */
1917 SDL_BuildWindowedSinc(cvt, dst_fmt, 768); 1919 SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
1918 } 1920 }
1919 1921
1920 /* 1922 /*
1921 cvt->rate_incr = 0.0; 1923 cvt->rate_incr = 0.0;