Author: silverblade Date: Wed Jul 2 07:28:32 2008 New Revision: 34258
URL: http://svn.reactos.org/svn/reactos?rev=34258&view=rev Log: Implemented routines for destroying legacy sound devices. Updated SB16_NT4 so that it may now correctly create and destroy devices. It can also register and unregister an interrupt handler (currently hard-coded to IRQ 5 but will be selectable later).
Added: branches/silverblade-audio/include/reactos/libs/sound/hardware.h (with props) Modified: branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/sb16_nt4.rbuild branches/silverblade-audio/include/reactos/libs/sound/devname.h branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h branches/silverblade-audio/lib/drivers/sound/legacy/devname.c branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c
Modified: branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/drivers/multim... ============================================================================== --- branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c [iso-8859-1] (original) +++ branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -20,6 +20,7 @@ #include <ntddsnd.h> #include <debug.h>
+#include <hardware.h> #include <sbdsp.h> #include <devname.h>
@@ -94,12 +95,65 @@ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;} + + +/* + ============ HACKY TESTING CODE FOLLOWS ============== +*/ + +PDEVICE_OBJECT g_device; +PKINTERRUPT g_interrupt = 0; + +STDCALL +BOOLEAN +InterruptService( + IN struct _KINTERRUPT *Interrupt, + IN PVOID ServiceContext) +{ + DbgPrint("ISR called\n"); + return TRUE; +} + + + +NTSTATUS +PrepareSoundBlaster( + IN PDRIVER_OBJECT DriverObject) +{ + NTSTATUS result; + + DbgPrint("Creating sound device\n"); + result = CreateSoundDeviceWithDefaultName(DriverObject, 0, 69, 0, &g_device); + DbgPrint("Request returned status 0x%08x\n", + result); + + DbgPrint("Attaching interrupt\n"); + /* Interrupt */ + result = LegacyAttachInterrupt(g_device, 5, InterruptService, &g_interrupt); + DbgPrint("Request %s\n", + result == STATUS_SUCCESS ? "succeeded" : "failed"); + + return result; +} +
VOID STDCALL UnloadSoundBlaster( IN PDRIVER_OBJECT DriverObject) { + NTSTATUS Status; DbgPrint("Sound Blaster driver being unloaded\n"); + + if ( g_interrupt ) + { + DbgPrint("Disconnecting interrupt\n"); + IoDisconnectInterrupt(g_interrupt); + } + + DbgPrint("Destroying devices\n"); + Status = DestroySoundDeviceWithDefaultName(g_device, 0, 69); + DbgPrint("Status 0x%08x\n", Status); + /*INFO_(IHVAUDIO, "Sound Blaster driver being unloaded");*/ }
@@ -158,15 +212,12 @@
STDCALL NTSTATUS -ThisIsSparta(IN PDRIVER_OBJECT DriverObject) -{ - DEVICE_OBJECT device; +TestSoundBlasterLibrary() +{ NTSTATUS result; - BOOLEAN speaker_state = TRUE; + BOOLEAN speaker_state = TRUE, agc_enabled = FALSE; UCHAR major = 0x69, minor = 0x96; UCHAR level = 0; - - /*CreateSoundDeviceWithDefaultName(DriverObject, 0, 69, 0, &device);*/
/* 0x220 is the port we expect to work */ DbgPrint("Resetting Sound Blaster DSP at 0x220\n"); @@ -188,6 +239,8 @@ result == STATUS_SUCCESS ? "successful" : "unsuccessful"); DbgPrint("Sound Blaster DSP version is %d.%02d\n", major, minor);
+ /* Speaker tests */ + result = SbDspIsSpeakerEnabled((PUCHAR)0x220, &speaker_state, SB_DEFAULT_TIMEOUT); DbgPrint("Speaker state retrieval %s\n", result == STATUS_SUCCESS ? "succeeded" : "failed"); @@ -214,6 +267,9 @@ result == STATUS_SUCCESS ? "succeeded" : "failed"); DbgPrint("Speaker state is now %s\n", speaker_state ? "ENABLED" : "DISABLED"); + + + /* Mixer tests */
DbgPrint("Resetting SB Mixer\n"); SbMixerReset((PUCHAR)0x220); @@ -229,8 +285,23 @@ result == STATUS_SUCCESS ? "succeeded" : "failed"); DbgPrint("Level is 0x%x\n", level);
+ + /* AGC testing */ + + agc_enabled = SbMixerIsAGCEnabled((PUCHAR)0x220); + DbgPrint("AGC enabled? %d\n", agc_enabled); + + SbMixerEnableAGC((PUCHAR)0x220); + agc_enabled = SbMixerIsAGCEnabled((PUCHAR)0x220); + DbgPrint("AGC enabled? %d\n", agc_enabled); + + SbMixerDisableAGC((PUCHAR)0x220); + agc_enabled = SbMixerIsAGCEnabled((PUCHAR)0x220); + DbgPrint("AGC enabled? %d\n", agc_enabled); + return STATUS_SUCCESS; } +
@@ -254,5 +325,6 @@ DriverObject->DriverUnload = UnloadSoundBlaster;
/* Hax */ - return ThisIsSparta(DriverObject); -} + TestSoundBlasterLibrary(); + return PrepareSoundBlaster(DriverObject); +}
Modified: branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/sb16_nt4.rbuild URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/drivers/multim... ============================================================================== --- branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/sb16_nt4.rbuild [iso-8859-1] (original) +++ branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/sb16_nt4.rbuild [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -8,6 +8,7 @@ <importlibrary definition="sb16_nt4.def" /> <library>soundblaster</library> <library>audio</library> + <library>audioleg</library> <library>ntoskrnl</library> <library>hal</library> <file>main.c</file>
Modified: branches/silverblade-audio/include/reactos/libs/sound/devname.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/devname.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/devname.h [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -92,7 +92,7 @@ IN PCWSTR WideDosDeviceName, IN UCHAR Index, IN ULONG ExtensionSize, - OUT PDEVICE_OBJECT DeviceObject); + OUT PDEVICE_OBJECT* DeviceObject);
/* @@ -108,6 +108,31 @@ IN UCHAR DeviceType, IN UCHAR Index, IN ULONG ExtensionSize, - OUT PDEVICE_OBJECT DeviceObject); + OUT PDEVICE_OBJECT* DeviceObject); + + +/* + DestroySoundDevice + + Destroy a device and its symbolic link +*/ +NTSTATUS +DestroySoundDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PCWSTR WideDosDeviceName, + IN UCHAR Index); + + +/* + DestroySoundDeviceWithDefaultName + + Similar to DestroySoundDevice, but operating on one of the + default device names. +*/ +NTSTATUS +DestroySoundDeviceWithDefaultName( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR DeviceType, + IN UCHAR Index);
#endif
Added: branches/silverblade-audio/include/reactos/libs/sound/hardware.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/hardware.h (added) +++ branches/silverblade-audio/include/reactos/libs/sound/hardware.h [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -1,0 +1,23 @@ +/* + ReactOS Sound System + Legacy support + Hardware interaction helper + + Author: + Andrew Greenwood (silverblade@reactos.org) + + History: + 2 July 2008 - Created +*/ + +#ifndef ROS_AUDIOLEG_HARDWARE_H +#define ROS_AUDIOLEG_HARDWARE_H + +NTSTATUS +LegacyAttachInterrupt( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR Irq, + IN PKSERVICE_ROUTINE ServiceRoutine, + OUT PKINTERRUPT* InterruptObject); + +#endif
Propchange: branches/silverblade-audio/include/reactos/libs/sound/hardware.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -116,6 +116,18 @@ #define SB_MIX_BASS_LEFT_LEVEL 0x46 #define SB_MIX_BASS_RIGHT_LEVEL 0x47
+/* + Mixer switches + (are these correct?) +*/ +#define SB_MIX_MIDI_LEFT_SWITCH 0x01 +#define SB_MIX_MIDI_RIGHT_SWITCH 0x02 +#define SB_MIX_LINE_LEFT_SWITCH 0x04 +#define SB_MIX_LINE_RIGHT_SWITCH 0x08 +#define SB_MIX_CD_LEFT_SWITCH 0x10 +#define SB_MIX_CD_RIGHT_SWITCH 0x20 +#define SB_MIX_MIC_SWITCH 0x40 +
/* Reset the Sound Blaster DSP. @@ -290,5 +302,23 @@ IN UCHAR Line, OUT PUCHAR Level);
+/* + Enable automatic gain control +*/ +VOID +SbMixerEnableAGC(IN PUCHAR BasePort); + +/* + Disable automatic gain control +*/ +VOID +SbMixerDisableAGC(IN PUCHAR BasePort); + +/* + Retrieve the current state of the automatic gain control +*/ +BOOLEAN +SbMixerIsAGCEnabled(IN PUCHAR BasePort); +
#endif
Modified: branches/silverblade-audio/lib/drivers/sound/legacy/devname.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/legacy/devname.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/legacy/devname.c [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -167,17 +167,25 @@ OUT PCWSTR* DeviceNameBody, OUT PCWSTR* DosDeviceNameBody) { - ASSERT(DeviceNameBody != NULL); - ASSERT(DosDeviceNameBody != NULL); - if ( DeviceType > MAX_DEVICE_TYPE ) { DPRINT("Invalid device type"); return STATUS_INVALID_PARAMETER; }
- *DeviceNameBody = SoundDeviceNameBodies[DeviceType].DeviceName; - *DosDeviceNameBody = SoundDeviceNameBodies[DeviceType].DosDeviceName; + if ( DeviceNameBody ) + { + DPRINT("Reporting device name\n"); + *DeviceNameBody = SoundDeviceNameBodies[DeviceType].DeviceName; + DPRINT("%ws\n", *DeviceNameBody); + } + + if ( DosDeviceNameBody ) + { + DPRINT("Reporting DOS device name\n"); + *DosDeviceNameBody = SoundDeviceNameBodies[DeviceType].DosDeviceName; + DPRINT("%ws\n", *DosDeviceNameBody); + }
return STATUS_SUCCESS; } @@ -254,7 +262,7 @@ IN PCWSTR WideDosDeviceName, IN UCHAR Index, IN ULONG ExtensionSize, - OUT PDEVICE_OBJECT DeviceObject) + OUT PDEVICE_OBJECT* DeviceObject) { NTSTATUS Status;
@@ -287,6 +295,8 @@ { return Status; } + + DPRINT("Creating device %ws\n", WideDeviceName);
/* Now create the device */ Status = IoCreateDevice(DriverObject, @@ -295,7 +305,7 @@ FILE_DEVICE_SOUND, 0, FALSE, - &DeviceObject); + DeviceObject);
if ( ! NT_SUCCESS(Status) ) { @@ -306,12 +316,14 @@ return Status; }
+ DPRINT("Creating link %ws\n", WideDosDeviceName); + /* Create a symbolic link for the DOS deviec name */ Status = IoCreateSymbolicLink(&DosDeviceName, &DeviceName);
if ( ! NT_SUCCESS(Status) ) { - /* IoDeleteDevice( --- What are we deleting? */ + IoDeleteDevice(*DeviceObject);
/* These will have been allocated by ConstructSoundDeviceNames */ FreeUnicodeStringBuffer(&DeviceName); @@ -337,7 +349,7 @@ IN UCHAR DeviceType, IN UCHAR Index, IN ULONG ExtensionSize, - OUT PDEVICE_OBJECT DeviceObject) + OUT PDEVICE_OBJECT* DeviceObject) { NTSTATUS Status; PCWSTR WideDeviceName = NULL; @@ -383,3 +395,86 @@
return STATUS_SUCCESS; } + +NTSTATUS +DestroySoundDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PCWSTR WideDosDeviceName, + IN UCHAR Index) +{ + NTSTATUS Status; + UNICODE_STRING DosDeviceName; + + /* Check for NULL parameters */ + if ( ( ! WideDosDeviceName ) || ( ! DeviceObject ) ) + { + DPRINT("Unexpected NULL parameter"); + return STATUS_INVALID_PARAMETER; + } + + /* Range-check */ + if ( Index >= SOUND_MAX_DEVICES ) + { + DPRINT("Device %d exceeds maximum", Index); + return STATUS_INVALID_PARAMETER; + } + + Status = ConstructDeviceName(WideDosDeviceName, Index, &DosDeviceName); + + if ( ! NT_SUCCESS(Status) ) + { + return Status; + } + + DPRINT("Deleting symlink %ws\n", WideDosDeviceName); + + Status = IoDeleteSymbolicLink(&DosDeviceName); + DPRINT("Status of symlink deletion is 0x%08x\n", Status); +/* + ASSERT(NT_SUCCESS(Status)); +*/ + + IoDeleteDevice(DeviceObject); + + return STATUS_SUCCESS; +} + +NTSTATUS +DestroySoundDeviceWithDefaultName( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR DeviceType, + IN UCHAR Index) +{ + NTSTATUS Status; + PCWSTR WideDosDeviceName = NULL; + + /* Check for NULL parameters */ + if ( ( ! DeviceObject ) ) + { + DPRINT("Unexpected NULL parameter"); + return STATUS_INVALID_PARAMETER; + } + + /* Range-check */ + if ( Index >= SOUND_MAX_DEVICES ) + { + DPRINT("Device index %d exceeds maximum", Index); + return STATUS_INVALID_PARAMETER; + } + + /* Look-up the default name based on the device type */ + Status = GetDefaultSoundDeviceNameBodies(DeviceType, + NULL, + &WideDosDeviceName); + + if ( ! NT_SUCCESS(Status) ) + { + return Status; + } + + DPRINT("DOS device name at %p\n", WideDosDeviceName); + + DPRINT("DOS device name is based on %ws\n", WideDosDeviceName); + + return DestroySoundDevice(DeviceObject, WideDosDeviceName, Index); +}
Modified: branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c [iso-8859-1] Wed Jul 2 07:28:32 2008 @@ -12,8 +12,10 @@ Notes: Functions documented in sbdsp.h
- Currently, input/output switches and AGC are not - supported. Nor is PC speaker volume. + Currently, input/output switches and PC speaker volume + level are not supported. + + The I/O switches are used for muting/unmuting mic, etc. */
#include <ntddk.h> @@ -218,3 +220,27 @@
return STATUS_SUCCESS; } + +VOID +SbMixerEnableAGC(IN PUCHAR BasePort) +{ + /* Untested... */ + WRITE_SB_MIXER_REGISTER(BasePort, SB_MIX_AGC); + WRITE_SB_MIXER_DATA(BasePort, 1); +} + +VOID +SbMixerDisableAGC(IN PUCHAR BasePort) +{ + /* Untested... */ + WRITE_SB_MIXER_REGISTER(BasePort, SB_MIX_AGC); + WRITE_SB_MIXER_DATA(BasePort, 0); +} + +BOOLEAN +SbMixerIsAGCEnabled(IN PUCHAR BasePort) +{ + /* Untested... */ + WRITE_SB_MIXER_REGISTER(BasePort, SB_MIX_AGC); + return (READ_SB_MIXER_DATA(BasePort) != 0); +}