You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
5.6 KiB
180 lines
5.6 KiB
/*********************************************************************** |
|
* 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 <xbasic_types.h> |
|
#include <xio.h> |
|
#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); |
|
}
|
|
|