⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waveinpdd.c

📁 WinCE5.0BSP for Renesas SH7770
💻 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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -