src/audio/SDL_audiocvt.c
branchgsoc2008_audio_resampling
changeset 2662 5470680ca587
parent 2661 d38309be5178
child 2663 0caed045d01b
equal deleted inserted replaced
2661:d38309be5178 2662:5470680ca587
  1534 	   Note: We can 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. However, this
  1536 	   significantly fewer multiplications and additions. However, this
  1537 	   depends on the zero stuffing ratio, so it may not pay off.
  1537 	   depends on the zero stuffing ratio, so it may not pay off.
  1538 	*/
  1538 	*/
       
  1539 	/* We only calculate the values of samples which are 0 (mod len_div) because those are the only ones used */
  1539 #define filter_sinc(type, mult) { \
  1540 #define filter_sinc(type, mult) { \
  1540 			type *sinc = (type *)cvt->coeff; \
  1541 			type *sinc = (type *)cvt->coeff; \
  1541 			type *state = (type *)cvt->state_buf; \
  1542 			type *state = (type *)cvt->state_buf; \
  1542 			type *buf = (type *)cvt->buf; \
  1543 			type *buf = (type *)cvt->buf; \
  1543 			for(i = 0; i < n; ++i) { \
  1544 			for(i = 0; i < n; ++i) { \
  1544 				state[cvt->state_pos] = buf[i]; \
  1545 				state[cvt->state_pos] = buf[i]; \
  1545 				buf[i] = 0; \
  1546 				buf[i] = 0; \
  1546 				for(j = 0; j < m;  ++j) { \
  1547 				if( i % cvt->len_div == 0 ) { \
  1547 					buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
  1548 					for(j = 0; j < m;  ++j) { \
  1548 				} \
  1549 						buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
       
  1550 					} \
       
  1551 				}\
  1549 				cvt->state_pos = (cvt->state_pos + 1) % m; \
  1552 				cvt->state_pos = (cvt->state_pos + 1) % m; \
  1550 			} \
  1553 			} \
  1551 		}
  1554 		}
  1552 	
  1555 	
  1553 	/* If it's floating point, do it normally, otherwise used fixed-point code */
  1556 	/* If it's floating point, do it normally, otherwise used fixed-point code */
  1614 	/* Set up the filter parameters */
  1617 	/* 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;
  1618 	fc = (cvt->len_mult > cvt->len_div) ? 0.5f / (float)cvt->len_mult : 0.5f / (float)cvt->len_div;
  1616 #ifdef DEBUG_CONVERT
  1619 #ifdef DEBUG_CONVERT
  1617 	printf("Lowpass cutoff frequency = %f\n", fc);
  1620 	printf("Lowpass cutoff frequency = %f\n", fc);
  1618 #endif
  1621 #endif
  1619 //	fc = 0.02f;
       
  1620 	two_pi_fc = 2.0f * M_PI * fc;
  1622 	two_pi_fc = 2.0f * M_PI * fc;
  1621 	two_pi_over_m = 2.0f * M_PI / (float)m;
  1623 	two_pi_over_m = 2.0f * M_PI / (float)m;
  1622 	four_pi_over_m = 2.0f * two_pi_over_m;
  1624 	four_pi_over_m = 2.0f * two_pi_over_m;
  1623 	m_over_two = (float)m / 2.0f;
  1625 	m_over_two = (float)m / 2.0f;
  1624 	norm_sum = 0.0f;
  1626 	norm_sum = 0.0f;
  1633 		}
  1635 		}
  1634 		norm_sum += fabs(fSinc[i]);
  1636 		norm_sum += fabs(fSinc[i]);
  1635 	}
  1637 	}
  1636 		
  1638 		
  1637 #define convert_fixed(type, fix) { \
  1639 #define convert_fixed(type, fix) { \
  1638 		norm_fact = 0.7f / norm_sum; \
  1640 		norm_fact = 0.5f / norm_sum; \
  1639 		type *dst = (type *)cvt->coeff; \
  1641 		type *dst = (type *)cvt->coeff; \
  1640 		for( i = 0; i <= m; ++i ) { \
  1642 		for( i = 0; i <= m; ++i ) { \
  1641 			dst[i] = fix(fSinc[i] * norm_fact); \
  1643 			dst[i] = fix(fSinc[i] * norm_fact); \
  1642 		} \
  1644 		} \
  1643 	}
  1645 	}
  1707     }
  1709     }
  1708 	
  1710 	
  1709 #define discard_mono(type) { \
  1711 #define discard_mono(type) { \
  1710         const type *src = (const type *) (cvt->buf); \
  1712         const type *src = (const type *) (cvt->buf); \
  1711         type *dst = (type *) (cvt->buf); \
  1713         type *dst = (type *) (cvt->buf); \
  1712         for (i = 0; i < cvt->len_cvt / cvt->len_div / sizeof (type); ++i) { \
  1714         for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
  1713             dst[0] = src[0]; \
  1715             dst[0] = src[0]; \
  1714             src += cvt->len_div; \
  1716             src += cvt->len_div; \
  1715             ++dst; \
  1717             ++dst; \
  1716         } \
  1718         } \
  1717     }
  1719     }
  1733     }
  1735     }
  1734 	
  1736 	
  1735 	cvt->len_cvt *= cvt->len_mult;
  1737 	cvt->len_cvt *= cvt->len_mult;
  1736 
  1738 
  1737 	// Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies
  1739 	// Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies
  1738 	SDL_FilterFIR( cvt, format );
  1740 	QSDL_FilterFIR( cvt, format );
       
  1741 	
       
  1742 	// OPTIMIZATION: we only need to calculate the non-discarded samples. This could be a big speedup!
  1739 	
  1743 	
  1740 	// Step 3: Discard unnecessary samples
  1744 	// Step 3: Discard unnecessary samples
       
  1745 
  1741 #ifdef DEBUG_CONVERT
  1746 #ifdef DEBUG_CONVERT
  1742 	printf("Discarding samples by a factor of %u\n", cvt->len_div);
  1747 	printf("Discarding samples by a factor of %u\n", cvt->len_div);
  1743 #endif
  1748 #endif
  1744     switch (SDL_AUDIO_BITSIZE(format)) {
  1749     switch (SDL_AUDIO_BITSIZE(format)) {
  1745     case 8:
  1750     case 8:
  1857 	cvt->len_mult = dst_rate / rate_gcd;
  1862 	cvt->len_mult = dst_rate / rate_gcd;
  1858 	cvt->len_div = src_rate / rate_gcd;
  1863 	cvt->len_div = src_rate / rate_gcd;
  1859 	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
  1864 	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
  1860 	cvt->filters[cvt->filter_index++] = SDL_Resample;
  1865 	cvt->filters[cvt->filter_index++] = SDL_Resample;
  1861 	//SDL_BuildIIRLowpass(cvt, dst_fmt);
  1866 	//SDL_BuildIIRLowpass(cvt, dst_fmt);
  1862 	SDL_BuildWindowedSinc(cvt, dst_fmt, 20);
  1867 	SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
  1863 	
  1868 	
  1864     /*cvt->rate_incr = 0.0;
  1869     /*cvt->rate_incr = 0.0;
  1865     if ((src_rate / 100) != (dst_rate / 100)) {
  1870     if ((src_rate / 100) != (dst_rate / 100)) {
  1866         Uint32 hi_rate, lo_rate;
  1871         Uint32 hi_rate, lo_rate;
  1867         int len_mult;
  1872         int len_mult;