/*********************************************************************** * Records a buffer of sound from either the Line-In or Mic-In ports * to the AC97 controller and plays it back through the Line-Out port * using the AC97. ***********************************************************************/ #include #include #include "xac97_l.h" void XAC97_WriteReg(Xuint32 baseaddr, Xuint32 reg_addr, Xuint32 value) { XAC97_mSetAC97RegisterData(baseaddr, value); XAC97_mSetAC97RegisterAccessCommand(baseaddr, reg_addr); while (!XAC97_isRegisterAccessFinished(baseaddr)); } Xuint32 XAC97_ReadReg(Xuint32 baseaddr, Xuint32 reg_addr) { XAC97_mSetAC97RegisterAccessCommand(baseaddr, reg_addr | 0x80); while (!XAC97_isRegisterAccessFinished(baseaddr)); return XAC97_mGetAC97RegisterData(baseaddr); } void XAC97_AwaitCodecReady(Xuint32 baseaddr) { while(!XAC97_isCodecReady(baseaddr)); } void XAC97_Delay(Xuint32 value) { volatile int i = value; while(i-- > 0); } void XAC97_SoftReset(Xuint32 BaseAddress) { XAC97_WriteReg(BaseAddress, AC97_Reset, 0x0000); /** Set default output volumes **/ XAC97_WriteReg(BaseAddress, AC97_MasterVol, AC97_VOL_MID); XAC97_WriteReg(BaseAddress, AC97_AuxOutVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_MasterVolMono, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_PCMOutVol, AC97_VOL_MAX); /** Clear the fifos **/ XAC97_ClearFifos(BaseAddress); } void XAC97_HardReset(Xuint32 BaseAddress) { XAC97_mSetControl(BaseAddress, AC97_ENABLE_RESET_AC97); XAC97_Delay(100000); XAC97_mSetControl(BaseAddress, AC97_DISABLE_RESET_AC97); XAC97_Delay(100000); XAC97_SoftReset(BaseAddress); } void XAC97_InitAudio(Xuint32 BaseAddress, Xuint8 Loopback) { Xuint8 i; /** Reset audio codec **/ XAC97_SoftReset(BaseAddress); /** Wait until we receive the ready signal **/ XAC97_AwaitCodecReady(BaseAddress); if( Loopback == AC97_ANALOG_LOOPBACK ) { XAC97_WriteReg(BaseAddress, AC97_MicVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_LineInVol, AC97_VOL_MAX); } else if( Loopback == AC97_DIGITAL_LOOPBACK ) XAC97_WriteReg(BaseAddress, AC97_GeneralPurpose, AC97_GP_ADC_DAC_LOOPBACK); } // end XAC97_InitAudio() void XAC97_EnableInput(Xuint32 BaseAddress, Xuint8 InputType) { XAC97_WriteReg(BaseAddress, AC97_RecordGain, AC97_VOL_MAX); if( InputType == AC97_MIC_INPUT ) XAC97_WriteReg(BaseAddress, AC97_RecordSelect, AC97_RECORD_MIC_IN); else if( InputType == AC97_LINE_INPUT ) XAC97_WriteReg(BaseAddress, AC97_RecordSelect, AC97_RECORD_LINE_IN); } void XAC97_DisableInput(Xuint32 BaseAddress, Xuint8 InputType) { XAC97_WriteReg(BaseAddress, AC97_RecordGain, AC97_VOL_MUTE); if( InputType == AC97_MIC_INPUT ) XAC97_WriteReg(BaseAddress, AC97_MicVol, AC97_VOL_MUTE); else if( InputType == AC97_LINE_INPUT ) XAC97_WriteReg(BaseAddress, AC97_LineInVol, AC97_VOL_MUTE); } void XAC97_RecAudio(Xuint32 BaseAddress, Xuint32 StartAddress, Xuint32 EndAddress) { Xuint32 i; Xuint32 sample; volatile Xuint32 *sound_ptr = (Xuint32*)StartAddress; /** Enable VRA Mode **/ XAC97_WriteReg(BaseAddress, AC97_ExtendedAudioStat, 1); /** Clear out the FIFOs **/ XAC97_ClearFifos(BaseAddress); /** Wait until we receive the ready signal **/ XAC97_AwaitCodecReady(BaseAddress); /** Volume settings **/ XAC97_WriteReg(BaseAddress, AC97_MasterVol, AC97_VOL_MUTE); XAC97_WriteReg(BaseAddress, AC97_AuxOutVol, AC97_VOL_MUTE); XAC97_WriteReg(BaseAddress, AC97_MasterVolMono, AC97_VOL_MUTE); XAC97_WriteReg(BaseAddress, AC97_PCBeepVol, AC97_VOL_MUTE); XAC97_WriteReg(BaseAddress, AC97_PCMOutVol, AC97_VOL_MUTE); XAC97_WriteReg(BaseAddress, AC97_GeneralPurpose, AC97_GP_PCM_BYPASS_3D); /** Record the incoming audio **/ while( sound_ptr < (Xuint32*)EndAddress ) { sample = XAC97_ReadFifo(BaseAddress); *sound_ptr = sample; sound_ptr++; } } // end XAC97_RecAudio() void XAC97_PlayAudio(Xuint32 BaseAddress, Xuint32 StartAddress, Xuint32 EndAddress){ Xuint32 i; Xuint32 sample; volatile Xuint32 *sound_ptr = (Xuint32*)StartAddress; /** Wait for the ready signal **/ XAC97_AwaitCodecReady(BaseAddress); /** Disable VRA Mode **/ XAC97_WriteReg(BaseAddress, AC97_ExtendedAudioStat, 0); /** Play Volume Settings **/ XAC97_WriteReg(BaseAddress, AC97_MasterVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_AuxOutVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_MasterVolMono, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_PCBeepVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_PCMOutVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_LineInVol, AC97_VOL_MAX); XAC97_WriteReg(BaseAddress, AC97_MicVol, AC97_VOL_MAX); /** Clear FIFOs **/ XAC97_ClearFifos(BaseAddress); while( sound_ptr < (Xuint32*)EndAddress ) { sample = *sound_ptr; sound_ptr = sound_ptr + 1; XAC97_WriteFifo(BaseAddress, sample); } XAC97_ClearFifos(BaseAddress); } // end XAC97_PlayAudio() Xuint32 XAC97_ReadFifo(Xuint32 BaseAddress) { while(XAC97_isOutFIFOEmpty(BaseAddress)); return XAC97_mGetOutFifoData(BaseAddress); } void XAC97_WriteFifo(Xuint32 BaseAddress, Xuint32 sample) { while(XAC97_isInFIFOFull(BaseAddress)); XAC97_mSetInFifoData(BaseAddress, sample); } void XAC97_ClearFifos(Xuint32 BaseAddress) { Xuint32 i; XAC97_mSetControl(BaseAddress, AC97_CLEAR_FIFOS); for( i = 0; i < 512; i++ ) XAC97_mSetInFifoData(BaseAddress, 0); }