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

📄 hwctxt.cpp

📁 s3c2443的Wavedev代码,觉对好用.
💻 CPP
📖 第 1 页 / 共 5 页
字号:

BOOL HardwareContext::GetInputMute (void)
{
    return m_fInputMute;
}

MMRESULT HardwareContext::SetInputMute (BOOL fMute)
{
    m_fInputMute = fMute;
    return m_InputDeviceContext.SetGain(fMute ? 0: m_dwInputGain);
}

DWORD HardwareContext::GetInputGain (void)
{
    return m_dwInputGain;
}

MMRESULT HardwareContext::SetInputGain (DWORD dwGain)
{
    m_dwInputGain = dwGain;
    if (! m_fInputMute) {
        m_InputDeviceContext.SetGain(dwGain);
    }
    return MMSYSERR_NOERROR;
}




/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		InitOutputDMA()

Description:	Initializes the DMA channel for output.

Notes:			DMA Channel 2 is used for transmitting output sound
				data from system memory to the AC97 controller.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitOutputDMA()
{
	RETAILMSG(AC97_DEBUG,(_T("+++InitOutputDMA\r\n")));	
	//----- 1. Initialize the DMA channel for output mode and use the first output DMA buffer -----
    if (!g_PhysDMABufferAddr.LowPart)
    {
        DEBUGMSG(TRUE, (TEXT("ERROR:HardwareContext::InitOutputDMA: Invalid DMA buffer physical address.\r\n")));
        return(FALSE);
    }
    v_pDMAregs->DISRC1	= (int)(g_PhysDMABufferAddr.LowPart); 
    v_pDMAregs->DISRCC1 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);				// Source is system bus, increment addr

    //----- 2. Initialize the DMA channel to send data over the AC97 -----
    v_pDMAregs->DIDST1	= (int)(AC_PCMDATA_PHYS); 
    v_pDMAregs->DIDSTC1 |= (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);	// Dest is  periperal bus, fixed addr

	//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
	//		   single tx, single service, AC97 request, no auto-reload, half-word, tx count
	v_pDMAregs->DCON1	= (  HANDSHAKE_MODE | GENERATE_INTERRUPT 
#if	DMA_FLAG	// Kingfish2 AC97
//					| TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2 ) );				
					| TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4 ) );
#else						   									
//					| NO_DMA_AUTO_RELOAD | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );	
					| NO_DMA_AUTO_RELOAD | TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4 ) );
#endif						   

	v_pDMAregs->DMAREQSEL1 = (DMAREQSEL_PCMOUT) + (1<<0); 
	//----- 4. Reset the playback pointers -----
	AUDIO_RESET_PLAYBACK_POINTER();
	
	DEBUGMSG(ZONE_FUNCTION,(TEXT("---InitOutputDMA\n")));
        RETAILMSG(AC97_DEBUG,(_T("---InitOutputDMA\r\n")));
	return TRUE;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		StartOutputDMA()

Description:	Starts outputting the sound data to the audio codec
				chip via DMA.

Notes:			Currently, both playback and record share the same
				DMA channel.  Consequently, we can only start this
				operation if the input channel isn't using DMA.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::StartOutputDMA()
{
	RETAILMSG(AC97_DEBUG1,(_T("+++StartOutputDMA\r\n")));	
	
	if(!m_OutputDMARunning && (m_Dx == D0) )
    {
        //----- 1. Initialize our buffer counters -----
        m_OutputDMARunning=TRUE;
        m_OutBytes[OUT_BUFFER_A]=m_OutBytes[OUT_BUFFER_B]=0;

        //----- 2. Prime the output buffer with sound data -----
		m_OutputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;	
		ULONG OutputTransferred = TransferOutputBuffers(m_OutputDMAStatus);

      	//RETAILMSG(AC97_DEBUG,(_T("StartOutputDMA:OutputTransferred =>0x%x\n"), OutputTransferred));        
		//----- 3. If we did transfer any data to the DMA buffers, go ahead and enable DMA -----
		if(OutputTransferred)
        {
			//----- 4. Configure the DMA channel for playback -----
			if(!InitOutputDMA())
			{
				DEBUGMSG(ZONE_ERROR, (TEXT("HardwareContext::StartOutputDMA() - Unable to initialize output DMA channel!\r\n")));
				goto START_ERROR;
			}
			// Kingfish2. AC97
#if	DMA_FLAG
			v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<12)) | (0x2<<12);	// 0x2 = DMA
#else
			v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<12)) | (0x1<<12);	// 0x1 = PIO
#endif	

			//----- 5. Make sure the audio isn't muted -----
			AudioMute(DMA_CH_OUT, FALSE);					
			RETAILMSG(AC97_DEBUG,(_T("Start DMA Controller\r\n")));	
			//----- 6. Start the DMA controller -----
			AUDIO_RESET_PLAYBACK_POINTER();
			SELECT_AUDIO_DMA_OUTPUT_BUFFER_A();
			Codec_channel();								// Turn ON output channel
			// charlie, start A buffer
			
			AUDIO_OUT_DMA_ENABLE();
#if DMA_FLAG			
	        // wait for DMA to start.
	        delay_count = 0;

	        while((v_pDMAregs->DSTAT1&0xfffff)==0){
#if WAIT_DMA_END
				Sleep(1);
#else
   				if( delay_count++ > DELAY_COUNT )	break;
#endif
	        }        
	        // change the buffer pointer
	        SELECT_AUDIO_DMA_OUTPUT_BUFFER_B();
	        // Set DMA for B Buffer
#endif

        }
        else    // We didn't transfer any data, so DMA wasn't enabled
        {
            m_OutputDMARunning=FALSE;
        }
    }
    
    RETAILMSG(AC97_DEBUG,(_T("---StartOutputDMA\r\n")));	

	return TRUE;

START_ERROR:
	return FALSE;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		StopOutputDMA()

Description:	Stops any DMA activity on the output channel.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
void HardwareContext::StopOutputDMA()
{
	RETAILMSG(AC97_DEBUG1,(_T("StopOutputDMA:%d\r\n"),m_OutputDMARunning));	
	//----- 1. If the output DMA is running, stop it -----
    if (m_OutputDMARunning)
	{
		m_OutputDMAStatus = DMA_CLEAR;				
		AUDIO_OUT_DMA_DISABLE();
		AUDIO_OUT_CLEAR_INTERRUPTS();
		// Kingfish2 AC97
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<12)) | (0x0<<12);	// 0x0 = OFF
		AudioMute(DMA_CH_OUT, TRUE);	
	   }
	

	m_OutputDMARunning = FALSE;
	Codec_channel();
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		InitInputDMA()

Description:	Initializes the DMA channel for input.

Notes:			***** NOT IMPLEMENTED *****

				The following routine is not implemented due to a
				hardware bug in the revision of the Samsung SC2443
				CPU this driver was developed on.  See the header
				at the top of this file for details.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitInputDMA()
{

	DEBUGMSG(ZONE_FUNCTION,(TEXT("+++InitInputDMA\n")));
	RETAILMSG(AC97_DEBUG1,(TEXT("+++InitInputDMA\n")));
    if (!g_PhysDMABufferAddr.LowPart)
    {
        DEBUGMSG(TRUE, (TEXT("ERROR:HardwareContext::InitInputDMA: Invalid DMA buffer physical address.\r\n")));
        return(FALSE);
    }

	//============================ Configure DMA Channel 1 ===========================
	//------ On platforms with the revsion of the Samsung SC2443 CPU with the AC97 SLAVE bug fix, this -----
	//		 code can be used to configure DMA channel 1 for input.

	//----- 1. Initialize the DMA channel for input mode and use the first input DMA buffer -----
#if AC97_RECORD_MICIN
	v_pDMAregs->DISRC2	= (int)AC_MICDATA_PHYS;	
#else
	v_pDMAregs->DISRC2	= (int)AC_PCMDATA_PHYS;	
#endif    
	v_pDMAregs->DISRCC2 = (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);				// Source is periperal bus, fixed addr

    //----- 2. Initialize the DMA channel to receive data over the AC97 -----
    v_pDMAregs->DIDST2	= (int)(RECORD_DMA_BUFFER_PHYS); 
    v_pDMAregs->DIDSTC2 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);	// Destination is system bus, increment addr

	//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
	//		   single tx, single service, AC97 request, no auto-reload, half-word, tx count
#if AC97_RECORD_MICIN	
	v_pDMAregs->DCON2	= (  HANDSHAKE_MODE | GENERATE_INTERRUPT 
#else
	v_pDMAregs->DCON2	= (  HANDSHAKE_MODE | GENERATE_INTERRUPT 
#endif
#if DMA_FLAG
#if (INCHANNELS==2)	
						   | TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4) );
#else						   
						   | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
#endif
#else /* DMA_FLAG */
						   | NO_DMA_AUTO_RELOAD | TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4) );
						   //| NO_DMA_AUTO_RELOAD | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
#endif /* DMA_FLAG */

#if AC97_RECORD_MICIN
	v_pDMAregs->DMAREQSEL2 = (DMAREQSEL_MICIN) + (1<<0); 
#else
	v_pDMAregs->DMAREQSEL2 = (DMAREQSEL_PCMIN) + (1<<0); 
#endif
RETAILMSG(AC97_DEBUG1,(TEXT("---InitInputDMA\n")));
	return(TRUE);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		StartInputDMA()

Description:	Starts inputting the recorded sound data from the 
				audio codec chip via DMA.

Notes:			***** NOT IMPLEMENTED *****

				The following routine is not implemented due to a
				hardware bug in the revision of the Samsung SC2443
				CPU this driver was developed on.  See the header
				at the top of this file for details.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::StartInputDMA()
{
	
	DEBUGMSG(ZONE_FUNCTION,(TEXT("+++StartInputDMA\n")));
   	RETAILMSG(AC97_DEBUG1,(TEXT("+++StartInputDMA\n")));
//	RETAILMSG(AC97_DEBUG1,(TEXT("m_InputDMARunning=%d\r\n"),m_InputDMARunning));
	if(!m_InputDMARunning)
    {
        //----- 1. Initialize our buffer counters -----
        m_InputDMARunning=TRUE;
		Codec_channel();        // Turn On Input channel
        m_InBytes[IN_BUFFER_A]=m_InBytes[IN_BUFFER_B]=0;

        //----- 2. Prime the output buffer with sound data -----
		m_InputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;	

		//----- 3. Configure the DMA channel for record -----
		if(!InitInputDMA())
		{
			DEBUGMSG(ZONE_ERROR, (TEXT("HardwareContext::StartInputDMA() - Unable to initialize input DMA channel!\r\n")));
			goto START_ERROR;
		}
		// Kingfish2 AC97
#if AC97_RECORD_MICIN
#if	DMA_FLAG
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<8)) | (0x2<<8);	// 0x2 = DMA
#else
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<8)) | (0x1<<8);	// 0x1 = PIO
#endif	

#else // AC97_RECORD_MICIN

#if	DMA_FLAG
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<10)) | (0x2<<10);	// 0x2 = DMA
#else
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<10)) | (0x1<<10);	// 0x1 = PIO
#endif	

#endif

		//----- 4. Make sure the audio isn't muted -----
		AudioMute(DMA_CH_MIC, FALSE);					

		//----- 5. Start the input DMA -----
		AUDIO_RESET_RECORD_POINTER();
		SELECT_AUDIO_DMA_INPUT_BUFFER_A();

		Codec_channel();        // Turn On Input channel
		//v_pDMAregs->DMASKTRIG2 |= ENABLE_DMA_CHANNEL;
		AUDIO_IN_DMA_ENABLE();

	
#if DMA_FLAG			
        // wait for DMA to start.
        delay_count = 0;
        while((v_pDMAregs->DSTAT2&0xfffff)==0){
#if WAIT_DMA_END
			Sleep(1);
#else
        	if( delay_count++ > DELAY_COUNT )	break;
#endif
        } 

        // change the buffer pointer
        SELECT_AUDIO_DMA_INPUT_BUFFER_B();
#endif				
    }
    DEBUGMSG(ZONE_FUNCTION,(TEXT("---StartInputDMA\n")));
	RETAILMSG(AC97_DEBUG1,(TEXT("---StartInputDMA 0x%X\n"),v_pAC97regs->AC_GLBCTRL));
	
	return(TRUE);

START_ERROR:
	return(FALSE);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		StopInputDMA()

Description:	Stops any DMA activity on the input channel.

Notes:			***** NOT IMPLEMENTED *****

				The following routine is not implemented due to a
				hardware bug in the revision of the Samsung SC2443
				CPU this driver was developed on.  See the header
				at the top of this file for details.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
void HardwareContext::StopInputDMA()
{

	//----- 1. If the output DMA is running, stop it -----
	RETAILMSG(AC97_DEBUG1,(TEXT("+++StopInputDMA\n")));
    if (m_InputDMARunning)
	{
		AUDIO_IN_DMA_DISABLE(); // jylee
		AUDIO_IN_CLEAR_INTERRUPTS();	
		
		m_InputDMAStatus = DMA_CLEAR;				
		
		// Kingfish2 AC97
#if AC97_RECORD_MICIN		
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<8)) | (0x0<<8);	// 0x0 = DMA OFF
#else
		v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3<<10)) | (0x0<<10);	// 0x0 = DMA OFF
#endif

		AudioMute(DMA_CH_MIC, TRUE);		
    }

	m_InputDMARunning = FALSE;
	Codec_channel();
	RETAILMSG(AC97_DEBUG1,(TEXT("---StopInputDMA\n")));
}


DWORD HardwareContext::GetInterruptThreadPriority()
{
    HKEY hDevKey;
    DWORD dwValType;
    DWORD dwValLen;
    DWORD dwPrio = 249; // Default priority

    hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
    if (hDevKey)
    {
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
            hDevKey,
            TEXT("Priority256"),
            NULL,
            &dwValType,
            (PUCHAR)&dwPrio,
            &dwValLen);
        RegCloseKey(hDevKey);
    }

⌨️ 快捷键说明

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