Mercurial > sdl-ios-xcode
comparison src/audio/SDL_audiocvt.c @ 2660:a55543cef395 gsoc2008_audio_resampling
Cleaned up some bugs, but the FIR filter is still distorting.
author | Aaron Wishnick <schnarf@gmail.com> |
---|---|
date | Wed, 02 Jul 2008 07:25:02 +0000 |
parents | 8da698bc1205 |
children | d38309be5178 |
comparison
equal
deleted
inserted
replaced
2659:8da698bc1205 | 2660:a55543cef395 |
---|---|
1548 buf[i] += mult(state[(cvt->state_pos - j) % m], sinc[j]); \ | 1548 buf[i] += mult(state[(cvt->state_pos - j) % m], sinc[j]); \ |
1549 } \ | 1549 } \ |
1550 } \ | 1550 } \ |
1551 } | 1551 } |
1552 | 1552 |
1553 /* If it's floating point, we don't need to do any shifting */ | 1553 /* If it's floating point, do it normally, otherwise used fixed-point code */ |
1554 if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) { | 1554 if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) { |
1555 float *sinc = (float *)cvt->coeff; | 1555 float *sinc = (float *)cvt->coeff; |
1556 float *state = (float *)cvt->state_buf; | 1556 float *state = (float *)cvt->state_buf; |
1557 float *buf = (float *)cvt->buf; | 1557 float *buf = (float *)cvt->buf; |
1558 | 1558 |
1559 for(i = 0; i < n; ++i) { | 1559 for(i = 0; i < n; ++i) { |
1560 state[cvt->state_pos++] = buf[i]; | 1560 state[cvt->state_pos++] = buf[i]; |
1561 if(cvt->state_pos == m) cvt->state_pos = 0; | 1561 if(cvt->state_pos == m) cvt->state_pos = 0; |
1562 buf[i] = 0.0f; | 1562 buf[i] = 0.0f; |
1563 for(j = 0; j < m; ++j) { | 1563 for(j = 0; j < m; ++j) { |
1564 buf[i] += state[j] * sinc[j]; | 1564 buf[i] += state[(cvt->state_pos - j) % m] * sinc[j]; |
1565 } | 1565 } |
1566 } | 1566 } |
1567 } else { | 1567 } else { |
1568 switch (SDL_AUDIO_BITSIZE(format)) { | 1568 switch (SDL_AUDIO_BITSIZE(format)) { |
1569 case 8: | 1569 case 8: |
1626 } else { | 1626 } else { |
1627 fSinc[i] = sinf(two_pi_fc * ((float)i - m_over_two)) / ((float)i - m_over_two); | 1627 fSinc[i] = sinf(two_pi_fc * ((float)i - m_over_two)) / ((float)i - m_over_two); |
1628 /* Apply blackman window */ | 1628 /* Apply blackman window */ |
1629 fSinc[i] *= 0.42f - 0.5f * cosf(two_pi_over_m * (float)i) + 0.08f * cosf(four_pi_over_m * (float)i); | 1629 fSinc[i] *= 0.42f - 0.5f * cosf(two_pi_over_m * (float)i) + 0.08f * cosf(four_pi_over_m * (float)i); |
1630 } | 1630 } |
1631 norm_sum += abs(fSinc[i]); | 1631 fSinc[i] = 0.0f; |
1632 norm_sum += fabs(fSinc[i]); | |
1632 printf("%f\n", fSinc[i]); | 1633 printf("%f\n", fSinc[i]); |
1633 } | 1634 } |
1634 | 1635 |
1635 /* Now normalize and convert to fixed point. We scale everything to half the precision | |
1636 of whatever datatype we're using, for example, 16 bit data means we use 8 bits */ | |
1637 | |
1638 #define convert_fixed(type, fix) { \ | 1636 #define convert_fixed(type, fix) { \ |
1639 norm_fact = 0.9f / norm_sum; \ | 1637 norm_fact = 0.8f / norm_sum; \ |
1640 norm_fact = 0.15f; \ | |
1641 type *dst = (type *)cvt->coeff; \ | 1638 type *dst = (type *)cvt->coeff; \ |
1642 for( i = 0; i <= m; ++i ) { \ | 1639 for( i = 0; i <= m; ++i ) { \ |
1643 dst[i] = fix(fSinc[i] * norm_fact); \ | 1640 dst[i] = fix(fSinc[i] * norm_fact); \ |
1644 printf("%f = 0x%x\n", fSinc[i], dst[i]); \ | 1641 printf("%f = 0x%x\n", fSinc[i] * norm_fact, dst[i]); \ |
1645 } \ | 1642 } \ |
1646 } | 1643 } |
1647 | 1644 |
1648 /* If we're using floating point, we only need to normalize */ | 1645 /* If we're using floating point, we only need to normalize */ |
1649 if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) { | 1646 if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) { |
1718 ++dst; \ | 1715 ++dst; \ |
1719 } \ | 1716 } \ |
1720 } | 1717 } |
1721 | 1718 |
1722 // Step 1: Zero stuff the conversion buffer | 1719 // Step 1: Zero stuff the conversion buffer |
1723 #ifdef DEBUG_CONVERT | 1720 /*#ifdef DEBUG_CONVERT |
1724 printf("Zero-stuffing by a factor of %u\n", cvt->len_mult); | 1721 printf("Zero-stuffing by a factor of %u\n", cvt->len_mult); |
1725 #endif | 1722 #endif |
1726 switch (SDL_AUDIO_BITSIZE(format)) { | 1723 switch (SDL_AUDIO_BITSIZE(format)) { |
1727 case 8: | 1724 case 8: |
1728 zerostuff_mono(Uint8); | 1725 zerostuff_mono(Uint8); |
1733 case 32: | 1730 case 32: |
1734 zerostuff_mono(Uint32); | 1731 zerostuff_mono(Uint32); |
1735 break; | 1732 break; |
1736 } | 1733 } |
1737 | 1734 |
1738 cvt->len_cvt *= cvt->len_mult; | 1735 cvt->len_cvt *= cvt->len_mult;*/ |
1739 | 1736 |
1740 // Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies | 1737 // Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies |
1741 SDL_FilterFIR( cvt, format ); | 1738 SDL_FilterFIR( cvt, format ); |
1742 | 1739 |
1743 // Step 3: Discard unnecessary samples | 1740 // Step 3: Discard unnecessary samples |
1744 #ifdef DEBUG_CONVERT | 1741 /*#ifdef DEBUG_CONVERT |
1745 printf("Discarding samples by a factor of %u\n", cvt->len_div); | 1742 printf("Discarding samples by a factor of %u\n", cvt->len_div); |
1746 #endif | 1743 #endif |
1747 switch (SDL_AUDIO_BITSIZE(format)) { | 1744 switch (SDL_AUDIO_BITSIZE(format)) { |
1748 case 8: | 1745 case 8: |
1749 discard_mono(Uint8); | 1746 discard_mono(Uint8); |
1757 } | 1754 } |
1758 | 1755 |
1759 #undef zerostuff_mono | 1756 #undef zerostuff_mono |
1760 #undef discard_mono | 1757 #undef discard_mono |
1761 | 1758 |
1762 cvt->len_cvt /= cvt->len_div; | 1759 cvt->len_cvt /= cvt->len_div;*/ |
1763 | 1760 |
1764 if (cvt->filters[++cvt->filter_index]) { | 1761 if (cvt->filters[++cvt->filter_index]) { |
1765 cvt->filters[cvt->filter_index] (cvt, format); | 1762 cvt->filters[cvt->filter_index] (cvt, format); |
1766 } | 1763 } |
1767 } | 1764 } |