384 lines
7.7 KiB
C
384 lines
7.7 KiB
C
/*++
|
|
"@(#) NEC devcaps.c 1.1 95/03/22 21:23:27"
|
|
|
|
Copyright (c) 1995 NEC Corporation
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
devcaps.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code for the device capabilities functions.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "sound.h"
|
|
#include <string.h>
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, SoundWaveOutGetCaps)
|
|
#pragma alloc_text(PAGE, SoundWaveInGetCaps)
|
|
#pragma alloc_text(PAGE, SoundMidiOutGetCaps)
|
|
#pragma alloc_text(PAGE, SoundAuxGetCaps)
|
|
#pragma alloc_text(PAGE, SoundQueryFormat)
|
|
#endif
|
|
|
|
//
|
|
// Local routine
|
|
//
|
|
NTSTATUS SoundQueryFormat(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN PPCMWAVEFORMAT pFormat
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
SoundWaveOutGetCaps(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN OUT PIRP pIrp,
|
|
IN PIO_STACK_LOCATION IrpStack
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return device capabilities for wave output device.
|
|
Data is truncated if not enough space is provided.
|
|
Irp is always completed.
|
|
|
|
|
|
Arguments:
|
|
|
|
pLDI - pointer to local device info
|
|
pIrp - the Irp
|
|
IrpStack - the current stack location
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - always succeeds
|
|
|
|
--*/
|
|
|
|
{
|
|
WAVEOUTCAPSW wc;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// say how much we're sending back
|
|
//
|
|
|
|
pIrp->IoStatus.Information =
|
|
min(sizeof(wc),
|
|
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
|
|
|
|
//
|
|
// fill in the info
|
|
//
|
|
|
|
wc.wMid = MID_NEC;
|
|
wc.wPid = PID_WAVEOUT;
|
|
wc.vDriverVersion = DRIVER_VERSION;
|
|
wc.dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 |
|
|
WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16 |
|
|
WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 |
|
|
WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
|
|
WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 |
|
|
WAVE_FORMAT_4M16;
|
|
wc.wChannels = 2;
|
|
wc.dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;
|
|
|
|
//
|
|
// Copy across the product name - we just provide the string id
|
|
//
|
|
|
|
*(PULONG)wc.szPname = IDS_WAVEOUT_PNAME;
|
|
|
|
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
|
|
&wc,
|
|
pIrp->IoStatus.Information);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SoundWaveInGetCaps(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN OUT PIRP pIrp,
|
|
IN PIO_STACK_LOCATION IrpStack
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return device capabilities for wave input device.
|
|
Data is truncated if not enough space is provided.
|
|
Irp is always completed.
|
|
|
|
|
|
Arguments:
|
|
|
|
pLDI - pointer to local device info
|
|
pIrp - the Irp
|
|
IrpStack - the current stack location
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - always succeeds
|
|
|
|
--*/
|
|
|
|
{
|
|
WAVEINCAPSW wc;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// say how much we're sending back
|
|
//
|
|
|
|
pIrp->IoStatus.Information =
|
|
min(sizeof(wc),
|
|
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
|
|
|
|
//
|
|
// fill in the info
|
|
//
|
|
|
|
wc.wMid = MID_NEC;
|
|
wc.wPid = PID_WAVEIN;
|
|
wc.vDriverVersion = DRIVER_VERSION;
|
|
wc.dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 |
|
|
WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16 |
|
|
WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 |
|
|
WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
|
|
WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 |
|
|
WAVE_FORMAT_4M16;
|
|
wc.wChannels = 2;
|
|
|
|
//
|
|
// Copy across the product name - we just provide the string id
|
|
//
|
|
|
|
*(PULONG)wc.szPname = IDS_WAVEIN_PNAME;
|
|
|
|
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
|
|
&wc,
|
|
pIrp->IoStatus.Information);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SoundMidiOutGetCaps(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN OUT PIRP pIrp,
|
|
IN PIO_STACK_LOCATION IrpStack
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return device capabilities for midi output device.
|
|
Data is truncated if not enough space is provided.
|
|
Irp is always completed.
|
|
|
|
|
|
Arguments:
|
|
|
|
pLDI - pointer to local device info
|
|
pIrp - the Irp
|
|
IrpStack - the current stack location
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - always succeeds
|
|
|
|
--*/
|
|
|
|
{
|
|
MIDIOUTCAPSW mc;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// say how much we're sending back
|
|
//
|
|
|
|
pIrp->IoStatus.Information =
|
|
min(sizeof(mc),
|
|
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
|
|
|
|
//
|
|
// fill in the info
|
|
//
|
|
|
|
mc.wMid = MID_NEC;
|
|
mc.wPid = PID_SYNTH;
|
|
mc.wTechnology = MOD_FMSYNTH;
|
|
mc.wVoices = 128;
|
|
mc.wNotes = 18;
|
|
mc.wChannelMask = 0xffff; // all channels
|
|
mc.vDriverVersion = DRIVER_VERSION;
|
|
mc.dwSupport = MIDICAPS_VOLUME | MIDICAPS_LRVOLUME;
|
|
|
|
//
|
|
// Copy across the product name - we just provide the string id
|
|
//
|
|
|
|
*(PULONG)mc.szPname = IDS_MIDIOUT_PNAME;
|
|
|
|
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
|
|
&mc,
|
|
pIrp->IoStatus.Information);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SoundAuxGetCaps(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN OUT PIRP pIrp,
|
|
IN PIO_STACK_LOCATION IrpStack
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return device capabilities for axu devices
|
|
Data is truncated if not enough space is provided.
|
|
Irp is always completed.
|
|
|
|
|
|
Arguments:
|
|
|
|
pLDI - pointer to local device info
|
|
pIrp - the Irp
|
|
IrpStack - the current stack location
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - always succeeds
|
|
|
|
--*/
|
|
|
|
{
|
|
AUXCAPSW auxCaps;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// say how much we're sending back
|
|
//
|
|
|
|
pIrp->IoStatus.Information =
|
|
min(sizeof(auxCaps),
|
|
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
|
|
|
|
//
|
|
// fill in the info
|
|
//
|
|
|
|
auxCaps.wMid = MID_NEC;
|
|
auxCaps.wPid = PID_AUX;
|
|
auxCaps.vDriverVersion = DRIVER_VERSION;
|
|
auxCaps.wTechnology = AUXCAPS_AUXIN;
|
|
auxCaps.dwSupport = AUXCAPS_LRVOLUME | AUXCAPS_VOLUME;
|
|
|
|
//
|
|
// Copy across the product name - we just provide the string id
|
|
//
|
|
|
|
*(PULONG)auxCaps.szPname = IDS_AUX_PNAME;
|
|
|
|
|
|
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
|
|
&auxCaps,
|
|
pIrp->IoStatus.Information);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS SoundQueryFormat(
|
|
IN PLOCAL_DEVICE_INFO pLDI,
|
|
IN PPCMWAVEFORMAT pFormat
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Tell the caller whether the wave format specified (input or
|
|
output) is supported
|
|
|
|
Arguments:
|
|
|
|
pLDI - pointer to local device info
|
|
pFormat - format being queried
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - format is supported
|
|
STATUS_NOT_SUPPORTED - format not supported
|
|
|
|
--*/
|
|
{
|
|
|
|
if (pFormat->wf.wFormatTag != WAVE_FORMAT_PCM &&
|
|
pFormat->wf.wFormatTag != WAVE_FORMAT_ALAW &&
|
|
pFormat->wf.wFormatTag != WAVE_FORMAT_MULAW ||
|
|
|
|
pFormat->wf.nChannels != 1 &&
|
|
pFormat->wf.nChannels != 2 ||
|
|
|
|
HwNearestRate(pFormat->wf.nSamplesPerSec) !=
|
|
pFormat->wf.nSamplesPerSec ||
|
|
|
|
pFormat->wBitsPerSample != 8 &&
|
|
pFormat->wBitsPerSample != 16
|
|
|
|
) {
|
|
return STATUS_NOT_SUPPORTED;
|
|
} else {
|
|
|
|
|
|
if (pFormat->wf.wFormatTag != WAVE_FORMAT_PCM) {
|
|
|
|
/*
|
|
** Check the avg bytes per second so buffer size computations
|
|
** don't blow up.
|
|
*/
|
|
|
|
if (pFormat->wBitsPerSample != 8) {
|
|
return STATUS_NOT_SUPPORTED;
|
|
}
|
|
} else {
|
|
/*
|
|
** Check for too fast for non-demand mode DMA
|
|
*/
|
|
|
|
if (((PGLOBAL_DEVICE_INFO)pLDI->pGlobalInfo)->SingleModeDMA) {
|
|
if (pFormat->wf.nChannels == 2 &&
|
|
pFormat->wBitsPerSample == 16 &&
|
|
pFormat->wf.nSamplesPerSec > 25000) {
|
|
return STATUS_NOT_SUPPORTED;
|
|
}
|
|
}
|
|
}
|
|
return STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|