⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sample_rate_converter.c

📁 Minix比较全的源码
💻 C
字号:
#include "sample_rate_converter.h"#define SRC_RATE        48000U#define reg(n) DSP->base + n/* register/base and control equates for the SRC RAM */#define SRC_SYNTH_FIFO      0x00#define SRC_DAC_FIFO        0x20#define SRC_ADC_FIFO        0x40#define SRC_SYNTH_LVOL      0x7c#define SRC_SYNTH_RVOL      0x7d#define SRC_DAC_LVOL        0x7e#define SRC_DAC_RVOL        0x7f#define SRC_ADC_LVOL        0x6c#define SRC_ADC_RVOL        0x6d#define SRC_TRUNC_N_OFF     0x00#define SRC_INT_REGS_OFF    0x01#define SRC_ACCUM_FRAC_OFF  0x02#define SRC_VFREQ_FRAC_OFF  0x03/* miscellaneous control defines */#define SRC_IOPOLL_COUNT    0x1000UL#define SRC_SYNTHFREEZE     (1UL << 21)#define SRC_DACFREEZE       (1UL << 20)#define SRC_ADCFREEZE       (1UL << 19)FORWARD _PROTOTYPE( int src_reg_read, (DEV_STRUCT * DSP, 			u16_t reg, u16_t *data) );FORWARD _PROTOTYPE( int src_reg_write, (DEV_STRUCT * DSP, 			u16_t reg, u16_t val) );int src_init ( DEV_STRUCT * DSP ) {	u32_t   i;	int     retVal;	/* Clear all SRC RAM then init - keep SRC disabled until done */	/* Wait till SRC_RAM_BUSY is 0 */	if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))		return (SRC_ERR_NOT_BUSY_TIMEOUT);	pci_outl(reg(SAMPLE_RATE_CONV), SRC_DISABLE);	/* from the opensound system driver, no idea where the specification is */	/* there are indeed 7 bits for the addresses of the SRC */	for( i = 0; i < 0x80; ++i ) {		if (SRC_SUCCESS != (retVal = src_reg_write(DSP, (u16_t)i, 0U)))			return (retVal);	}	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_SYNTH_BASE + SRC_TRUNC_N_OFF, 16 << 4)))		return (retVal);	if (SRC_SUCCESS != (retVal = src_reg_write(DSP, 					SRC_SYNTH_BASE + SRC_INT_REGS_OFF, 16 << 10)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_DAC_BASE + SRC_TRUNC_N_OFF, 16 << 4)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_DAC_BASE + SRC_INT_REGS_OFF, 16 << 10)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_SYNTH_LVOL, 1 << 12)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_SYNTH_RVOL, 1 << 12)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_DAC_LVOL, 1 << 12)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_DAC_RVOL, 1 << 12)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_ADC_LVOL, 1 << 12)))		return (retVal);	if (SRC_SUCCESS != (retVal = 				src_reg_write(DSP, SRC_ADC_RVOL, 1 << 12)))		return (retVal);	/* default some rates */	src_set_rate(DSP, SRC_SYNTH_BASE, SRC_RATE);	src_set_rate(DSP, SRC_DAC_BASE,   SRC_RATE);	src_set_rate(DSP, SRC_ADC_BASE,   SRC_RATE);	/* now enable the whole deal */	if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))		return (SRC_ERR_NOT_BUSY_TIMEOUT);	pci_outl(reg(SAMPLE_RATE_CONV), 0UL);	return 0;}PRIVATE int src_reg_read(DEV_STRUCT * DSP, u16_t reg, u16_t *data) {	u32_t dtemp;	/* wait for ready */	if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))		return (SRC_ERR_NOT_BUSY_TIMEOUT);	dtemp = pci_inl(reg(SAMPLE_RATE_CONV));	/* assert a read request */	/*pci_outl(reg(SAMPLE_RATE_CONV),	  (dtemp & SRC_CTLMASK) | ((u32_t) reg << 25));*/	pci_outl(reg(SAMPLE_RATE_CONV), (dtemp & 				(DIS_REC|DIS_P2|DIS_P1|SRC_DISABLE)) | ((u32_t) reg << 25));	/* now wait for the data */	if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))		return (SRC_ERR_NOT_BUSY_TIMEOUT);	if (NULL != data)		*data = (u16_t) pci_inl(reg(SAMPLE_RATE_CONV));	return 0;}PRIVATE int src_reg_write(DEV_STRUCT * DSP, u16_t reg, u16_t val) {	u32_t dtemp;	/* wait for ready */	if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))		return (SRC_ERR_NOT_BUSY_TIMEOUT);	dtemp = pci_inl(reg(SAMPLE_RATE_CONV));	/* assert the write request */	pci_outl(reg(SAMPLE_RATE_CONV),	  (dtemp & SRC_CTLMASK) | SRC_RAM_WE | ((u32_t) reg << 25) | val); 	return 0;}void src_set_rate(DEV_STRUCT * DSP, char base, u16_t rate) {	u32_t    freq, dtemp, i;	u16_t     N, truncM, truncStart, wtemp;	if( base != SRC_ADC_BASE )	{		/* freeze the channel */		dtemp = base == SRC_SYNTH_BASE ? SRC_SYNTHFREEZE : SRC_DACFREEZE;		for( i = 0; i < SRC_IOPOLL_COUNT; ++i )			if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )				break;		pci_outl(reg(SAMPLE_RATE_CONV),				(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) |				dtemp);		/* calculate new frequency and write it - preserve accum */		/* please don't try to understand. */		freq = ((u32_t) rate << 16) / 3000U;		src_reg_read(DSP, base + SRC_INT_REGS_OFF, &wtemp);		src_reg_write(DSP, base + SRC_INT_REGS_OFF,				(wtemp & 0x00ffU) |				(u16_t) (freq >> 6) & 0xfc00);		src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);		/* un-freeze the channel */		dtemp = base == SRC_SYNTH_BASE ? SRC_SYNTHFREEZE : SRC_DACFREEZE;		for( i = 0; i < SRC_IOPOLL_COUNT; ++i )			if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )				break;		pci_outl(reg(SAMPLE_RATE_CONV),				(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) &				~dtemp);	}	else /* setting ADC rate */	{		/* freeze the channel */		for( i = 0; i < SRC_IOPOLL_COUNT; ++i )			if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )				break;		pci_outl(reg(SAMPLE_RATE_CONV),				(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) |				SRC_ADCFREEZE);		/* derive oversample ratio */		N = rate/3000U;		if( N == 15 || N == 13 || N == 11 || N == 9 )			--N;		src_reg_write(DSP, SRC_ADC_LVOL, N << 8);		src_reg_write(DSP, SRC_ADC_RVOL, N << 8);		/* truncate the filter and write n/trunc_start */		truncM = (21*N - 1) | 1;		if( rate >= 24000U )		{			if( truncM > 239 )				truncM = 239;			truncStart = (239 - truncM) >> 1;			src_reg_write(DSP, base + SRC_TRUNC_N_OFF,					(truncStart << 9) | (N << 4));		}		else		{			if( truncM > 119 )				truncM = 119;			truncStart = (119 - truncM) >> 1;			src_reg_write(DSP, base + SRC_TRUNC_N_OFF,					0x8000U | (truncStart << 9) | (N << 4));		}		/* calculate new frequency and write it - preserve accum */		freq = ((48000UL << 16) / rate) * N;		src_reg_read(DSP, base + SRC_INT_REGS_OFF, &wtemp);		src_reg_write(DSP, base + SRC_INT_REGS_OFF,				(wtemp & 0x00ffU) |				(u16_t) (freq >> 6) & 0xfc00);		src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);		/* un-freeze the channel */		for( i = 0; i < SRC_IOPOLL_COUNT; ++i )			if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )				break;		pci_outl(reg(SAMPLE_RATE_CONV),				(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) &				~SRC_ADCFREEZE);	}	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -