Mercurial > sdl-ios-xcode
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; |