?? waveout.c
字號:
/*++
Copyright (c) 1999-2004 BSQUARE Corporation. All rights reserved.
Module Name:
waveout.c
Module Description:
This module contains the implementation of the audio output driver.
Author:
Revision History:
--*/
#include <windows.h>
#include <bceddk.h>
#include "psc_i2s.h"
#include <wavedbg.h>
extern PWAVE_DEVICE_INSTANCE WaveDevice;
extern PWAVE_RESOURCE WaveOutResource;
//
// Private Routines.
//
static int
FillOutputBuffer (
IN OUT PWAVE_RESOURCE WaveResource
)
{
PWAVEHDR Header = WaveResource->WaveHeader;
PUCHAR pDMABuffer;
ULONG bytesCopied;
// Check Wave header is valid
if ((Header==NULL) || (Header->dwBufferLength==0)) {
return 0;
}
pDMABuffer = HalGetNextDMABuffer(WaveDevice->DMAChannelOutput);
// copy as much data as possible
bytesCopied = min(WaveResource->DmaBufferSize, (Header->dwBufferLength-Header->dwBytesRecorded));
// copy the data
memcpy(pDMABuffer, Header->lpData+Header->dwBytesRecorded, bytesCopied);
// Update bytes recorded
Header->dwBytesRecorded += bytesCopied;
// Send DMA buffer
HalActivateDMABuffer(WaveDevice->DMAChannelOutput, pDMABuffer, bytesCopied);
return bytesCopied;
}
static int
FillTwoOutputBuffers (
IN OUT PWAVE_RESOURCE WaveResource
)
{
PWAVEHDR Header = WaveResource->WaveHeader;
PUCHAR pDMABuffer;
ULONG bytesCopied;
// Check Wave header is valid
if ((Header == NULL) || (Header->dwBufferLength==0)) {
return 0;
}
// work out how much data we can copy
bytesCopied = min(WaveResource->DmaBufferSize,
(Header->dwBufferLength-Header->dwBytesRecorded)/2);
// Do the first buffer
pDMABuffer = HalGetNextDMABuffer(WaveDevice->DMAChannelOutput);
memcpy(pDMABuffer, Header->lpData+Header->dwBytesRecorded, bytesCopied);
Header->dwBytesRecorded += bytesCopied;
// Send DMA buffer
HalActivateDMABuffer(WaveDevice->DMAChannelOutput, pDMABuffer, bytesCopied);
// Now do the second buffer
pDMABuffer = HalGetNextDMABuffer(WaveDevice->DMAChannelOutput);
memcpy(pDMABuffer, Header->lpData+Header->dwBytesRecorded, bytesCopied);
Header->dwBytesRecorded += bytesCopied;
// Send DMA buffer
HalActivateDMABuffer(WaveDevice->DMAChannelOutput, pDMABuffer, bytesCopied);
return bytesCopied*2;
}
//
// Exported Routines.
//
MMRESULT
GetOutputVolume(
IN PWAVE_DEVICE_INSTANCE WaveInstance,
OUT PULONG VolumeSetting
)
/*++
Routine Description:
Arguments:
VolumeSetting - Pointer to the volume variable.
Return Value:
Returns MMSYSERR_NOERROR if successful, MMSYSERR_NOMEM if
unsuccessful. Note that this is probably not a good error
code to return, but it's the best of the bunch to choose from.
--*/
{
ULONG Volume = 0;
Volume = CodecGetVolume(WaveInstance->hSMBus);
*VolumeSetting = Volume;
return MMSYSERR_NOERROR;
}
MMRESULT
SetOutputVolume(
IN PWAVE_DEVICE_INSTANCE WaveInstance,
IN ULONG VolumeSetting
)
/*++
Routine Description:
Takes the input volume setting and sets the attenuation
accordingly. The input volume has a scale from 0 to 0xFFFF,
where 0 is for silence and 0xFFFF for the highest volume
setting. Note that the high order 16-bits are masked
because for stereo sound, it is the right channel volume.
Arguments:
VolumeSetting - Requested volume variable.
Return Value:
Returns MMSYSERR_NOERROR if successful, MMSYSERR_NOMEM if
unsuccessful. Note that this is probably not a good error
code to return, but it's the best of the bunch to choose from.
--*/
{
MMRESULT ReturnValue;
BOOLEAN Success;
DEBUGMSG(1|ZONE_WODM, (TEXT("+SetOutputVolume(%x)\r\n"),VolumeSetting));
ReturnValue = MMSYSERR_ERROR;
Success = CodecSetVolume(WaveInstance->hSMBus,
VolumeSetting);
if (Success == FALSE) {
DEBUGMSG(ZONE_WODM, (
TEXT("SetOutputVolume: Failed codec write.\r\n")));
goto ErrorReturn;
}
ReturnValue = MMSYSERR_NOERROR;
ErrorReturn:
DEBUGMSG(ZONE_WODM, (TEXT("-SetOutputVolume\r\n")));
return ReturnValue;
}
VOID
WaveOutStart(
IN OUT PWAVE_RESOURCE WaveResource,
IN OUT PWAVEHDR WaveHeader
)
/*++
Routine Description:
This routine handles set up of a new wave output stream.
Arguments:
WaveResource - Pointer to the wave resource structure corresponding to the
stream to be started.
WaveHeader - Pointer to the wave header information.
Return Value:
None.
--*/
{
WaveResource->MoreData = TRUE;
WaveResource->WaveHeader = WaveHeader;
FillTwoOutputBuffers(WaveResource);
StartDma(WaveResource);
}
VOID
WaveOutContinue (
IN OUT PWAVE_RESOURCE WaveResource,
IN OUT PWAVEHDR WaveHeader
)
/*++
Routine Description:
This routine handles continuation of a playing audio output stream.
The operations are similar to starting wave output.
Arguments:
WaveHeader - Pointer to the wave header information.
Return Value:
None.
--*/
{
WaveResource->WaveHeader = WaveHeader;
if (HalDMAIsUnderflowed(WaveResource->DMAChannel)) {
FillTwoOutputBuffers(WaveResource);
} else {
FillOutputBuffer(WaveResource);
}
}
VOID
WaveOutEndOfData(
IN OUT PWAVE_RESOURCE WaveResource
)
/*++
Routine Description:
This routine handles clean up of audio output when the wave
output stream has ended. It stops any output DMA transfer
in progress and mutes audio output on the codec.
Arguments:
Return Value:
None.
--*/
{
DEBUGMSG(ZONE_WODM, (TEXT("+WaveOutEndOfData\r\n")));
HalWaitForDMA(WaveResource->DMAChannel);
WaveResource->MoreData = FALSE;
ShutdownDma(WaveResource);
DEBUGMSG(ZONE_WODM, (TEXT("-WaveOutEndOfData\r\n")));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -