?? hac.c
字號:
ulSrcSampleCount--;
}
}
/*****************************************************************************
* FUNCTION : AudioGetBuffer_S16
* DESCRIPTION : get audio DMA buffer and convert sample(16bit Stereo)
* INPUTS : pSrcPtr - audio buffer address
* pDstPtr - wave audio buffer address
* ulSrcSampleCount - sampling count
* OUTPUTS : None
* DESIGN NOTES : convert packed 16bit to 16bit stereo
* CAUTIONS :
*****************************************************************************/
VOID
AudioGetBuffer_S16 (
PUSHORT pSrcPtr,
PULONG pDstPtr,
ULONG ulSrcSampleCount
)
{
ULONG ulSample;
while (ulSrcSampleCount > 0) {
// Mic
if( g_VolumeSettings.dwInputSelect == WPDMX_LINE_MIC ){
pSrcPtr++;
ulSample = READ_REGISTER_USHORT(pSrcPtr++);
((PPCM_SAMPLE)pDstPtr)->s16.sample_left = (USHORT)ulSample;
((PPCM_SAMPLE)pDstPtr)->s16.sample_right = (USHORT)ulSample;
}
// Line In
else{
ulSample = READ_REGISTER_USHORT(pSrcPtr++);
((PPCM_SAMPLE)pDstPtr)->s16.sample_right = (USHORT)ulSample;
ulSample = READ_REGISTER_USHORT(pSrcPtr++);
((PPCM_SAMPLE)pDstPtr)->s16.sample_left = (USHORT)ulSample;
}
pDstPtr++;
ulSrcSampleCount--;
}
}
/*****************************************************************************
* FUNCTION : private_AudioInContinue
* DESCRIPTION : continuerecording a sound - occurs at audio in interrupt
* INPUTS : pwh: wave header to insert sound into
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS : pwh can be null for no buffers available
*****************************************************************************/
VOID
private_WaveInContinue(
PWAVEHDR pwh
)
{
ULONG *lpAudioBuffer;
LONG nDstLen, nSrcLen;
ULONG nSampleCount,nSampleUnit;
FUNC_VERBOSE("+PDD_WaveInContinue");
switch (g_pcmtype[WAPI_IN])
{
case PCM_TYPE_S16:
nSampleUnit = 4; // 2 words per sample unit
break;
case PCM_TYPE_M16:
nSampleUnit = 2; // 1 word per sample unit
break;
case PCM_TYPE_S8:
nSampleUnit = 2; // 2 bytes per sample unit
break;
case PCM_TYPE_M8:
nSampleUnit = 1; // 1 byte per sample unit
break;
} // end switch
lpAudioBuffer = (PULONG)(pRecAudioBufferBase + ((1 - v_recPage) * AUDIO_DMA_PAGE_SIZE));
// process raw audio samples
// copy processed audio sample into WAVEHDR
nSrcLen = HAC_R_DMA_PAGE_SIZE / sizeof(ULONG);
while (nSrcLen > 0) {
try
{
if( pwh == 0 ) break;
nDstLen = pwh->dwBufferLength - pwh->dwBytesRecorded;
if (nDstLen <= 0)
{
DEBUGMSG(ZONE_TEST,(TEXT("WAVE RECORD: NEXT BUFFER\r\n")));
pwh = pwh->lpNext;
if( pwh == 0 )
{
DEBUGMSG(ZONE_TEST,(TEXT("WAVE RECORD: NO BUFFERS\r\n")));
break;
}
}
else{
nSampleCount = nDstLen / nSampleUnit;
if (nSrcLen < (LONG)nSampleCount) nSampleCount = nSrcLen;
switch( g_pcmtype[WAPI_IN] )
{
case PCM_TYPE_S16: // 16 bit stereo
AudioGetBuffer_S16((PUSHORT)lpAudioBuffer, (PULONG)(pwh->lpData + pwh->dwBytesRecorded), nSampleCount);
break;
case PCM_TYPE_M16: // 16 bit mono
AudioGetBuffer_M16((PUSHORT)lpAudioBuffer, (PUSHORT)(pwh->lpData + pwh->dwBytesRecorded), nSampleCount);
break;
case PCM_TYPE_S8: // 8 bit stereo
AudioGetBuffer_S8((PUSHORT)lpAudioBuffer, (PUSHORT)(pwh->lpData + pwh->dwBytesRecorded), nSampleCount);
break;
case PCM_TYPE_M8: // 8 bit mono
AudioGetBuffer_M8((PUSHORT)lpAudioBuffer, (PBYTE)(pwh->lpData + pwh->dwBytesRecorded), nSampleCount);
break;
default: // really screwed up if we're here!
DEBUGMSG(ZONE_ERROR,(TEXT("WAVE RECORD: invalid pcm type %d\r\n"),
g_pcmtype[WAPI_IN] ));
break;
} //end switch
pwh->dwBytesRecorded += nSampleCount * nSampleUnit;
nSrcLen -= nSampleCount;
lpAudioBuffer += nSampleCount;
}
}
except ( 1 )
{
DUMPEXCEPTION();
}
} // end while
v_recPage = 1 - v_recPage;
pDriverGlobals->aud[AUDIO_NO].rec_address = dma_pageRecPhysicalAddress[v_recPage];
pDriverGlobals->aud[AUDIO_NO].inInt = (USHORT)NULL;
FUNC_VERBOSE("-PDD_WaveInContinue");
}
/*****************************************************************************
* FUNCTION : set_volume
* DESCRIPTION : sample set to DMA Buffer
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
set_volume( ULONG v )
{
ULONG Loop_r;
ULONG lvol, rvol;
Loop_r = 0;
lvol = (USHORT)((0x0000F800 - (v & 0x0000F800)) >> 3);
rvol = (USHORT)((0xF8000000 - (v & 0xF8000000)) >> 27);
ulMasterVol = (lvol | rvol)<<4;
if (v == 0) {
ulMasterVol |= (0x8000 << 4); // bit 15 means mute. Use this to get total attenuation.
}
DEBUGMSG(ZONE_TEST,(TEXT("set_volume 0x%08x => 0x%08x\r\n"),v ,ulMasterVol));
retry_set_volume:
Loop_r++;
if (Write_codec( (ULONG)0x00002000, ulMasterVol ) == FALSE){ // Set Master Volume
DEBUGMSG(ZONE_ERROR,(TEXT("Change Master Volume Error !\r\n")));
if(Loop_r < AC97_RETRTY_MAX) goto retry_set_volume;
RETAILMSG(1, (TEXT("AC97: Change Master Volume Error!\r\n")));
}
}
/*****************************************************************************
* FUNCTION : SetMute
* DESCRIPTION : Mute
* INPUTS : Codec Register, Mute
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
void SetMute(BOOL muted)
{
if (muted) {
ulMasterVol |= (0x8000 << 4);
}
else{
ulMasterVol &= ~(0x8000 << 4);
}
Write_codec( (ULONG)0x00002000, (ULONG)ulMasterVol );
}
/*****************************************************************************
* FUNCTION : check_SamplesPerSec
* DESCRIPTION : Check Samples Per Sec
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
check_SamplesPerSec(
int ch,
DWORD s
)
{
// Samples Per Sec is 8kHz, 11.025kHz, 22.050kHz, 44.1kHz, 48kHz
if( s == 8000 || s == 11025 || s == 22050 || s == 44100 || s == 48000 ){
return TRUE;
}
else{
return FALSE;
}
}
/*****************************************************************************
* FUNCTION : set_aud_index
* DESCRIPTION : set aud index
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
set_aud_index(
PDRIVER_GLOBALS globals,
int i
)
{
globals->aud_index_hac = i;
}
/*****************************************************************************
* FUNCTION : check_PlayInRec
* DESCRIPTION : Check Playback in Recording(simultaneously)
* INPUTS : PlayFlag - device open flag for playback
* RecFlag - device open flag for recording
* OUTPUTS : Return MMSYSERR_NOERROR for success, other for failure
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
MMRESULT
check_PlayInRec(
int PlayFlag,
int RecFlag
)
{
return MMSYSERR_NOERROR;
}
/*****************************************************************************
* FUNCTION : check_RecInPlay
* DESCRIPTION : Check Recording in Playback(simultaneously)
* INPUTS : PlayFlag - device open flag for playback
* RecFlag - device open flag for recording
* OUTPUTS : Return MMSYSERR_NOERROR for success, other for failure
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
MMRESULT
check_RecInPlay(
int PlayFlag,
int RecFlag
)
{
return MMSYSERR_NOERROR;
}
VOID codec_updateRecordSelect( USHORT input_select )
{
// Set Record Select
Write_codec( (ULONG)0x0001A000, ((ULONG)input_select) << 4 );
}
VOID codec_updateRecordGain( ULONG regval )
{
// Set Record Gain
Write_codec( (ULONG)0x0001C000, regval << 4 );
}
/*****************************************************************************
* FUNCTION : UpdateInputSelect
* DESCRIPTION : Input Select mic or line-in
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
void UpdateInputSelect(void)
{
USHORT input_select;
ULONG volume, regval;
ULONG lvol, rvol;
switch (g_VolumeSettings.dwInputSelect) {
case WPDMX_LINE_MIC:
input_select = 0x0000;
if (g_VolumeSettings.fMicMute) {
volume = 0;
}
else {
volume = g_VolumeSettings.dwMicVolume & 0xffff;
volume = volume | (volume << 16); // incoming volume is mono, cvt. to stereo
}
break;
case WPDMX_LINE_IN:
input_select = 0x0404;
if (g_VolumeSettings.fLineInMute) {
volume = 0;
}
else {
volume = g_VolumeSettings.dwLineInVolume;
}
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("UpdateInputSelect: illegal setting %04x\r\n"), g_VolumeSettings.dwInputSelect));
return;
}
if (volume == 0) {
regval = 0x8000;
}
else {
lvol = (USHORT)((0xF8000000 - (volume & 0xF8000000)) >> 19);
rvol = (USHORT)((0x0000F800 - (volume & 0x0000F800)) >> 11);
regval = (lvol | rvol);
}
DEBUGMSG(ZONE_TEST, (TEXT("UpdateInputSelect: sel=%04x vol=%04x\r\n"), input_select, regval));
codec_updateRecordSelect( input_select );
codec_updateRecordGain( regval );
}
/*****************************************************************************
* FUNCTION : private_SetMixerValue
* DESCRIPTION : Set Mixer Value
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
MMRESULT
private_SetMixerValue(DWORD dwControl, DWORD dwSetting)
{
DWORD dwControlType = dwSetting & WPDMX_CTL_MASK;
DWORD dwLine = dwSetting & WPDMX_LINE_MASK;
DEBUGMSG(ZONE_TEST, (TEXT("private_SetMixerValue(%04x, %08x)\r\n"), dwControl, dwSetting));
switch (dwControl) {
// volume controls
case WPDMX_MASTER_VOL:
private_waveOutSetVolume(dwSetting);
break;
case WPDMX_LINEIN_VOL:
g_VolumeSettings.dwLineInVolume = dwSetting;
UpdateInputSelect();
break;
case WPDMX_MIC_VOL:
g_VolumeSettings.dwMicVolume = dwSetting;
UpdateInputSelect();
break;
// Mute controls
case WPDMX_MASTER_MUTE:
g_VolumeSettings.fMasterMute = dwSetting;
SetMute(g_VolumeSettings.fMasterMute);
break;
case WPDMX_LINEIN_MUTE:
g_VolumeSettings.fLineInMute = dwSetting;
UpdateInputSelect();
break;
case WPDMX_MIC_MUTE:
g_VolumeSettings.fMicMute = dwSetting;
UpdateInputSelect();
break;
// The input Mux
case WPDMX_INPUT_MUX:
g_VolumeSettings.dwInputSelect = dwSetting;
UpdateInputSelect();
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("private_SetMixerValue: unsupported control %d\r\n"), dwControl));
return MMSYSERR_NOTSUPPORTED;
}
return MMSYSERR_NOERROR;
}
/*****************************************************************************
* FUNCTION : private_SetDefaultVolume
* DESCRIPTION : Set master volume and default input
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
void private_SetDefaultVolume()
{
// Set the global master volume to max
private_waveOutSetVolume(0xffffffff);
#if AC97_USE_MIC == 1
private_SetMixerValue(WPDMX_INPUT_MUX, WPDMX_LINE_MIC);
#endif
#if AC97_USE_LINE_IN == 1
private_SetMixerValue(WPDMX_INPUT_MUX, WPDMX_LINE_IN);
#endif
// set default for input
private_SetMixerValue(WPDMX_MIC_VOL, 0xAAAAAAAA);
private_SetMixerValue(WPDMX_MIC_MUTE, 0);
private_SetMixerValue(WPDMX_LINEIN_VOL, 0xAAAAAAAA);
private_SetMixerValue(WPDMX_LINEIN_MUTE, 0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -