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

📄 wavein.c

📁 基于AMD Au1200(MIPS32处理器)的AC97驱动源码
💻 C
字号:
/*++
Copyright (c) 2001-2004  BSQUARE Corporation.  All rights reserved.

Module Name:

    wavein.c

Module Description:

    This module contains the implementation of the audio input 
    driver.

Author:

    Ian Rae 25-April-2001

Revision History:

	Ian Rae January 2004 - modified for Au1550 DDMA API

--*/
#include <windows.h>
#include <bceddk.h>
#include "ac97.h"
#include "ac97aud.h"
#include "au1kac97.h"

#include <wavedbg.h>

//#undef  DEBUGMSG
//#define DEBUGMSG(cond, msg)  NKDbgPrintfW##msg

extern PWAVE_DEVICE_INSTANCE WaveDevice;

#define AVERAGE_ST_TO_MO

// number of right shifts to covert a 16bit sample to 8bit
#define REC_SAMP_SCALE  (8)


static
SHORT
StereoToMono(
	IN SHORT leftSample,
	IN SHORT rightSample
	)
{
#ifdef AVERAGE_ST_TO_MO
	LONG average;

	average = leftSample + rightSample;
	average /= 2;

	return (SHORT)average;
#else
	return rightSample;
#endif
}

VOID
EmptyDmaBufferHW(
	IN OUT PWAVE_RESOURCE WaveResource,
	IN PUSHORT srcBuffer,
	IN ULONG  srcLength
	)
/*++

--*/
{
	BOOLEAN  data16;
	BOOLEAN  stereo;
	ULONG    samplesPerSecond;
	SHORT   *srcData;
	CHAR    *destData8;
	SHORT   *destData16;
	PWAVEHDR  Header;
	ULONG    iterations,i;
	SHORT   sampleLeft, sampleRight;
	ULONG    destBytesRemaining;


	samplesPerSecond = WaveResource->WaveFormat.nSamplesPerSec;
	data16 = (WaveResource->WaveFormat.wBitsPerSample == 16);
	stereo = (WaveResource->WaveFormat.nChannels == 2);

	srcData = srcBuffer;

	Header = WaveResource->WaveHeader;

	if( Header==NULL )
	{
		DEBUGMSG( 1, (TEXT("EmptyDmaBufferHW: NULL Header.\r\n")));
		goto ErrorReturn;
	}

    DEBUGMSG(0, (
             TEXT("EmptyDmaBufferHW: Buffer information:\r\n")
             TEXT("    Length=%u  Recorded=%u  16-bit=%u  Stereo=%u")
             TEXT("  Rate=%u.\r\n"),
             Header->dwBufferLength,
             Header->dwBytesRecorded,
             (ULONG)data16,
             (ULONG)stereo,
             samplesPerSecond));

	destBytesRemaining = Header->dwBufferLength - Header->dwBytesRecorded;
	destData8 = Header->lpData + Header->dwBytesRecorded;
	destData16 = (SHORT*)destData8;


    iterations = WaveResource->DmaBufferSize/BYTES_PER_SAMPLE; 

	for( i=0; i<iterations; i++ )
	{
		// Check that we aren't at the end of the output buffer already
		// If we are then mark this buffer as complete and move on to the next

		if( destBytesRemaining == 0 )
		{
			Header->dwBytesRecorded = Header->dwBufferLength;
			DEBUGMSG(0, (TEXT("EmptyDmaBufferHW: DMA buffer emptied.\r\n")
						 TEXT("    Header: Length=%u, Recorded=%u\r\n"),
						 Header->dwBufferLength,
						 Header->dwBytesRecorded ));
			Header = Header->lpNext;

			if( Header == NULL )
			{
				RETAILMSG(1, (TEXT("EmptyDmaBufferHW: NULL wave buffer found.\r\n")));
				goto dataDone;

			}

			DEBUGMSG(0, (TEXT("EmptyDmaBufferHW: Chained to new wave buffer.\r\n")
			             TEXT("     Length=%u Recorded=%u.\r\n"),
						 Header->dwBufferLength,
						 Header->dwBytesRecorded));

			destBytesRemaining = Header->dwBufferLength - Header->dwBytesRecorded;

			if( destBytesRemaining == 0)
			{
				DEBUGMSG(0, (TEXT("EmptyDmaBufferHW: Empty buffer found.\r\n")));
                break;
            }
            else
			{
				destData8 = Header->lpData + Header->dwBytesRecorded;
                destData16 = (USHORT*)destData8;
            }
		}

		sampleLeft = *srcData++;
		sampleRight = *srcData++;

		if( data16 )
		{
			// 16bit destination data
			if( stereo )
			{
				*destData16++ = sampleLeft;
				*destData16++ = sampleRight;
			}
			else
			{
				// Mono, store average of left and right
				sampleLeft = StereoToMono( sampleLeft, sampleRight );
				*destData16++ = sampleLeft;
			}
		}
		else
		{
			// 8bit destination data
			if( stereo )
			{
				*destData8++ = (CHAR)((sampleLeft>>REC_SAMP_SCALE)+128);
				*destData8++ = (CHAR)((sampleRight>>REC_SAMP_SCALE)+128);
			}
			else
			{
				// Mono, store average of left and right
				sampleLeft = StereoToMono( sampleLeft, sampleRight );
				*destData8++ = (CHAR)((sampleLeft>>REC_SAMP_SCALE)+128);
			}
		}
		// Adjust bytes remaining according to whether
		// stream is 16bit or stereo
		destBytesRemaining -= ((stereo ? 2:1) * (data16 ? 2:1 ));
	}

	Header->dwBytesRecorded = (Header->dwBufferLength - destBytesRemaining);

dataDone:
	WaveResource->WaveHeader = Header;

ErrorReturn:
	return;
}


//
// Exported Routines
//

VOID
WaveInStart(
	IN OUT PWAVE_RESOURCE WaveResource,
	IN OUT PWAVE_RESOURCE WaveOutResource,
	IN OUT PWAVEHDR WaveHeader
	)

/*++

Routine Description:

	This routine handles the set up of a new wave input stream.

Arguments

	WaveResource - Pointer to the wave resource structure corresponding to the
		stream to be started.
	
	WaveOutResource - Pointer to the wave resource structure corresponding to the
		output stream that will provide a clock for input data.

	WaveHeader - Pointer to the wave header information.

Return Value:

	None.

--*/

{
	ULONG *Buffer=NULL;

	WaveResource->MoreData = TRUE;

    //
    // Ensure the DMA channel is off off and any status bits are cleared.
    //

    ShutdownDma(WaveResource);

    //
    // Store a copy of the specified wave header pointer into the resource
    // structure.
    //

    WaveResource->WaveHeader = WaveHeader;

	HalSetDMAForReceive(WaveDevice->DMAChannelInput);

	DEBUGMSG(1, (
             TEXT("WaveInStart: Starting DMA.\r\n")));

 	// Start the RX DMA
	StartDma(WaveResource);
}



VOID
WaveInContinue (
    IN OUT PWAVE_RESOURCE WaveResource,
	IN OUT PWAVE_RESOURCE WaveOutResource,
    IN OUT PWAVEHDR WaveHeader
    )

/*++

Routine Description:

    This routine handles continuation of a recording audio input stream.

Arguments:

	WaveResource - Pointer to the wave resource structure corresponding to the
		stream to be started.
	
	WaveOutResource - Pointer to the wave resource structure corresponding to the
		output stream that will provide a clock for input data.

    WaveHeader - Pointer to the wave header information.

Return Value:

    None.

--*/

{
	PULONG Buffer=NULL;
	ULONG  BufferLength=0;

	WaveResource->WaveHeader = WaveHeader;

	// Get full buffer
	Buffer = HalGetNextDMABuffer(WaveDevice->DMAChannelInput);
	// Empty the buffer
	EmptyDmaBufferHW( WaveResource, (PUSHORT)Buffer, WaveResource->DmaBufferSize );
	// Give it back to the DMA
	HalActivateDMABuffer(WaveDevice->DMAChannelInput,
	                     Buffer,
						 WaveResource->DmaBufferSize);

	InterruptDone(WaveResource->SysIntr);
}



VOID
WaveInStop(
	IN OUT PWAVE_RESOURCE WaveResource,
	IN OUT PWAVE_RESOURCE WaveOutResource
	)

/*++

Routine Description:

	This routines handles stopping of the audio input stream. DMA transfers are halted
	and buffer data is handled appropriately.

Arguments:

	WaveResource - Pointer to the wave resource structure corresponding to the
		stream to be started.

Return Value:

	None.

--*/

{
	ShutdownDma(WaveResource);
	WaveResource->MoreData = FALSE;
}

⌨️ 快捷键说明

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