📄 l2_audio.c
字号:
/*++
Copyright (c) 2001 Sunplus Technology Co., Ltd.
Module Name:
L2_audio.c
Abstract:
Audio L2 function
Environment:
Keil C51 Compiler
Revision History:
11/12/2001 cclin created
--*/
//=============================================================================
//Header file
//=============================================================================
#include "general.h"
//=============================================================================
//Symbol
//=============================================================================
//-----------------------------------------------------------------------------
//Constant
//-----------------------------------------------------------------------------
#define K_AC_Index_Reset 0x00
#define K_AC_Index_MasterVolume 0x02
#define K_AC_Index_MasterVolumeMono 0x06
#define K_AC_Index_PcBeepVolume 0x0A
#define K_AC_Index_PhoneVolume 0x0C
#define K_AC_Index_MicVolume 0x0E
#define K_AC_Index_LineInVolume 0x10
#define K_AC_Index_CdVolume 0x12
#define K_AC_Index_VideoVolume 0x14
#define K_AC_Index_AuxVolume 0x16
#define K_AC_Index_PcmOutVol 0x18
#define K_AC_Index_RecordSelect 0x1A
#define K_AC_Index_RecordGain 0x1C
#define K_AC_Index_GeneralPurpose 0x20
#define K_AC_Index_3dControl 0x22
#define K_AC_Index_PowerDownCtrlSts 0x26
#define K_AC_Index_SerialConfig 0x74
#define K_AC_Index_MiscCtrlBits 0x76
#define K_AC_Index_SampleRate0 0x78
#define K_AC_Index_SampleRate1 0x7A
#define K_AC_Index_VendorId1 0x7C
#define K_AC_Index_VendorId2 0x7E
//AC'97 CODEC register content //current //default
#define K_AC_Reset 0x0400 //0x0400
#define K_AC_MasterVolume 0x8000 //0x8000
#define K_AC_MasterVolumeMono 0x8000 //0x8000
#define K_AC_PcBeepVolume 0x8000 //0x8000
#define K_AC_PhoneVolume 0x8008 //0x8008
#define K_AC_MicVolume 0x0040 //0x8008
#define K_AC_LineInVolume 0x8808 //0x8808
#define K_AC_CdVolume 0x8808 //0x8808
#define K_AC_VideoVolume 0x8808 //0x8808
#define K_AC_AuxVolume 0x8808 //0x8808
#define K_AC_PcmOutVol 0x8808 //0x8808
#define K_AC_RecordSelect 0x0606 //0x0000
#define K_AC_RecordGain 0x0f0f //0x8000
#define K_AC_GeneralPurpose 0x0000 //0x0000
#define K_AC_3dControl 0x0000 //0x0000
#define K_AC_PowerDownCtrlSts 0x0000 //0x0000
#define K_AC_SerialConfig 0x7000 //0x7000
#define K_AC_MiscCtrlBits 0x0000 //0x0000
#define K_AC_SampleRate0 0x1F40 //0xBB80
#define K_AC_SampleRate1 0xBB80 //0xBB80
#define K_AC_VendorId1 0x4144 //0x4144
#define K_AC_VendorId2 0x5303 //0x5303
//Sub-sampling specific
#define K_AUDIO_MaxSampleRate 0x1F40
#define K_AUDIO_SubSampleFactor (K_AUDIO_MaxSampleRate / K_AC_SampleRate0)
//AC'97 CODEC register read/write retry count
#define K_AC_MAXRETRYCOUNT 1000000
//#define EmbCodec 1
//#define AC97 2
//-----------------------------------------------------------------------------
//Variable
//-----------------------------------------------------------------------------
//=============================================================================
//Program
//=============================================================================
//-----------------------------------------------------------------------------
//L2_InitAudio
//-----------------------------------------------------------------------------
/*
routine description:
Select corresponding audio pins.
CamMode is not referenced in this function.
arguments:
CamMode - Camera mode
return value:
0x00 - success
others - error
*/
UCHAR L2_InitAudio(ULONG CamMode) USING_0
{
UCHAR status = L2K_SUCCESS;
//avoid warning
ULONG Temp0 = CamMode;
//body
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_InitAC97
//-----------------------------------------------------------------------------
/*
routine description:
Initialize the AC97 codec: data path, record gain and volume.
The initialization of the AC97 codec follows the default values stated below.
Default value:
data path: Mic-MonoMix-ACLink and ACLink-LineOut
record gain: 0dB gain unmuted
volume: 0dB gain unmated
For further configuration, please use L2_WrAC97Reg() and L2_RdAC97Reg().
arguments:
return value:
0x00 - success
others - error
*/
UCHAR L2_InitAC97(void) USING_0
{
UCHAR status = L2K_SUCCESS;
// ULONG i;
XBYTE[0x2019] = 0x04;
XBYTE[0x2604] = 0x01; //enable AC-97 interface
// while (i != 25000) //25000 loop * 40 us/loop = 1 sec
// i++;
//PRINT_L2("XBYTE[0x2604] = %bx", XBYTE[0x2604]);
L2_WrAC97Reg(K_AC_Index_MicVolume, K_AC_MicVolume);
L2_WrAC97Reg(K_AC_Index_RecordSelect, K_AC_RecordSelect);
L2_WrAC97Reg(K_AC_Index_RecordGain, K_AC_RecordGain);
L2_WrAC97Reg(K_AC_Index_GeneralPurpose, K_AC_GeneralPurpose);
L2_WrAC97Reg(K_AC_Index_MiscCtrlBits, K_AC_MiscCtrlBits);
L2_WrAC97Reg(K_AC_Index_SampleRate0, K_AC_SampleRate0);
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_RdAC97Reg
//-----------------------------------------------------------------------------
/*
routine description:
Read the specific AC97 register.
arguments:
AC97Addr - AC97 register address
Value - AC97 register value
return value:
0x00 - success
others - error
*/
UCHAR L2_RdAC97Reg(UCHAR AC97Addr, USHORT* Value) USING_0
{
UCHAR status = L2K_SUCCESS;
ULONG retry = 0;
//clear valid bit of audio in register
XBYTE[0x26b3] &= 0xfd;
//set register address to read
XBYTE[0x2601] = (AC97Addr & 0x7f) | 0x80;
//set AudOutReg high to xmit address
XBYTE[0x26a0] = 0x01;
//wait for AudInVld high or time out
do
{
status = XBYTE[0x26b3] & 0x02;
retry++;
} while ((status == 0x00) && (retry <= K_AC_MAXRETRYCOUNT));
*Value = (((USHORT) XBYTE[0x26b1]) |
(((USHORT) XBYTE[0x26b2]) << 8));
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_WrAC97Reg
//-----------------------------------------------------------------------------
/*
routine description:
Write the specific AC97 register.
arguments:
AC97Addr - AC97 register address
Value - AC97 register value
return value:
0x00 - success
others - error
*/
UCHAR L2_WrAC97Reg(UCHAR AC97Addr, USHORT Value) USING_0
{
UCHAR status = L2K_SUCCESS;
ULONG retry = 0;
//set register address to write
XBYTE[0x2601] = AC97Addr & 0x7f;
//set register value low to write
XBYTE[0x2602] = M_LoByteOfWord(Value); //low
XBYTE[0x2603] = M_HiByteOfWord(Value); //high
//set AudOutReg high to xmit address and value
XBYTE[0x26a0] = 0x01;
//wait for AudOutBsy low or time out
do
{
status = XBYTE[0x26b3] & 0x01;
retry++;
} while ((status != 0x00) && (retry <= K_AC_MAXRETRYCOUNT));
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_InitEmbAudCodec
//-----------------------------------------------------------------------------
/*
routine description:
Initialize the embedded audio codec.
arguments:
Play - 0: record. Enable the embedded ADC
1: play. Enable the embedded DAC
return value:
0x00 - success
others - error
*/
UCHAR L2_InitEmbAudCodec(BIT Play)
{
UCHAR status = L2K_SUCCESS;
//avoid warning
//ULONG Temp0 = Play;
//patch5.0@richie@audio begin
if (Play == 0) // record
{
XBYTE[0x2670] = 0x01; // disable adc
XBYTE[0x2670] = 0x0E; // enable adc
XBYTE[0x2671] = 0x00; // unmute adc
}
else
{
XBYTE[0x2670] = 0x02;
XBYTE[0x2675] = 0x00;
XBYTE[0x2675] = 0x01;
}
//patch5.0@richie@audio end
//body
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_SetEmbAudCodecVol
//-----------------------------------------------------------------------------
/*
routine description:
Set the volume of the embedded audio codec
arguments:
Volume - 0: mute
- 1: min (default)
- 255: max
return value:
0x00 - success
others - error
*/
UCHAR L2_SetEmbAudCodecVol(UCHAR Volume)
{
XBYTE[0x2676] = Volume;
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//L2_EnableAudStream
//-----------------------------------------------------------------------------
/*
routine description:
Configure the audio buffer and related registers for
audio streaming data with USB.
arguments:
AudFormat - Bit[0]: 0(mono) is required
Bit[1]: resolution
0: 8bit per sample
1: 16bit per sample
Bit[2]: pcm format
0: pcm
1: pcm8
Bit[3]: 0(non-compression) is required.
Bit[5-4]: downsample mode
0: no downsample
1: 1/2 downsample
2: 1/6 downsample
Bit[7-6]: reserved
ADCFreq - 0: 48KHz
1: 24KHz
2: 8KHz
3: 44.1KHz
return value:
0x00 - success
others - error
*/
UCHAR L2_EnableAudStream(UCHAR AudFormat, UCHAR ADCFreq)
{
UCHAR status = L2K_SUCCESS;
//avoid warning
ULONG Temp0 = AudFormat;
//body
L2_InitEmbAudCodec(0);
XBYTE[0x2605] = 0x00; //CODEC to USB //cytsai@0305
XBYTE[0x2680] = 0x00; //Disable ADPCM encoder/decoder
XBYTE[0x2674] = ADCFreq;
XBYTE[0x2606] = AudFormat;
XBYTE[0x2501] |= 0x04; // Audio short packet enable
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_PlayAud
//-----------------------------------------------------------------------------
/*
routine description:
Play the audio data in the SDRAM to the audio codec.
arguments:
DRAMAddr DRAM address where the sound file resides.
AudBufSize 0: 1K bytes
1: 2K bytes
2: 4K bytes
3: 8K bytes
AudFormat Bit[0]: channel
0: mono
1: stereo
Bit[1]: resolution
0: 8bit per sample
1: 16bit per sample
Bit[2]: pcm format
0: pcm
1: pcm8
Bit[3]: compression
0: non-compression
1: IMA-ADPCM compression
Bit[7-4]: reserved
PlayFreq Play frequency.
0: 48KHz
1: 24KHz
2: 8KHz
return value:
0x00 - success
others - error
*/
UCHAR L2_PlayAud(ULONG DRAMAddr, UCHAR AudBufSize, UCHAR AudFormat, UCHAR PlayFreq )
{
UCHAR status = L2K_SUCCESS;
//ULONG AudBufCnt;
//ULONG i;
ULONG temp0 = DRAMAddr;
UCHAR temp1 = AudBufSize;
ULONG AudBufCnt;
// UCHAR i;
UCHAR Decompression = 0;
L2_StopAud();
//----------------------------------------
// Audio configuration
XBYTE[0x2605] = 0x04; // DRAM-to-AC97/DAC
// XBYTE[0x2605] = 0x02; // CPU-to-AC97/DAC
if((AudFormat&0x40)==0x40)
Decompression = 0x01;
else
Decompression = 0x00;
if (Decompression == 0x01)
AudFormat |= 0x02; // Aud16bit set in compression mode
AudFormat &= 0x0f; // Set AudDSMode 0
AudFormat &= 0xbf; // remove bit6
//PRINT_L2("AudFormat = %bx\n", AudFormat);
//PRINT_L2("Decompression = %bx\n", Decompression);
XBYTE[0x2606] = AudFormat;
XBYTE[0x2674] = PlayFreq;
L2_InitEmbAudCodec(1); // play
// i = 0;
// while(1)
// {
// XBYTE[0x2600] = (UCHAR) i;
// i++;
// }
//----------------------------------------
// DRAM configuration
XBYTE[0x273A] = (UCHAR)DRAMAddr; // Audio buffer start address
XBYTE[0x273B] = (UCHAR)(DRAMAddr>>8); // Audio buffer start address
XBYTE[0x273C] = (UCHAR)(DRAMAddr>>16); // Audio buffer start address
AudBufCnt = ((ULONG)XBYTE[0x27b4]<<8) | ((ULONG)XBYTE[0x27b3]);
//PRINT_L2("AudBufCnt befor audcliprst = %lx\n", AudBufCnt);
XBYTE[0x27A1] = 0x40; // Set audcliprst
AudBufCnt = ((ULONG)XBYTE[0x27b4]<<8) | ((ULONG)XBYTE[0x27b3]);
//PRINT_L2("AudBufCnt after audcliprst = %lx\n", AudBufCnt);
XBYTE[0x2723] = AudBufSize; // Set DRAM audio buffer size
//Joe@2003.3.12 9:21 add begin
//XBYTE[0x2000] = 0x00;
//Joe@2003.3.12 9:22 add end
//XBYTE[0x2000] = 0x05; // Set playback mode
L2_SetDRAMAudDMACnt(0);
if (Decompression == 0x01)
XBYTE[0x2680] = 0x02;
XBYTE[0x273E] = 0x01; // Set audclip enable and auddir=0
XBYTE[0x2676] = 0x10; // DAC volume
// return
return(status);
}
//-----------------------------------------------------------------------------
//L2_PlayAudMode
//-----------------------------------------------------------------------------
/*
routine description:
Play the audio data through dmac
arguments:
DRAMAddr DRAM address where the sound file resides.
AudBufSize 0: 1K bytes
1: 2K bytes
2: 4K bytes
3: 8K bytes
AudFormat Bit[0]: channel
0: mono
1: stereo
Bit[1]: resolution
0: 8bit per sample
1: 16bit per sample
Bit[2]: pcm format
0: pcm
1: pcm8
Bit[3]: compression
0: non-compression
1: IMA-ADPCM compression
Bit[7-4]: reserved
PlayFreq Play frequency.
0: 48KHz
1: 24KHz
2: 8KHz
return value:
0x00 - success
others - error
*/
UCHAR L2_PlayAudDMAMode(ULONG DRAMAddr, UCHAR AudFormat, UCHAR PlayFreq)
{
UCHAR status = L2K_SUCCESS;
//ULONG AudBufCnt;
UCHAR Decompression = 0;
ULONG tmp0 = DRAMAddr;
L2_StopAud();
//----------------------------------------
// Audio configuration
XBYTE[0x2605] = 0x06; // DMAC-to-AC97/DAC
// XBYTE[0x2605] = 0x02; // CPU-to-AC97/DAC
if((AudFormat&0x40)==0x40)
Decompression = 0x01;
else
Decompression = 0x00;
if (Decompression == 0x01)
AudFormat |= 0x02; // Aud16bit set in compression mode
AudFormat &= 0x0f; // Set AudDSMode 0
AudFormat &= 0xbf; // remove bit6
//PRINT_L2("AudFormat = %bx\n", AudFormat);
//PRINT_L2("Decompression = %bx\n", Decompression);
XBYTE[0x2606] = AudFormat;
XBYTE[0x2674] = PlayFreq;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -