299 lines
6.3 KiB
C
299 lines
6.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sbcdmix.c
|
|
|
|
Abstract:
|
|
|
|
Mixer code for the Sound Blaster 2 CD card.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "sound.h"
|
|
#include "sbcdmix.h"
|
|
|
|
/*
|
|
** Local functions and data
|
|
*/
|
|
|
|
VOID
|
|
SBCDWaveoutLineChanged(
|
|
PLOCAL_DEVICE_INFO pLDI,
|
|
UCHAR Code
|
|
);
|
|
VOID
|
|
SBCDSynthLineChanged(
|
|
PLOCAL_DEVICE_INFO pLDI,
|
|
UCHAR Code
|
|
);
|
|
|
|
VOID
|
|
SBCDSetVolumeControlIds(
|
|
PGLOBAL_DEVICE_INFO pGDI
|
|
);
|
|
|
|
BOOLEAN
|
|
SBCDMixerSet(
|
|
PGLOBAL_DEVICE_INFO pGDI,
|
|
ULONG ControlId
|
|
);
|
|
|
|
BOOLEAN
|
|
SBCDLineActive(
|
|
IN PGLOBAL_DEVICE_INFO pGDI,
|
|
IN ULONG LinelId
|
|
);
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(INIT,SBCDMixerInit)
|
|
#pragma alloc_text(INIT,SBCDSetVolumeControlIds)
|
|
|
|
#pragma alloc_text(PAGE,SBCDLineActive)
|
|
#pragma alloc_text(PAGE,SBCDWaveoutLineChanged)
|
|
#pragma alloc_text(PAGE,SBCDSynthLineChanged)
|
|
#pragma alloc_text(PAGE,SBCDMixerSet)
|
|
#endif
|
|
|
|
|
|
VOID
|
|
SBCDMixerInit(
|
|
PGLOBAL_DEVICE_INFO pGDI
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize our local data for the sound blaster 16
|
|
|
|
Arguments:
|
|
|
|
pGDI - Global card device info
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PLOCAL_MIXER_DATA LocalMixerData;
|
|
ULONG i;
|
|
|
|
LocalMixerData = &pGDI->LocalMixerData;
|
|
|
|
LocalMixerData->MixerLineInit = SBCDLineInit;
|
|
LocalMixerData->NumberOfLines = NumberOfLines;
|
|
LocalMixerData->MixerControlInit = SBCDControlInit;
|
|
LocalMixerData->NumberOfControls = NumberOfControls;
|
|
LocalMixerData->MixerTextInit = NULL;
|
|
LocalMixerData->MaxSettableItems = NumberOfControls - 1; // Can't set meters
|
|
|
|
/*
|
|
** NOTE - generic code works out NumberOfTextItems so we don't need to
|
|
** set it here (and we shouldn't!).
|
|
*/
|
|
|
|
/*
|
|
** Set up our callbacks
|
|
*/
|
|
|
|
LocalMixerData->MixerSet = SBCDMixerSet;
|
|
LocalMixerData->MixerLineActive = SBCDLineActive;
|
|
|
|
/*
|
|
** Note - these generic volume controls control both the recording and
|
|
** the playing volumes - whichever they are switched to
|
|
*/
|
|
|
|
SBCDSetVolumeControlIds(pGDI);
|
|
|
|
/*
|
|
** Set up line notifications and volume control ids for non-mixer devices
|
|
*/
|
|
|
|
SoundSetLineNotify(
|
|
(PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
|
|
SBCDWaveoutLineChanged);
|
|
|
|
|
|
if (pGDI->Synth.DeviceObject) {
|
|
SoundSetLineNotify(
|
|
(PLOCAL_DEVICE_INFO)pGDI->Synth.DeviceObject->DeviceExtension,
|
|
SBCDSynthLineChanged);
|
|
}
|
|
|
|
/*
|
|
** Set up defaults
|
|
*/
|
|
|
|
for (i = 0; i < NumberOfControls; i++) {
|
|
switch (i) {
|
|
|
|
/*
|
|
** For us it's either Mute, a volume, a Mux or a Mixer.
|
|
**
|
|
** Volumes are set to a fixed value
|
|
**
|
|
** Nothing is muted
|
|
*/
|
|
|
|
case ControlLineoutVolume:
|
|
case ControlLineoutMidioutVolume:
|
|
case ControlLineoutWaveoutVolume:
|
|
case ControlLineoutInternalCDVolume:
|
|
|
|
/*
|
|
** Half volume
|
|
*/
|
|
|
|
LocalMixerData->ControlInfo[i].Data.v[0].u = 32768;
|
|
LocalMixerData->ControlInfo[i].Data.v[1].u = 32768;
|
|
break;
|
|
|
|
case ControlLineoutMute:
|
|
case ControlLineoutMidioutMute:
|
|
case ControlLineoutInternalCDMute:
|
|
case ControlLineoutWaveoutMute:
|
|
/*
|
|
** Already 0
|
|
*/
|
|
break;
|
|
|
|
case ControlLineoutWaveoutPeak:
|
|
/*
|
|
** Not settable
|
|
*/
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE); // Added control but forgot to set it!
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
SBCDWaveoutLineChanged(
|
|
PLOCAL_DEVICE_INFO pLDI,
|
|
UCHAR Code
|
|
)
|
|
{
|
|
PLOCAL_MIXER_DATA LocalMixerData;
|
|
|
|
LocalMixerData = &((PGLOBAL_DEVICE_INFO)pLDI->pGlobalInfo)->LocalMixerData;
|
|
|
|
SoundMixerChangedItem(
|
|
&((PGLOBAL_DEVICE_INFO)pLDI->pGlobalInfo)->MixerInfo,
|
|
&LocalMixerData->LineNotification[DestLineoutSourceWaveout]);
|
|
}
|
|
|
|
VOID
|
|
SBCDSynthLineChanged(
|
|
PLOCAL_DEVICE_INFO pLDI,
|
|
UCHAR Code
|
|
)
|
|
{
|
|
PLOCAL_MIXER_DATA LocalMixerData;
|
|
PGLOBAL_DEVICE_INFO pGDI;
|
|
|
|
pGDI = CONTAINING_RECORD(pLDI->pGlobalInfo, GLOBAL_DEVICE_INFO, Synth);
|
|
|
|
LocalMixerData = &pGDI->LocalMixerData;
|
|
|
|
SoundMixerChangedItem(
|
|
&pGDI->MixerInfo,
|
|
&LocalMixerData->LineNotification[DestLineoutSourceMidiout]);
|
|
}
|
|
VOID
|
|
SBCDSetVolumeControlIds(
|
|
PGLOBAL_DEVICE_INFO pGDI
|
|
)
|
|
{
|
|
SoundSetVolumeControlId(
|
|
(PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
|
|
ControlLineoutWaveoutVolume);
|
|
|
|
SoundSetVolumeControlId(
|
|
(PLOCAL_DEVICE_INFO)pGDI->DeviceObject[CDInternal]->DeviceExtension,
|
|
ControlLineoutInternalCDVolume);
|
|
|
|
if (pGDI->Synth.DeviceObject) {
|
|
SoundSetVolumeControlId(
|
|
(PLOCAL_DEVICE_INFO)pGDI->Synth.DeviceObject->DeviceExtension,
|
|
ControlLineoutMidioutVolume);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
SBCDMixerSet(
|
|
PGLOBAL_DEVICE_INFO pGDI,
|
|
ULONG ControlId
|
|
)
|
|
{
|
|
switch (ControlId) {
|
|
|
|
case ControlLineoutVolume: // 0
|
|
case ControlLineoutMidioutVolume: // 6
|
|
case ControlLineoutInternalCDVolume: // 8
|
|
case ControlLineoutWaveoutVolume: // 10
|
|
return SBCDSetVolume(pGDI, ControlId);
|
|
|
|
case ControlLineoutInternalCDMute: // 9
|
|
case ControlLineoutMidioutMute: // 7
|
|
case ControlLineoutMute: // 1
|
|
case ControlLineoutWaveoutMute: // 11
|
|
return SBCDSetMute(pGDI, ControlId);
|
|
|
|
case ControlLineoutWaveoutPeak: // 12
|
|
/*
|
|
** Not settable
|
|
*/
|
|
return FALSE;
|
|
default:
|
|
dprintf1(("Invalid ControlId %u", ControlId));
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
SBCDLineActive(
|
|
IN PGLOBAL_DEVICE_INFO pGDI,
|
|
IN ULONG LineId
|
|
)
|
|
{
|
|
switch (LineId) {
|
|
|
|
case DestLineout:
|
|
return TRUE;
|
|
|
|
case DestLineoutSourceMidiout:
|
|
case DestLineoutSourceInternal:
|
|
return TRUE;
|
|
|
|
/*
|
|
** Wave out deemed 'active' when open
|
|
*/
|
|
|
|
case DestLineoutSourceWaveout:
|
|
if (WAVE_OUT_ACTIVE(&pGDI->WaveInfo)) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE); // Invalid
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|