?? waveinpdd.c
字號:
//
// Copyright(C) Renesas Technology Corp. 1999-2005. All rights reserved.
//
// WaveDev Driver for ITS-DS7
//
// FILE : WAVEINPDD.C
// CREATED : 1999.04.26 (for HD64465 on PFM-DS6)
// MODIFIED : 2005.03.04
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY :
// 2003.06.20
// - Created release code.
// (based on WaveDev driver for ITS-DS6 Ver.2.2.0 for WCE4.1)
// 2004.04.21
// - Revised simultaneous use check. If WAVE_FORMAT_QUERY flag specified,
// open flag leaks.
// 2004.09.01
// - Created release code for WCE5.0.
// 2005.02.25
// - Removed software volume control.
// 2005.03.04
// - Moved private_WaveInContinue is moved to each hac.c and hssi.c.
//----------------------------------------------------------------------------
//
// Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <excpt.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <mmsystem.h>
#include "platform.h"
#include "shx.h"
#include "sh7770.h"
#include "drv_glob.h"
#include "oalintr.h"
#include "wavepdd.h"
#include "waveInpdd.h"
#include "dma.h"
//#include "drvlib.h"
extern BOOL dma_Init(int, PDMA_INFO *);
extern BOOL dma_Deinit(PDMA_INFO);
extern BOOL dma_SetPort(PDMA_INFO, DWORD);
extern BOOL dma_SetPage(PDMA_INFO, DWORD, DWORD, DWORD, DWORD);
extern BOOL dma_SetControl(PDMA_INFO, DWORD);
extern BOOL dma_SetCommand(PDMA_INFO, DWORD);
extern BOOL dma_InterruptEnable(PDMA_INFO);
extern BOOL dma_InterruptDisable(PDMA_INFO);
extern BOOL dma_Stop(PDMA_INFO);
extern BOOL dma_IsFinished(PDMA_INFO/*, DWORD*/);
PDMA_INFO pDMA_in; // DMA Register (for Wave input)
extern DWORD AUDIO_NO; // Audio Driver No.
extern ULONG get_CODEC_SAMPLING_RATE(int);
extern VOID get_DMA_Buffer_Address(int, DWORD, ULONG *);
extern DWORD get_DPTR(int);
extern DWORD get_DSAR(int, DWORD, int);
extern DWORD get_DDAR(int, DWORD, int);
extern DWORD get_DTCR(int, DWORD, int);
extern VOID module_init( VOID );
extern VOID module_deinit( VOID );
extern BOOL codec_init( VOID );
extern VOID module_txstart( VOID );
extern VOID module_txdmastart( VOID );
extern VOID module_rxstart( VOID );
extern VOID module_rxdmastart( VOID );
extern VOID module_txstop( VOID );
extern VOID module_rxstop( VOID );
extern VOID get_DMA_Buffer( PCM_TYPE, INT32, INT32, USHORT *, USHORT *);
extern BOOL check_SamplesPerSec(int, DWORD);
extern BOOL check_RecInPlay(int, int);
extern VOID private_WaveInContinue(PWAVEHDR pwh);
extern PWAVEFORMATEX g_pwfx[2];
extern PCM_TYPE g_pcmtype[2];
// audio in globals
// Double Buffer for Audio Recoeding
ULONG dma_pageRecPhysicalAddress[2];
ULONG v_recPage;
PBYTE pRecAudioBufferBase; // Audio buffer
extern PDRIVER_GLOBALS pDriverGlobals; // Drivers Globals
// OpenFlag
extern int RecOpenFlag;
extern int PlayOpenFlag;
// statistics
DWORD g_dwOverruns; // # of overrun errors
DWORD g_dwFrames; // # of 48 word frames filled
LPWAVEFORMATEX lpFormat2 = 0;
static volatile BOOL v_fMoreData[2];
extern struct _global_volume
{
ULONG dwMasterVolume;
ULONG dwLineInVolume;
ULONG dwMicVolume;
BOOL fMasterMute;
BOOL fLineInMute;
BOOL fMicMute;
ULONG dwInputSelect;
} g_VolumeSettings;
#define DUMPEXCEPTION() \
DEBUGMSG(ZONE_ERROR,(TEXT("Exception %d @ %s:%d\r\n"), GetExceptionCode(), __FILE__, __LINE__ ))
/*****************************************************************************
* FUNCTION : private_AudioInGetInterruptType
* DESCRIPTION : decodes type of audio interrupt
* INPUTS : None
* OUTPUTS : interrupt type
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
AUDIO_STATE
private_AudioInGetInterruptType(
VOID
)
{
if ( pDriverGlobals->aud[AUDIO_NO].inInt == (USHORT)NULL )
{
return AUDIO_STATE_IGNORE;
}
else
{
return AUDIO_STATE_IN_RECORDING;
}
}
/*****************************************************************************
* FUNCTION : private_AudioInInitialize
* DESCRIPTION : sets up register access for audio-in
* sets delay time for audio-in start-up
* INPUTS : TRUE iff successful
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
private_AudioInInitialize(
VOID
)
{
ULONG SizeOfBuffer;
char here[] = "PDD_AudioInInitialize";
BOOL RET_VALUE;
FUNC_WPDD("+PDD_AudioInInitialize");
DEBUGMSG(ZONE_TEST, (TEXT("WaveInpdd.c : private_AudioInInitialize\r\n")));
// Get DMA Transfer Buffer Address (for Recording)
get_DMA_Buffer_Address(pDriverGlobals->aud[AUDIO_NO].REC_CH, AUDIO_NO, dma_pageRecPhysicalAddress);
// DMA Initialize
dma_Init(pDriverGlobals->aud[AUDIO_NO].REC_CH, &pDMA_in);
//
// DMA Setting
//
dma_SetPort(pDMA_in, get_DPTR(pDriverGlobals->aud[AUDIO_NO].REC_CH));
dma_SetPage(pDMA_in,
0, // Page0
get_DSAR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,0), // Sorce Address
get_DDAR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,0), // Destination Address
get_DTCR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,0)); // Transfer Count
dma_SetPage(pDMA_in,
1, // Page1
get_DSAR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,1), // Sorce Address
get_DDAR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,1), // Destination Address
get_DTCR(pDriverGlobals->aud[AUDIO_NO].REC_CH,AUDIO_NO,1)); // Transfer Count
// Set pointers to virtual addresses of audio buffers
SizeOfBuffer = (AUDIO_DMA_PAGE_SIZE * 2);
pRecAudioBufferBase = VirtualAlloc( NULL,
SizeOfBuffer,
MEM_RESERVE,
PAGE_NOACCESS );
if (pRecAudioBufferBase == NULL) {
DEBUGMSG(ZONE_ERROR,(TEXT("Buffer virtual alloc NG!!\r\n")));
dma_Deinit(pDMA_in);
return FALSE;
}
RET_VALUE = VirtualCopy( (PVOID)pRecAudioBufferBase,
(PVOID)dma_pageRecPhysicalAddress[0],
(DWORD)SizeOfBuffer,
PAGE_READWRITE | PAGE_NOCACHE);
if (!RET_VALUE){
DEBUGMSG(ZONE_ERROR,(TEXT("Buffer virtual copy NG!!\r\n")));
VirtualFree((PVOID)pRecAudioBufferBase, 0, MEM_RELEASE);
dma_Deinit(pDMA_in);
return FALSE;
}
// Initialize AudioInInterrupt Flag
pDriverGlobals->aud[AUDIO_NO].rec_address = (ULONG)NULL;
pDriverGlobals->aud[AUDIO_NO].inInt = (USHORT)NULL;
DEBUGMSG(ZONE_TEST, (TEXT("WaveInpdd.c private_AudioInInitialize: END\r\n")));
FUNC("-PDD_AudioInInitialize");
return TRUE;
}
/*****************************************************************************
* FUNCTION : private_AudioInPowerHandler
* DESCRIPTION : performs power on/off, this also happens at open/close!
* INPUTS : bPowerDown 1=power off, 0=power on
* bInKernel 1=in kernel (don't call OS), 0=in IST
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS : Don't call OS when in kernel mode
*****************************************************************************/
VOID
private_AudioInPowerHandler(
BOOL bPowerDown,
BOOL bInKernel
)
{
}
VOID
AudioOutPowerHandler(
BOOL bPowerDown
)
{
return; // Power Handling Not Yet Implemented
}
/*****************************************************************************
* FUNCTION : private_AudioInDeinitialize
* DESCRIPTION : Free memory required by driver
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioInDeinitialize(
VOID
)
{
FUNC("+PDD_AudioInDeinitialize");
// DMA Deinitialize
dma_Deinit(pDMA_in);
// AudioRecordingBuffer Release
if( pRecAudioBufferBase ){
VirtualFree((PVOID)pRecAudioBufferBase, 0, MEM_RELEASE);
pRecAudioBufferBase = NULL;
}
FUNC("-PDD_AudioInDisable");
}
/*****************************************************************************
* FUNCTION : private_AudioInStart
* DESCRIPTION : start recording a sound
* INPUTS : pwh: wave header to insert sound into
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveInStart(
PWAVEHDR pwh
)
{
ULONG RegValue;
DWORD i;
FUNC_WPDD("+PDD_WaveInStart");
v_recPage = 0;
// Stop DMA
dma_Stop(pDMA_in);
if (lpFormat2)
{
// Rx Start
module_rxstart();
i = 0;
while ( private_ChangeRecSampleRate(lpFormat2->nSamplesPerSec) == FALSE ){ // Set Sampling Rate
i++;
if(i>5) break;
}
}
//
// DMA Setting
//
// DMA Control Register Setting
RegValue = DCR_DPDS_32BIT |
DCR_DDRMD_MODULE |
DCR_DPDAM_INCREMENT |
DCR_DMDL_MEMORY |
DCR_SPDS_32BIT |
DCR_SDRMD_MODULE |
DCR_SPDAM_FIX |
DCR_SMDL_PERIPHERAL |
DCR_DIP_2PAGE |
DCR_ACMD_ENABLE |
DCR_CT_ENABLE |
DCR_PKMD_DISABLE |
DCR_BTMD_DISABLE |
DCR_DTAU_BYTE |
DCR_DTAC_DISABLE |
DCR_DTAMD_PIN ;
dma_SetControl(pDMA_in, RegValue);
// DMA TransferCompleteInterrupts Enable
dma_InterruptEnable(pDMA_in);
// DMA Enable & AutoTransferMode
RegValue = DCMDR_DMEN;
dma_SetCommand(pDMA_in, RegValue);
// Rx DMA Enable
module_rxdmastart();
v_recPage = 1 - v_recPage;
pDriverGlobals->aud[AUDIO_NO].rec_address = dma_pageRecPhysicalAddress[v_recPage];
pDriverGlobals->aud[AUDIO_NO].inInt = (USHORT)NULL;
FUNC_WPDD("-PDD_WaveInStart");
}
/*****************************************************************************
* FUNCTION : private_AudioInStop
* DESCRIPTION : stop recording a sound
* INPUTS :
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveInStop()
{
FUNC_WPDD("+PDD_WaveInStop");
// Rx Stop
module_rxstop();
// DMA Transfer Stop
dma_Stop(pDMA_in);
FUNC_WPDD("-PDD_WaveInStop");
}
/*****************************************************************************
* FUNCTION : private_AudioInStandby
* DESCRIPTION : stop recording a sound
* INPUTS :
* OUTPUTS : None
* DESIGN NOTES : what is the difference between this and Stop?
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveInStandby()
{
FUNC_WPDD("+PDD_WaveInStandby");
FUNC_WPDD("-PDD_WaveInStandby");
}
/*****************************************************************************
* FUNCTION : private_AudioInClose
* DESCRIPTION : close recording device, powers off
* INPUTS :
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveInClose()
{
FUNC_WPDD("PDD_WaveInClose");
lpFormat2=0;
pDriverGlobals->aud[AUDIO_NO].rec_address = (ULONG)NULL;
pDriverGlobals->aud[AUDIO_NO].inInt = (USHORT)NULL;
RecOpenFlag = 0;
}
/*****************************************************************************
* FUNCTION : private_AudioInOpen
* DESCRIPTION : opens recording sound device, powers on
* INPUTS : lpFormat = what recording parameters to use
* OUTPUTS : MMRESULT - ok if params ok, else a error code
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
MMRESULT
private_WaveInOpen(
LPWAVEFORMATEX lpFormat,
BOOL fQueryFormatOnly
)
{
MMRESULT mmRet = MMSYSERR_NOERROR;
FUNC_WPDD("+PDD_WaveInOpen");
// check simultaneously
mmRet = check_RecInPlay(PlayOpenFlag, RecOpenFlag);
if(mmRet != MMSYSERR_NOERROR){
goto EXIT;
}
// Rx Stop
module_rxstop();
lpFormat2=lpFormat; // for WaveInContinue
// Allow PCM, mono or stereo, 8 or 16 bit at 11, 22, or 44 KHz
if ((lpFormat->wFormatTag != WAVE_FORMAT_PCM) ||
(lpFormat->nChannels != Monaural && lpFormat->nChannels != Stereo) ||
(check_SamplesPerSec(pDriverGlobals->aud[AUDIO_NO].REC_CH,lpFormat->nSamplesPerSec) != TRUE) ||
(lpFormat->wBitsPerSample != SixteenBits && lpFormat->wBitsPerSample != EightBits))
{
mmRet = WAVERR_BADFORMAT;
}
if (fQueryFormatOnly || mmRet != MMSYSERR_NOERROR)
{
goto EXIT;
}
RecOpenFlag = 1;
// Open with the given format. Choose a playback rate from this.
g_pwfx[WAPI_IN] = lpFormat;
if (g_pwfx[WAPI_IN]->wBitsPerSample == EightBits)
{
if (g_pwfx[WAPI_IN]->nChannels == Monaural)
g_pcmtype[WAPI_IN] = PCM_TYPE_M8;
else
g_pcmtype[WAPI_IN] = PCM_TYPE_S8;
}
else
{
if (g_pwfx[WAPI_IN]->nChannels == Monaural)
g_pcmtype[WAPI_IN] = PCM_TYPE_M16;
else
g_pcmtype[WAPI_IN] = PCM_TYPE_S16;
}
// Power on and initialize the AFE
private_AudioInPowerHandler( FALSE, FALSE );
// clear stats
g_dwOverruns = 0;
g_dwFrames = 0;
EXIT:
FUNC_WPDD("-PDD_WaveInOpen");
return(mmRet);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -