📄 aaci_audio_ok.c
字号:
// Enable Transmit
AACI_RegWrite32( AACIReg_Channel1TxControl,
AACI_RegRead32(AACIReg_Channel1TxControl) |
AACIBit_EnableFIFO );
/*
//yz_add for DMA !!
if(!(g_DMAEvent= CreateEvent( NULL, FALSE, FALSE,NULL))) {
RETAILMSG(1, (TEXT("CreateEvent(g_DMAEvent) FAILED\r\n")));
bRet = FALSE;
}
hDMAThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)PDD_DMAThread,
NULL,
0,
NULL);
DmaCmd = DMA_CMD_STOP;
if (!hDMAThread) {
RETAILMSG(1, (TEXT("hDMAThread Create FAILED\r\n")));
bRet = FALSE;
}
SetThreadPriority( hDMAThread , THREAD_PRIORITY_ABOVE_NORMAL );
*/
//add whs
Sleep(500);
//MakeTest();
hWaveThread = CreateThread(NULL, 0, DeviceThreadProc, NULL, 0, NULL);
if(!hWaveThread)
{
RETAILMSG(DBG_AACI, (TEXT("CreateThread Error FAILED\r\n")));
return -1;
}
FUNC_WPDD("-AACI_Initialize");
return bRet;
}
static BOOL ResetDevice()//复位设备
{
int loop = 0;
DWORD temp = 0;
// Start by disabling the AACI
AACI_RegWrite32( AACIReg_MainControl, 0 );
INITMSG("AACI: Disabling Interrupts");
AACI_RegWrite32( AACIReg_SlotIntEnable, 0 );
AACI_RegWrite32( AACIReg_Channel1IntEnable, 0 );
INITMSG("AACI: Clearing Interrupts");
AACI_RegWrite32( AACIReg_IntClear, AACIBit_ClearAllInts );
INITMSG("AACI: Cold reset");
AACI_RegWrite32( AACIReg_Reset, 0x0 );
Sleep(200); // Wait while device resets
AACI_RegWrite32( AACIReg_Reset, 0x1 );
#ifdef TX_COMPACT_MODE
INITMSG("AACI: Setup Transmit FIFO1 (Compact mode)");
#else
INITMSG("AACI: Setup Transmit FIFO1 (Non-compact mode)");
#endif
if( AACI_RegRead32(AACIReg_Channel1Status) & (AACIBit_TXFIFOBusy) )
{
ERRMSG("AACI ERROR: Transmit FIFO1 busy!");
}
// Set up Transmit FIFO
AACI_RegWrite32( AACIReg_Channel1TxControl,
AACIBit_Slot3DataInFIFO |
AACIBit_Slot4DataInFIFO |
#ifdef TX_COMPACT_MODE
AACIBit_EnableCompactMode |
#endif
AACIBit_DataSize16bits |
AACIBit_EnableFIFOMode );
#ifdef RX_COMPACT_MODE
INITMSG("AACI: Setup Receive FIFO1 (Compact mode)");
#else
INITMSG("AACI: Setup Receive FIFO1 (Non-compact mode)");
#endif
if( AACI_RegRead32(AACIReg_Channel1Status) & (AACIBit_RXFIFOBusy) )
{
ERRMSG("AACI ERROR: Receive FIFO1 busy!");
}
// Set up Receive FIFO
AACI_RegWrite32( AACIReg_Channel1RxControl,
AACIBit_Slot3DataInFIFO |
AACIBit_Slot4DataInFIFO |
#ifdef RX_COMPACT_MODE
AACIBit_EnableCompactMode |
#endif
AACIBit_DataSize16bits |
AACIBit_EnableFIFOMode );
INITMSG("AACI: Setup Main Control Register");
//yz_add
AACI_RegWrite32( AACIReg_MainControl, AACIBit_Enable | /* Enable command , data, control channel */
AACIBit_Slot1TXEnable | AACIBit_Slot1RXEnable |
AACIBit_Slot2TXEnable | AACIBit_Slot2RXEnable | AACIBit_DMAEnable|AACIBit_Slot12RXEnable|AACIBit_Slot12TXEnable);
// Wait for CODEC to be ready
INITMSG("AACI: Wait till CODEC ready");
//读CODEC 的26H 寄存器,如果低四位都为1 则表示CODEC 准备好了
while( (AACI_CodecRead16(LM4549A_POWERDOWN_CTRL_STAT) != 0xF) && loop < 10 ) /* read 26h */
{
Sleep(10);
loop++;
}
if( loop == 10 )//如果是等待退出 则表示初始化失败,则直接退出
{
ERRMSG("AACI: Failed to wait for CODEC to power up" );
return FALSE;
}
/****************对应硬件设置**************************************/
/*
// Turn off PC Beep (by default it is on full)
INITMSG("AACI: Turn off PC Beep");
AACI_CodecWrite16( LM4549A_PC_BEEP_VOLUME, LM4549A_BIT_VOLUME_MUTE );
AACI_CodecWrite16( LM4549A_MASTER_VOLUME , 0x0000 );
//AACI_CodecWrite16( LM4549A_MIC_VOLUME , 0x8040 );
AACI_CodecWrite16( LM4549A_GENERAL_PURPOSE , 0x00 );
//AACI_CodecWrite16( LM4549A_RECORD_GAIN , 0x00 );
AACI_CodecWrite16( LM4549A_RECORD_SELECT , 0x0404 );
*/ // Turn on Variable Rate Audio (VRA) to allow sample rate to be set
INITMSG("AACI: Turn on VRA");
AACI_CodecWrite16( LM4549A_EXT_AUDIO_CTRL_STAT, 0x1 );
RETAILMSG( DBG_AACI , (TEXT("aaci : read sample per sec %x\r\n") , AACI_CodecRead16(LM4549A_PCM_FRONT_DAC_RATE) ));
AACI_CodecWrite16( LM4549A_PCM_FRONT_DAC_RATE, 44100 );
//控制录音
#if 1
AACI_CodecWrite16( 0x0e , 0x9f9f );//选择MIC1 MIC2 有效; -34.5db
AACI_CodecWrite16( 0x1c , 0x0505 );//录音增益选择 7.5db
AACI_CodecWrite16( 0x1a , 0x4000 );//选择录音信号源
#else
AACI_CodecWrite16( 0x0e , 0xb180 );//选择MIC1 有效,音量0db // by he
AACI_CodecWrite16( 0x1c , 0x0f0f );//录音增益选择 7.5db by he
AACI_CodecWrite16( 0x1a , 0x4000);//0x5000 );//选择录音信号源 // enable left channel; by he
#endif
AACI_CodecWrite16( 0x24 , 0x6bff & AACI_CodecRead16(0x24) );//电源选择
AACI_CodecWrite16( 0x26 , 0x4600 & AACI_CodecRead16(0x26) );//电源选择
//AACI_CodecWrite16(0x52, AACI_CodecRead16(0x52)|0x3e); //gpio1-5 interrupt wake up
AACI_CodecWrite16(0x52, AACI_CodecRead16(0x52)|0x3c); //gpio2-5 interrupt wake up by he 2007-5-8 16:32
//修改3
AACI_CodecWrite16( 0x4c, (AACI_CodecRead16(0x4c)&(~0x02)) );//GPIO1设置为输出: 0 ->output, 1 -> input
//add junxz 20070405
temp = AACI_CodecRead16(0x4c)&0x02;
while(temp)
{
RETAILMSG(1, (TEXT("ResetDevice(): *****0x%.4x*****0x%d\r\n"), AACI_CodecRead16(0x4c), temp));
if(temp==0x02)
{
AACI_CodecWrite16( 0x4c, (AACI_CodecRead16(0x4c)&(~0x02)) );//GPIO1设置为输出
RETAILMSG(1, (TEXT("AACIReg_Slot2Tx: *****0x%.4x*****\r\n"), AACI_CodecRead16(0x4c)));
}
temp = AACI_CodecRead16(0x4c)&0x02;
}
//20070405
SET_SLOT12_FALSE;
//修改3
AACI_CodecWrite16( LM4549A_PCM_OUT_VOL , 0x0909 );//0x18----control the audio dacs (12db -1.5db)
// add junxz
// Bass mode and Treble Intensity
AACI_CodecWrite16(LM4549A_MASTER_VOLUME, AACI_CodecRead16(0x02)|0x80); /*mute speaker*/
AACI_CodecWrite16(LM4549A_LINE_LEV_OUT_VOL, AACI_CodecRead16(0x04)|0x80); /*mute headphone*/
AACI_CodecWrite16(LM4549A_BASS_CONTROL, 0x9c46);
// 3D mode enable
AACI_CodecWrite16( LM4549A_3D_ENABLE, 0x2000);
// DAC 3D control
AACI_CodecWrite16(LM4549A_3D_CONTROL, 0x3a);
//add junxz
/****************对应硬件设置**************************************/
AACI_RegWrite32( AACIReg_Channel1IntEnable,
AACI_RegRead32( AACIReg_Channel1IntEnable ) &
~(AACIBit_TxCIE | AACIBit_TxIE | AACIBit_TxUIE) );
// Clear any transmit underruns now we have filled the FIFO
if( AACI_RegRead32( AACIReg_Channel1Status ) & AACIBit_TXUnderrun )
{
TESTMSG("AACI_WaveContinue: Transmit Underrun - too slow!");
AACI_RegWrite32( AACIReg_IntClear, AACIBit_TxUEC1 );
}
return TRUE;
}
//-----------------------------------------------------------------------------
// Power functions - Place holder functions for your own power code
//-----------------------------------------------------------------------------
static void PowerDown()
{
if( g_fPowerOn )
{
// Turn off the CODEC - go into low power mode
g_fPowerOn = FALSE;
}
}
static void PowerUp()
{
if( !g_fPowerOn )
{
// Turn on the CODEC - from low power mode
g_fPowerOn = TRUE;
}
}
//--------------------------------------------------------------------------
// MMRESULT AACI_WaveOpen (WAPI_INOUT apidir,
// LPWAVEFORMATEX lpFormat,
// BOOL fQueryFormatOnly)
//
// Opens or query the wave stream.
//
// It also can be used to query the format to see if it's a valid one.
// To do so, the caller has to set fQueryFormatOnly to TRUE.
//
// WAPI_INOUT apidir
// Direction of the stream: Playback=1, Record=0
//
// LPWAVEFORMATEX lpFormat
// Pointer to a structure that defines the format of the wave.
// Based on Microsoft definition.
//
// unsigned char fQueryFormatOnly
// If the caller only want to check on the format,
// this value should be set to TRUE
//---------------------------------------------------------------------------
//int MsgRecord[100][2];
extern WAVEFORMATEX RecordFormat;
MMRESULT AACI_WaveOpen (WAPI_INOUT apidir,
LPWAVEFORMATEX lpFormat,
BOOL fQueryFormatOnly)
{
MMRESULT mmRet = MMSYSERR_NOERROR;
RETAILMSG(0,(TEXT("\r\n<<<<<<<+AACI_WaveOpen v1.25>>>>>>>>\r\n")));
//如果你给出的格式不是下面的格式则直接退出
if ((lpFormat->wFormatTag != WAVE_FORMAT_PCM) ||
(lpFormat->nChannels !=1 && lpFormat->nChannels != 2) ||//通道为1/2
(lpFormat->nSamplesPerSec < 4000 || lpFormat->nSamplesPerSec > 48000) ||//采样率在4000---48000之间
(lpFormat->wBitsPerSample != 16 && lpFormat->wBitsPerSample != 8))//位深为8/16
{
VERBOSEMSG("AACI_WaveOpen: Bad Format");
mmRet = WAVERR_BADFORMAT;
goto EXIT;
}
// If the caller only wants to check on that format, return having
// checked above
if (fQueryFormatOnly)
{
VERBOSEMSG("AACI_WaveOpen: QueryFormatOnly");
goto EXIT;
}
//RETAILMSG(yz_debug,(TEXT("AACI_WaveOpen()\r\n")));
// If the device is already being use, return with MMSYSERR_ALLOCATED
if (g_fInUse[apidir])
{
mmRet = MMSYSERR_ALLOCATED;
goto EXIT;
}
g_fInUse[apidir] = TRUE;
g_pwfx[apidir] = lpFormat;
// Make sure the CODEC is on
PowerUp();
RETAILMSG(DBG_AACI,(TEXT("aaci Samples PerSec 3.98 : %d , %d , %d , %d \r\n") ,
lpFormat->nSamplesPerSec , lpFormat->nAvgBytesPerSec , lpFormat->nBlockAlign , lpFormat->wBitsPerSample ));
RETAILMSG( DBG_AACI, (TEXT("AACI_WaveOpen: dir=%d, chan=%d, samp=%d, bits=%d\r\n"),
apidir, lpFormat->nChannels, (USHORT)lpFormat->nSamplesPerSec,
lpFormat->wBitsPerSample) );
// Sort out pointer to correct function for speedy operation
if( apidir == WAPI_OUT )
{
VERBOSEMSG("AACI_WaveOpen: WAPI_OUT");
if (lpFormat->wBitsPerSample == 8)
{
if (lpFormat->nChannels == 1)
pfnFillFIFO = FillFIFO_M8;
else
pfnFillFIFO = FillFIFO_S8;
}
else
{
if (lpFormat->nChannels == 1)
{
pfnFillFIFO = FillFIFO_M16;
}
else
{
pfnFillFIFO = FillFIFO_S16;
}
}
// Unmute and turn PCM and Line Level volumes to max
// Set output sample rate
//yz_change for TOUCH!
AACI_CodecWrite16( LM4549A_PCM_FRONT_DAC_RATE, //输出声音采样率
(USHORT)lpFormat->nSamplesPerSec );
RETAILMSG( DBG_AACI , (TEXT("aaci : read sample per sec %x\r\n") , AACI_CodecRead16(LM4549A_PCM_FRONT_DAC_RATE) ));
AACI_RegWrite32( AACIReg_Channel1IntEnable,
AACI_RegRead32( AACIReg_Channel1IntEnable ) &
~(AACIBit_TxCIE | AACIBit_TxIE | AACIBit_TxUIE) );
// Clear any transmit underruns now we have filled the FIFO
if( AACI_RegRead32( AACIReg_Channel1Status ) & AACIBit_TXUnderrun )
{
TESTMSG("AACI_WaveContinue: Transmit Underrun - too slow!");
AACI_RegWrite32( AACIReg_IntClear, AACIBit_TxUEC1 );
}
OnPlayOpen();
}
else
{
RecordFormat = *lpFormat;
VERBOSEMSG("AACI_WaveOpen: WAPI_IN");
if (lpFormat->wBitsPerSample == 8)
{
if (lpFormat->nChannels == 1)
pfnGetFIFO = GetFIFO_M8;
else
pfnGetFIFO = GetFIFO_S8;
}
else
{
if (lpFormat->nChannels == 1)
pfnGetFIFO = GetFIFO_M16;
else
pfnGetFIFO = GetFIFO_S16;
}
// NOTE: By default only the MIC will be active for recording, you
// need to use the RECORD_SELECT codec register to change this
// Set up input gain to something reasonable (not too high so as to
// reduce signal chopping)
//yz_add
// AACI_CodecWrite16( 0x1c, 0x0000 );
// Set input sample rate
AACI_CodecWrite16( LM4549A_PCM_ADC_RATE,//采样频率
(USHORT)lpFormat->nSamplesPerSec );
AACI_RegWrite32( AACIReg_Channel1RxControl,
AACI_RegRead32(AACIReg_Channel1RxControl) &
(~AACIBit_EnableFIFO) );
// Clear any interrupts
AACI_RegWrite32( AACIReg_IntClear, AACIBit_RxTOFEC1 | AACIBit_RxOEC1 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -