?? waveoutpdd.c
字號(hào):
//
// Copyright(C) Renesas Technology Corp. 1999-2005. All rights reserved.
//
// WaveDev Driver for ITS-DS7
//
//----------------------------------------------------------------------------
//
// FILE : WAVEOUTPDD.C
// CREATED : 1999. 4.26 (for HD64465 on PFM-DS6)
// MODIFIED : 2005.03.04
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// FUNCTIONS : Playback part PDD of waveform audio driver
// 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.06.15
// - Modified HSSI supported full duplex mode.
// 2004.09.01
// - Created release code for WCE5.0.
// 2005.02.25
// - Removed software volume control.
// 2005.03.04
// - Moved private_AudioFillBuffer 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 <winbase.h>
#include "platform.h"
#include "shx.h"
#include "sh7770.h"
#include "drv_glob.h"
#include "oalintr.h"
#include "wavepdd.h"
#include "waveOutpdd.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_out; // DMA Register (for Playback)
extern DWORD AUDIO_NO; // Audio Driver No.
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 BOOL module_init( PDRIVER_GLOBALS, int );
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 conv_sample(PCM_TYPE, ULONG *, ULONG *);
extern VOID set_DMA_Buffer( LONG,ULONG,ULONG,ULONG *,unsigned int,int,int *);
extern VOID set_volume( ULONG );
extern BOOL check_SamplesPerSec(int, DWORD);
extern BOOL check_PlayInRec(int, int);
extern void SetMute( BOOL );
extern PWAVEFORMATEX g_pwfx[2];
extern PCM_TYPE g_pcmtype[2];
// base pointers
PBYTE pAudioBufferBase; // Audio buffer
extern PDRIVER_GLOBALS pDriverGlobals; // Drivers Globals
// Double Buffer for Audio Playback
ULONG dma_pagePhysicalAddress[2];
extern struct _global_volume
{
ULONG dwMasterVolume;
ULONG dwLineInVolume;
ULONG dwMicVolume;
BOOL fMasterMute;
BOOL fLineInMute;
BOOL fMicMute;
ULONG dwInputSelect;
} g_VolumeSettings;
ULONG v_nNextPage;
static volatile BOOL v_fMoreData[2];// TRUE iff MDD layer has called StopPlay
// v_fMoreData was volatile on D9000
// It could be involved in controlling
// multiple threads.
unsigned int extend_data_count;
unsigned int data_write_count;
// OpenFlag
int RecOpenFlag;
int PlayOpenFlag;
/*****************************************************************************
* FUNCTION : private_AudioOutGetInterruptType
* DESCRIPTION : decodes type of audio interrupt
* INPUTS : None
* OUTPUTS : interrupt type
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
AUDIO_STATE
private_AudioOutGetInterruptType(
VOID
)
{
FUNC_WPDD("+PDD_AudioOutGetInterruptType");
// An audio interrupt has occured. We need to tell the MDD who owns it
// and what state that puts us in.
if ( pDriverGlobals->aud[AUDIO_NO].outInt == (USHORT)NULL )
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: ignore")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_IGNORE; // assume audio-in generated interrupt
}
if (!v_fMoreData[WAPI_OUT])
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: stopped")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_STOPPED;
}
else if (pDriverGlobals->aud[AUDIO_NO].play_address != (ULONG)NULL)
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: playing")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_PLAYING;
}
else
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType:underflow")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_UNDERFLOW;
}
}
/*****************************************************************************
* FUNCTION : private_AudioOutInitialize
* DESCRIPTION : sets up register access for audio-out
* sets DA, DMA, and CMT registers that remain constant
* sets volume to maximum (default)
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
private_AudioOutInitialize(
VOID
)
{
BOOL RET_VALUE;
ULONG SizeOfBuffer;
char here[] = "PDD_AudioOutInitialize";
FUNC_WPDD("+PDD_AudioOutInitialize");
DEBUGMSG(ZONE_TEST, (TEXT("WaveOutpdd.c private_AudioOutInitialize: START\r\n")));
// Get DMA Transfer Buffer Address (for Playback)
get_DMA_Buffer_Address(pDriverGlobals->aud[AUDIO_NO].PLAY_CH, AUDIO_NO, dma_pagePhysicalAddress);
// DMAC Initialize (for Playback)
dma_Init(pDriverGlobals->aud[AUDIO_NO].PLAY_CH, &pDMA_out);
//
// DMA Setting
//
dma_SetPort(pDMA_out, get_DPTR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH));
dma_SetPage(pDMA_out,
0, // Page0
get_DSAR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,0), // Sorce Address
get_DDAR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,0), // Destination Address
get_DTCR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,0)); // Transfer Count
dma_SetPage(pDMA_out,
1, // Page1
get_DSAR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,1), // Sorce Address
get_DDAR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,1), // Destination Address
get_DTCR(pDriverGlobals->aud[AUDIO_NO].PLAY_CH,AUDIO_NO,1)); // Transfer Count
// Module Initialize
if( module_init(pDriverGlobals,AUDIO_NO) == FALSE ){
// DMAC Deinitialize (for Playback)
dma_Deinit( pDMA_out );
}
// Set pointers to virtual addresses of audio buffers
SizeOfBuffer = (AUDIO_DMA_PAGE_SIZE * 2);
pAudioBufferBase = VirtualAlloc( NULL,
SizeOfBuffer,
MEM_RESERVE,
PAGE_NOACCESS);
if (pAudioBufferBase == NULL) {
DEBUGMSG(ZONE_ERROR,(TEXT("Buffer virtual alloc NG!!\r\n")));
module_deinit();
return FALSE;
}
RET_VALUE = VirtualCopy( (PVOID)pAudioBufferBase,
(PVOID)dma_pagePhysicalAddress[0],
(DWORD)SizeOfBuffer,
PAGE_READWRITE | PAGE_NOCACHE);
if (!RET_VALUE){
DEBUGMSG(ZONE_ERROR,(TEXT("Buffer virtual copy NG!!\r\n")));
VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
pAudioBufferBase = NULL;
module_deinit();
dma_Deinit(pDMA_out);
return FALSE;
}
//
// CODEC Initialize
//
if( codec_init() != TRUE ){
VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
pAudioBufferBase = NULL;
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
pDriverGlobals = NULL;
module_deinit();
dma_Deinit(pDMA_out);
return FALSE;
}
// Initialize AudioOutInterrupt Flag
pDriverGlobals->aud[AUDIO_NO].play_address = (ULONG)NULL;
pDriverGlobals->aud[AUDIO_NO].outInt = (USHORT)NULL;
DEBUGMSG(ZONE_TEST, (TEXT("WaveOutpdd.c private_AudioOutInitialize: END\r\n")));
FUNC("-PDD_AudioOutInitialize");
return TRUE;
}
/*****************************************************************************
* FUNCTION : private_AudioOutPowerHandler
* DESCRIPTION : performs power on/off
* INPUTS : bPowerDown 1=power off, 0=power on
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioOutPowerHandler(
BOOL bPowerDown
)
{
BOOL Success;
FUNC("private_AudioOutPowerHandler");
DEBUGMSG(ZONE_TEST, (TEXT("private_AudioOutPowerHandler ---- bPowerDown=%d\r\n"),bPowerDown));
if( bPowerDown )
{
private_AudioOutDeinitialize();
}
else
{ // power up
Success=private_AudioOutInitialize();
}
return; // (see also private_WaveOutClose)
}
/*****************************************************************************
* FUNCTION : private_AudioOutDeinitialize
* DESCRIPTION : Reset playback device to initial state
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioOutDeinitialize(
VOID
)
{
FUNC("+PDD_AudioOutDeinitialize");
// DMA Deinit
dma_Deinit(pDMA_out);
// Module Deinit
module_deinit();
// DMA Transfer Buffer Release
if( pAudioBufferBase ){
VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
pAudioBufferBase = NULL;
}
// Audio Global Buffer Release
if( pDriverGlobals ){
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
pDriverGlobals = NULL;
}
FUNC("-PDD_AudioOutDeinitialize");
}
/*****************************************************************************
* FUNCTION : private_WaveOutStart
* DESCRIPTION : Initiates playback of wave
* INPUTS : wave
* OUTPUTS : None
* DESIGN NOTES : puts double buffer in initial state, starts play
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveOutStart (
PWAVEHDR pwh
)
{
const PPCMWAVEFORMAT pFormat = (PPCMWAVEFORMAT) g_pwfx[WAPI_OUT];
DWORD i;
FUNC_WPDD("+PDD_WaveOutStart");
v_fMoreData[WAPI_OUT] = TRUE; // more data expected
module_txstart(); // Tx Start
i = 0;
while ( private_ChangeSampleRate(pFormat->wf.nSamplesPerSec) == FALSE ){ // Set Sampling Rate
i++;
if(i>5) break;
}
v_nNextPage = 0;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -