706 lines
17 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*****************************************************************************
Copyright (c) 1993 Media Vision Inc. All Rights Reserved
Module Name:
devcaps.c
Abstract:
This module contains code for the device capabilities functions.
Author:
Nigel Thompson (nigelt) 7-Apr-1991
Environment:
Kernel mode
Revision History:
Robin Speed (RobinSp) 29-Jan-1992 - Add other devices and rewrite
Stephen Estrop (StephenE) 16-Apr-1992 - Converted to Unicode
EPA 01-11-93 Add PAS 16 support
*****************************************************************************/
#include "sound.h"
CONST WCHAR STR_MV_MIDI_OUT[] = L"MVI PAS 16 Midi Output";
CONST WCHAR STR_MV_MIDI_IN[] = L"MVI PAS 16 Midi Input";
//
// Driver Versions
//
#define WAVE_DRIVER_VERSION 0x0100
#define MIDI_DRIVER_VERSION 0x0100
#define AUX_DRIVER_VERSION 0x0100
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, SoundWaveOutGetCaps)
#pragma alloc_text(PAGE, SoundWaveInGetCaps)
#pragma alloc_text(PAGE, SoundMidiOutGetCaps)
#pragma alloc_text(PAGE, SoundMidiOutGetSynthCaps)
#pragma alloc_text(PAGE, SoundAuxGetCaps)
#pragma alloc_text(PAGE, SoundQueryFormat)
#pragma alloc_text(PAGE, GetWaveoutPid)
#pragma alloc_text(PAGE, GetWaveinPid)
#endif
//
// local functions
//
USHORT
GetWaveoutPid(
IN PGLOBAL_DEVICE_INFO pGDI
)
{
if ( pGDI->PASInfo.Caps.CapsBits.CDPC)
{
return MM_CDPC_WAVEOUT;
}
else
{
if ( IS_MIXER_508(pGDI))
{
return MM_PROAUD_16_WAVEOUT;
}
else
{
if ( pGDI->PASInfo.Caps.CapsBits.OPL_3)
{
return MM_PROAUD_PLUS_WAVEOUT;
}
else
{
return MM_PROAUD_WAVEOUT;
}
} // End ELSE
} // End ELSE
}
USHORT
GetWaveinPid(
IN PGLOBAL_DEVICE_INFO pGDI
)
{
if ( pGDI->PASInfo.Caps.CapsBits.CDPC)
{
return MM_CDPC_WAVEIN;
}
else
{
if ( IS_MIXER_508(pGDI))
{
return MM_PROAUD_16_WAVEIN;
}
else
{
if ( pGDI->PASInfo.Caps.CapsBits.OPL_3)
{
return MM_PROAUD_PLUS_WAVEIN;
}
else
{
return MM_PROAUD_WAVEIN;
}
} // End ELSE
} // End ELSE
}
/*****************************************************************************
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
*****************************************************************************/
NTSTATUS SoundWaveOutGetCaps( IN PLOCAL_DEVICE_INFO pLDI,
IN OUT PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack )
{
/***** Local Variables *****/
WAVEOUTCAPSW wc;
PGLOBAL_DEVICE_INFO pGDI;
NTSTATUS status = STATUS_SUCCESS;
/***** Start *****/
dprintf2(("SoundWaveOutGetCaps(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// say how much we're sending back
//
pIrp->IoStatus.Information = min(sizeof(wc),
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// fill in the info
//
//
// Copy across the product name - we just provide the string id
//
*(PULONG)wc.szPname = IDS_WAVEOUT_PNAME;
wc.wMid = MM_MEDIAVISION;
wc.vDriverVersion = WAVE_DRIVER_VERSION;
wc.wChannels = 2;
wc.dwSupport = WAVECAPS_VOLUME |
WAVECAPS_LRVOLUME;
// Playback Rate is NOT supported in SOUNDLIB
WAVECAPS_PLAYBACKRATE;
wc.dwFormats = WAVE_FORMAT_1M08 |
WAVE_FORMAT_1S08 |
WAVE_FORMAT_2M08 |
WAVE_FORMAT_2S08 |
WAVE_FORMAT_4M08 |
WAVE_FORMAT_4S08;
// only 16bit dac can support 16bit formats
if ( pGDI->PASInfo.Caps.CapsBits.DAC16 )
{
wc.dwFormats |= WAVE_FORMAT_1M16 |
WAVE_FORMAT_1S16 |
WAVE_FORMAT_2M16 |
WAVE_FORMAT_2S16 |
WAVE_FORMAT_4M16 |
WAVE_FORMAT_4S16;
} // End IF (pGDI->PASInfo.Caps.CapsBits.DAC16)
wc.wPid = GetWaveoutPid(pGDI);
RtlCopyMemory( pIrp->AssociatedIrp.SystemBuffer,
&wc,
pIrp->IoStatus.Information);
return status;
} // End SoundWaveOutGetCaps()
/*****************************************************************************
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
*****************************************************************************/
NTSTATUS SoundWaveInGetCaps(IN PLOCAL_DEVICE_INFO pLDI,
IN OUT PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack )
{
/***** Local Variables *****/
WAVEINCAPSW wc;
PGLOBAL_DEVICE_INFO pGDI;
NTSTATUS status = STATUS_SUCCESS;
/***** Start *****/
dprintf2(("SoundWaveInGetCaps(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// say how much we're sending back
//
pIrp->IoStatus.Information = min(sizeof(wc),
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// fill in the info
//
//
// Copy across the product name - we just provide the string id
//
*(PULONG)wc.szPname = IDS_WAVEIN_PNAME;
wc.wMid = MM_MEDIAVISION;
wc.vDriverVersion = WAVE_DRIVER_VERSION;
wc.wChannels = 2;
wc.dwFormats = WAVE_FORMAT_1M08 |
WAVE_FORMAT_1S08 |
WAVE_FORMAT_2M08 |
WAVE_FORMAT_2S08 |
WAVE_FORMAT_4M08 |
WAVE_FORMAT_4S08;
// only 16bit dac can support 16bit formats
if ( pGDI->PASInfo.Caps.CapsBits.DAC16 )
{
wc.dwFormats |= WAVE_FORMAT_1M16 |
WAVE_FORMAT_1S16 |
WAVE_FORMAT_2M16 |
WAVE_FORMAT_2S16 |
WAVE_FORMAT_4M16 |
WAVE_FORMAT_4S16;
} // End IF (pGDI->PASInfo.Caps.CapsBits.DAC16)
wc.wPid = GetWaveinPid(pGDI);
RtlCopyMemory( pIrp->AssociatedIrp.SystemBuffer,
&wc,
pIrp->IoStatus.Information);
return status;
} // End SoundWaveInGetCaps()
/*****************************************************************************
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
*****************************************************************************/
NTSTATUS SoundMidiOutGetCaps( IN PLOCAL_DEVICE_INFO pLDI,
IN OUT PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack )
{
/***** Local Variables *****/
MIDIOUTCAPSW mc;
NTSTATUS status = STATUS_SUCCESS;
PGLOBAL_DEVICE_INFO pGDI;
/***** Start *****/
dprintf2(("SoundMidiOutGetCaps(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// say how much we're sending back
//
pIrp->IoStatus.Information = min(sizeof(mc),
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// fill in the info
//
mc.wMid = MM_MEDIAVISION;
mc.vDriverVersion = MIDI_DRIVER_VERSION;
mc.wTechnology = MOD_MIDIPORT;
mc.wVoices = 0; // not used for ports
mc.wNotes = 0; // not used for ports
mc.wChannelMask = 0xFFFF; // all channels
mc.dwSupport = 0L;
RtlCopyMemory( mc.szPname,
STR_MV_MIDI_OUT,
sizeof(STR_MV_MIDI_OUT));
//
// Get the Proper Product ID
//
if ( pGDI->PASInfo.Caps.CapsBits.CDPC )
mc.wPid = MM_CDPC_MIDIOUT;
else
if ( IS_MIXER_508(pGDI) )
mc.wPid = MM_PROAUD_16_MIDIOUT;
else
if ( pGDI->PASInfo.Caps.CapsBits.OPL_3 )
mc.wPid = MM_PROAUD_PLUS_MIDIOUT;
else
mc.wPid = MM_PROAUD_MIDIOUT;
RtlCopyMemory( pIrp->AssociatedIrp.SystemBuffer,
&mc,
pIrp->IoStatus.Information);
return status;
}
/*****************************************************************************
Routine Description:
Return device capabilities for midi 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
*****************************************************************************/
NTSTATUS SoundMidiInGetCaps( IN PLOCAL_DEVICE_INFO pLDI,
IN OUT PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack )
{
/***** Local Variables *****/
MIDIINCAPSW mc;
NTSTATUS status = STATUS_SUCCESS;
PGLOBAL_DEVICE_INFO pGDI;
/***** Start *****/
dprintf2(("SoundMidiInGetCaps(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// say how much we're sending back
//
pIrp->IoStatus.Information = min(sizeof(mc),
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// fill in the info
//
mc.wMid = MM_MEDIAVISION;
mc.vDriverVersion = MIDI_DRIVER_VERSION;
RtlCopyMemory( mc.szPname,
STR_MV_MIDI_IN,
sizeof(STR_MV_MIDI_IN));
//
// Get the Proper Product ID
//
if ( pGDI->PASInfo.Caps.CapsBits.CDPC )
mc.wPid = MM_CDPC_MIDIIN;
else
if ( IS_MIXER_508(pGDI) )
mc.wPid = MM_PROAUD_16_MIDIIN;
else
if ( pGDI->PASInfo.Caps.CapsBits.OPL_3 )
mc.wPid = MM_PROAUD_PLUS_MIDIIN;
else
mc.wPid = MM_PROAUD_MIDIIN;
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
&mc,
pIrp->IoStatus.Information);
return status;
}
/*****************************************************************************
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
*****************************************************************************/
NTSTATUS SoundAuxGetCaps( IN PLOCAL_DEVICE_INFO pLDI,
IN OUT PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack )
{
/***** Local Variables *****/
AUXCAPSW auxCaps;
NTSTATUS status = STATUS_SUCCESS;
// PWSTR DeviceName;
PGLOBAL_DEVICE_INFO pGDI;
ULONG pName;
/***** Start *****/
dprintf2(("SoundAuxGetCaps(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// Find the device name
//
switch (pLDI->DeviceIndex)
{
case LineInDevice:
pName = IDS_AUX_PNAME;
break;
case CDInternal:
pName = IDS_AUX_PNAME;
break;
default:
dprintf1(("ERROR: SoundAuxGetCaps(): Getting aux caps for non-aux device!"));
return STATUS_INTERNAL_ERROR;
break;
} // End SWITCH (pLDI->DeviceIndex)
//
// say how much we're sending back
//
pIrp->IoStatus.Information = min(sizeof(auxCaps),
IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// fill in the info
//
auxCaps.wMid = MM_MEDIAVISION;
auxCaps.vDriverVersion = AUX_DRIVER_VERSION;
auxCaps.wTechnology = AUXCAPS_AUXIN;
#ifdef CDINTERNAL
if (pLDI->DeviceIndex == CDInternal) {
auxCaps.wTechnology = AUXCAPS_CDAUDIO;
}
#endif
auxCaps.dwSupport = AUXCAPS_LRVOLUME | AUXCAPS_VOLUME;
auxCaps.wPid = MM_PROAUD_AUX;
*(PULONG)auxCaps.szPname = pName;
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
&auxCaps,
pIrp->IoStatus.Information);
return status;
}
/*****************************************************************************
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
*****************************************************************************/
NTSTATUS SoundQueryFormat( IN PLOCAL_DEVICE_INFO pLDI,
IN PPCMWAVEFORMAT pFormat )
{
/***** Local Variables *****/
PGLOBAL_DEVICE_INFO pGDI;
/***** Start *****/
dprintf5(("SoundQueryFormat(): Start " ));
pGDI = pLDI->pGlobalInfo;
//
// Check the PCM Wave Format
//
if ( pFormat->wf.wFormatTag != WAVE_FORMAT_PCM ||
pFormat->wf.nChannels > 2 ||
pFormat->wf.nSamplesPerSec < pGDI->MinHz ||
pFormat->wf.nSamplesPerSec > pGDI->MaxOutHz ||
pFormat->wf.nBlockAlign < 1 )
{
dprintf1(("ERROR: SoundQueryFormat(): Wave Format NOT Supported" ));
return STATUS_NOT_SUPPORTED;
}
//
// Check for 8 Bit Stereo with an Invalid block align of 1
//
if ( pFormat->wBitsPerSample == 8 &&
pFormat->wf.nChannels == 2 &&
pFormat->wf.nBlockAlign == 1 )
{
dprintf1(("ERROR: SoundQueryFormat(): Wave Format NOT Supported" ));
return STATUS_NOT_SUPPORTED;
}
//
// Check the Sample Rate
//
if ( pGDI->PASInfo.Caps.CapsBits.DAC16 )
{
//
// PAS 16
//
if ( pFormat->wBitsPerSample != 8 &&
pFormat->wBitsPerSample != 12 &&
pFormat->wBitsPerSample != 16 )
{
dprintf1(("ERROR: SoundQueryFormat(): Wave Format NOT Supported" ));
return STATUS_NOT_SUPPORTED;
}
} // End IF (pGDI->PASInfo.Caps.CapsBits.DAC16)
else
{
//
// 8 Bit cards
//
if ( pFormat->wBitsPerSample != 8 )
{
dprintf1(("ERROR: SoundQueryFormat(): Wave Format NOT Supported" ));
return STATUS_NOT_SUPPORTED;
}
} // End ELSE
return STATUS_SUCCESS;
} // End SoundQueryFormat()
NTSTATUS
SoundMidiOutGetSynthCaps(
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 = MM_MEDIAVISION;
mc.wPid = MM_PROAUD_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_SYNTH_PNAME;
RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
&mc,
pIrp->IoStatus.Information);
return status;
}
/************************************ END ***********************************/