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

📄 hac.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -