src/audio/SDL_audiocvt.c
branchgsoc2008_audio_resampling
changeset 2661 d38309be5178
parent 2660 a55543cef395
child 2662 5470680ca587
equal deleted inserted replaced
2660:a55543cef395 2661:d38309be5178
  1528 static void SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format) {
  1528 static void SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format) {
  1529 	int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
  1529 	int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
  1530 	int m = cvt->len_sinc;
  1530 	int m = cvt->len_sinc;
  1531 	int i, j;
  1531 	int i, j;
  1532 				
  1532 				
  1533 	/* Note: this makes use of the symmetry of the sinc filter.
  1533 	/* 
  1534 	   We can also make a big optimization here by taking advantage
  1534 	   Note: We can make a big optimization here by taking advantage
  1535 	   of the fact that the signal is zero stuffed, so we can do
  1535 	   of the fact that the signal is zero stuffed, so we can do
  1536 	   significantly fewer multiplications and additions.
  1536 	   significantly fewer multiplications and additions. However, this
       
  1537 	   depends on the zero stuffing ratio, so it may not pay off.
  1537 	*/
  1538 	*/
  1538 #define filter_sinc(type, mult) { \
  1539 #define filter_sinc(type, mult) { \
  1539 			type *sinc = (type *)cvt->coeff; \
  1540 			type *sinc = (type *)cvt->coeff; \
  1540 			type *state = (type *)cvt->state_buf; \
  1541 			type *state = (type *)cvt->state_buf; \
  1541 			type *buf = (type *)cvt->buf; \
  1542 			type *buf = (type *)cvt->buf; \
  1542 			for(i = 0; i < n; ++i) { \
  1543 			for(i = 0; i < n; ++i) { \
  1543 				cvt->state_pos++; \
       
  1544 				if(cvt->state_pos >= m) cvt->state_pos = 0; \
       
  1545 				state[cvt->state_pos] = buf[i]; \
  1544 				state[cvt->state_pos] = buf[i]; \
  1546 				buf[i] = 0; \
  1545 				buf[i] = 0; \
  1547 				for(j = 0; j < m;  ++j) { \
  1546 				for(j = 0; j < m;  ++j) { \
  1548 					buf[i] += mult(state[(cvt->state_pos - j) % m], sinc[j]); \
  1547 					buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
  1549 				} \
  1548 				} \
       
  1549 				cvt->state_pos = (cvt->state_pos + 1) % m; \
  1550 			} \
  1550 			} \
  1551 		}
  1551 		}
  1552 	
  1552 	
  1553 	/* If it's floating point, do it normally, otherwise used fixed-point code */
  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;
       
  1562 			buf[i] = 0.0f;
  1561 			buf[i] = 0.0f;
  1563 			for(j = 0; j < m; ++j) {
  1562 			for(j = 0; j < m; ++j) {
  1564 				buf[i] += state[(cvt->state_pos - j) % m] * sinc[j];
  1563 				buf[i] += sinc[j] * state[(cvt->state_pos + j) % m];
  1565 			}
  1564 			}
       
  1565 			cvt->state_pos = (cvt->state_pos + 1) % m;
  1566 		}
  1566 		}
  1567 	} else {
  1567 	} else {
  1568 		switch (SDL_AUDIO_BITSIZE(format)) {
  1568 		switch (SDL_AUDIO_BITSIZE(format)) {
  1569 			case 8:
  1569 			case 8:
  1570 				filter_sinc(Sint8, SDL_FixMpy8);
  1570 				filter_sinc(Sint8, SDL_FixMpy8);
  1611 		return -1;
  1611 		return -1;
  1612 	}
  1612 	}
  1613 	
  1613 	
  1614 	/* Set up the filter parameters */
  1614 	/* Set up the filter parameters */
  1615 	fc = (cvt->len_mult > cvt->len_div) ? 0.5f / (float)cvt->len_mult : 0.5f / (float)cvt->len_div;
  1615 	fc = (cvt->len_mult > cvt->len_div) ? 0.5f / (float)cvt->len_mult : 0.5f / (float)cvt->len_div;
  1616 	fc = 0.04f;
  1616 #ifdef DEBUG_CONVERT
       
  1617 	printf("Lowpass cutoff frequency = %f\n", fc);
       
  1618 #endif
       
  1619 //	fc = 0.02f;
  1617 	two_pi_fc = 2.0f * M_PI * fc;
  1620 	two_pi_fc = 2.0f * M_PI * fc;
  1618 	two_pi_over_m = 2.0f * M_PI / (float)m;
  1621 	two_pi_over_m = 2.0f * M_PI / (float)m;
  1619 	four_pi_over_m = 2.0f * two_pi_over_m;
  1622 	four_pi_over_m = 2.0f * two_pi_over_m;
  1620 	m_over_two = (float)m / 2.0f;
  1623 	m_over_two = (float)m / 2.0f;
  1621 	norm_sum = 0.0f;
  1624 	norm_sum = 0.0f;
  1626 		} else {
  1629 		} else {
  1627 			fSinc[i] = sinf(two_pi_fc * ((float)i - m_over_two)) / ((float)i - m_over_two);
  1630 			fSinc[i] = sinf(two_pi_fc * ((float)i - m_over_two)) / ((float)i - m_over_two);
  1628 			/* Apply blackman window */
  1631 			/* 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);
  1632 			fSinc[i] *= 0.42f - 0.5f * cosf(two_pi_over_m * (float)i) + 0.08f * cosf(four_pi_over_m * (float)i);
  1630 		}
  1633 		}
  1631 		fSinc[i] = 0.0f;
       
  1632 		norm_sum += fabs(fSinc[i]);
  1634 		norm_sum += fabs(fSinc[i]);
  1633 		printf("%f\n", fSinc[i]);
       
  1634 	}
  1635 	}
  1635 		
  1636 		
  1636 #define convert_fixed(type, fix) { \
  1637 #define convert_fixed(type, fix) { \
  1637 		norm_fact = 0.8f / norm_sum; \
  1638 		norm_fact = 0.7f / norm_sum; \
  1638 		type *dst = (type *)cvt->coeff; \
  1639 		type *dst = (type *)cvt->coeff; \
  1639 		for( i = 0; i <= m; ++i ) { \
  1640 		for( i = 0; i <= m; ++i ) { \
  1640 			dst[i] = fix(fSinc[i] * norm_fact); \
  1641 			dst[i] = fix(fSinc[i] * norm_fact); \
  1641 			printf("%f = 0x%x\n", fSinc[i] * norm_fact, dst[i]); \
       
  1642 		} \
  1642 		} \
  1643 	}
  1643 	}
  1644 	
  1644 	
  1645 	/* If we're using floating point, we only need to normalize */
  1645 	/* If we're using floating point, we only need to normalize */
  1646 	if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1646 	if(SDL_AUDIO_ISFLOAT(format) && SDL_AUDIO_BITSIZE(format) == 32) {
  1662 				break;
  1662 				break;
  1663 		}
  1663 		}
  1664 	}
  1664 	}
  1665 	
  1665 	
  1666 	/* Initialize the state buffer to all zeroes, and set initial position */
  1666 	/* Initialize the state buffer to all zeroes, and set initial position */
  1667 	//memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
  1667 	memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
  1668 	cvt->state_pos = 0;
  1668 	cvt->state_pos = 0;
  1669 	
  1669 	
  1670 	/* Clean up */
  1670 	/* Clean up */
  1671 #undef convert_fixed
  1671 #undef convert_fixed
  1672 	free(fSinc);
  1672 	free(fSinc);
  1715             ++dst; \
  1715             ++dst; \
  1716         } \
  1716         } \
  1717     }
  1717     }
  1718 
  1718 
  1719 	// Step 1: Zero stuff the conversion buffer
  1719 	// Step 1: Zero stuff the conversion buffer
  1720 /*#ifdef DEBUG_CONVERT
  1720 #ifdef DEBUG_CONVERT
  1721 	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);
  1722 #endif
  1722 #endif
  1723     switch (SDL_AUDIO_BITSIZE(format)) {
  1723     switch (SDL_AUDIO_BITSIZE(format)) {
  1724     case 8:
  1724     case 8:
  1725         zerostuff_mono(Uint8);
  1725         zerostuff_mono(Uint8);
  1730     case 32:
  1730     case 32:
  1731         zerostuff_mono(Uint32);
  1731         zerostuff_mono(Uint32);
  1732         break;
  1732         break;
  1733     }
  1733     }
  1734 	
  1734 	
  1735 	cvt->len_cvt *= cvt->len_mult;*/
  1735 	cvt->len_cvt *= cvt->len_mult;
  1736 
  1736 
  1737 	// 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
  1738 	SDL_FilterFIR( cvt, format );
  1738 	SDL_FilterFIR( cvt, format );
  1739 	
  1739 	
  1740 	// Step 3: Discard unnecessary samples
  1740 	// Step 3: Discard unnecessary samples
  1741 /*#ifdef DEBUG_CONVERT
  1741 #ifdef DEBUG_CONVERT
  1742 	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);
  1743 #endif
  1743 #endif
  1744     switch (SDL_AUDIO_BITSIZE(format)) {
  1744     switch (SDL_AUDIO_BITSIZE(format)) {
  1745     case 8:
  1745     case 8:
  1746         discard_mono(Uint8);
  1746         discard_mono(Uint8);
  1754     }
  1754     }
  1755 	
  1755 	
  1756 #undef zerostuff_mono
  1756 #undef zerostuff_mono
  1757 #undef discard_mono
  1757 #undef discard_mono
  1758 
  1758 
  1759     cvt->len_cvt /= cvt->len_div;*/
  1759     cvt->len_cvt /= cvt->len_div;
  1760 	
  1760 	
  1761     if (cvt->filters[++cvt->filter_index]) {
  1761     if (cvt->filters[++cvt->filter_index]) {
  1762         cvt->filters[cvt->filter_index] (cvt, format);
  1762         cvt->filters[cvt->filter_index] (cvt, format);
  1763     }
  1763     }
  1764 }
  1764 }
  1857 	cvt->len_mult = dst_rate / rate_gcd;
  1857 	cvt->len_mult = dst_rate / rate_gcd;
  1858 	cvt->len_div = src_rate / rate_gcd;
  1858 	cvt->len_div = src_rate / rate_gcd;
  1859 	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
  1859 	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
  1860 	cvt->filters[cvt->filter_index++] = SDL_Resample;
  1860 	cvt->filters[cvt->filter_index++] = SDL_Resample;
  1861 	//SDL_BuildIIRLowpass(cvt, dst_fmt);
  1861 	//SDL_BuildIIRLowpass(cvt, dst_fmt);
  1862 	SDL_BuildWindowedSinc(cvt, dst_fmt, 12);
  1862 	SDL_BuildWindowedSinc(cvt, dst_fmt, 20);
  1863 	
  1863 	
  1864     /*cvt->rate_incr = 0.0;
  1864     /*cvt->rate_incr = 0.0;
  1865     if ((src_rate / 100) != (dst_rate / 100)) {
  1865     if ((src_rate / 100) != (dst_rate / 100)) {
  1866         Uint32 hi_rate, lo_rate;
  1866         Uint32 hi_rate, lo_rate;
  1867         int len_mult;
  1867         int len_mult;