src/audio/SDL_audiocvt.c
changeset 2881 c8d203ef4335
parent 2880 3c2f56e433a8
child 2883 11626a53e7bc
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;