📄 wavein.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 + -