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 }