[ros-diffs] [silverblade] 34257: Implemented Sound Blaster mixer register read/write. Tested ability to set and get the master volume level, under VirtualBox. Appears to function correctly. Temporary test code added to sb16_nt4.

silverblade at svn.reactos.org silverblade at svn.reactos.org
Wed Jul 2 12:23:19 CEST 2008


Author: silverblade
Date: Wed Jul  2 05:23:18 2008
New Revision: 34257

URL: http://svn.reactos.org/svn/reactos?rev=34257&view=rev
Log:
Implemented Sound Blaster mixer register read/write. Tested ability to
set and get the master volume level, under VirtualBox. Appears to function
correctly. Temporary test code added to sb16_nt4.


Modified:
    branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c
    branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h
    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/multimedia/audio/sb16_nt4/main.c?rev=34257&r1=34256&r2=34257&view=diff
==============================================================================
--- 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 05:23:18 2008
@@ -164,6 +164,7 @@
     NTSTATUS result;
     BOOLEAN speaker_state = TRUE;
     UCHAR major = 0x69, minor = 0x96;
+    UCHAR level = 0;
 
     /*CreateSoundDeviceWithDefaultName(DriverObject, 0, 69, 0, &device);*/
 
@@ -213,6 +214,20 @@
              result == STATUS_SUCCESS ? "succeeded" : "failed");
     DbgPrint("Speaker state is now %s\n",
              speaker_state ? "ENABLED" : "DISABLED");
+
+    DbgPrint("Resetting SB Mixer\n");
+    SbMixerReset((PUCHAR)0x220);
+
+    DbgPrint("Setting master level to 0F\n");
+    result = SbMixerSetLevel((PUCHAR)0x220, SB_MIX_MASTER_LEVEL, 0x0f);
+    DbgPrint("Request %s\n",
+             result == STATUS_SUCCESS ? "succeeded" : "failed");
+
+    DbgPrint("Getting master level\n");
+    result = SbMixerGetLevel((PUCHAR)0x220, SB_MIX_MASTER_LEVEL, &level);
+    DbgPrint("Request %s\n",
+             result == STATUS_SUCCESS ? "succeeded" : "failed");
+    DbgPrint("Level is 0x%x\n", level);
 
     return STATUS_SUCCESS;
 }

Modified: branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h?rev=34257&r1=34256&r2=34257&view=diff
==============================================================================
--- 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 05:23:18 2008
@@ -90,6 +90,7 @@
 /*
     Mixer lines
 */
+#define SB_MIX_RESET                0x00
 #define SB_MIX_MASTER_LEFT_LEVEL    0x30
 #define SB_MIX_MASTER_RIGHT_LEVEL   0x31
 #define SB_MIX_VOC_LEFT_LEVEL       0x32
@@ -103,8 +104,8 @@
 #define SB_MIX_MIC_LEVEL            0x3A
 #define SB_MIX_PC_SPEAKER_LEVEL     0x3B
 #define SB_MIX_OUTPUT_SWITCHES      0x3C
-#define SB_MIX_INPUT_LEFT_LEVEL     0x3D
-#define SB_MIX_INPUT_RIGHT_LEVEL    0x3E
+#define SB_MIX_INPUT_LEFT_SWITCHES  0x3D
+#define SB_MIX_INPUT_RIGHT_SWITCHES 0x3E
 #define SB_MIX_INPUT_LEFT_GAIN      0x3F
 #define SB_MIX_INPUT_RIGHT_GAIN     0x40
 #define SB_MIX_OUTPUT_LEFT_GAIN     0x41
@@ -247,4 +248,47 @@
     IN  ULONG Timeout);
 
 
+/*
+    Reset the mixer
+*/
+VOID
+SbMixerReset(IN PUCHAR BasePort);
+
+/*
+    Pack mixer level data
+*/
+NTSTATUS
+SbMixerPackLevelData(
+    IN  UCHAR Line,
+    IN  UCHAR Level,
+    OUT PUCHAR PackedLevel);
+
+/*
+    Unpack mixer level data
+*/
+NTSTATUS
+SbMixerUnpackLevelData(
+    IN  UCHAR Line,
+    IN  UCHAR PackedLevel,
+    OUT PUCHAR Level);
+
+/*
+    Set a mixer line level
+*/
+NTSTATUS
+SbMixerSetLevel(
+    IN  PUCHAR BasePort,
+    IN  UCHAR Line,
+    IN  UCHAR Level);
+
+/*
+    Get a mixer line level
+*/
+NTSTATUS
+SbMixerGetLevel(
+    IN  PUCHAR BasePort,
+    IN  UCHAR Line,
+    OUT PUCHAR Level);
+
+
 #endif

Modified: branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/soundblaster/mixer.c?rev=34257&r1=34256&r2=34257&view=diff
==============================================================================
--- 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 05:23:18 2008
@@ -11,6 +11,9 @@
 
     Notes:
         Functions documented in sbdsp.h
+
+        Currently, input/output switches and AGC are not
+        supported. Nor is PC speaker volume.
 */
 
 #include <ntddk.h>
@@ -18,4 +21,200 @@
 
 #include <sbdsp.h>
 
-/* Stub... */
+VOID
+SbMixerReset(IN PUCHAR BasePort)
+{
+    WRITE_SB_MIXER_REGISTER(BasePort, SB_MIX_RESET);
+    /* Are we meant to send anything else? */
+}
+
+NTSTATUS
+SbMixerPackLevelData(
+    IN  UCHAR Line,
+    IN  UCHAR Level,
+    OUT PUCHAR PackedLevel)
+{
+    if ( ! PackedLevel )
+        return STATUS_INVALID_PARAMETER_3;
+
+    switch ( Line )
+    {
+        case SB_MIX_MASTER_LEFT_LEVEL :
+        case SB_MIX_MASTER_RIGHT_LEVEL :
+        case SB_MIX_VOC_LEFT_LEVEL :
+        case SB_MIX_VOC_RIGHT_LEVEL :
+        case SB_MIX_MIDI_LEFT_LEVEL :
+        case SB_MIX_MIDI_RIGHT_LEVEL :
+        case SB_MIX_CD_LEFT_LEVEL :
+        case SB_MIX_CD_RIGHT_LEVEL :
+        case SB_MIX_LINE_LEFT_LEVEL :
+        case SB_MIX_LINE_RIGHT_LEVEL :
+        case SB_MIX_MIC_LEVEL :
+        case SB_MIX_LEGACY_MIC_LEVEL :  /* is this correct? */
+        {
+            if ( Level >= 0x20 )
+                return STATUS_INVALID_PARAMETER_2;
+
+            *PackedLevel = Level << 3;
+            return STATUS_SUCCESS;
+        }
+
+        case SB_MIX_INPUT_LEFT_GAIN :
+        case SB_MIX_INPUT_RIGHT_GAIN :
+        case SB_MIX_OUTPUT_LEFT_GAIN :
+        case SB_MIX_OUTPUT_RIGHT_GAIN :
+        {
+            if ( Level >= 0x04 )
+                return STATUS_INVALID_PARAMETER_2;
+
+            *PackedLevel = Level << 6;
+            return STATUS_SUCCESS;
+        }
+
+        case SB_MIX_VOC_LEVEL :         /* legacy */
+        case SB_MIX_MASTER_LEVEL :
+        case SB_MIX_FM_LEVEL :
+        case SB_MIX_CD_LEVEL :
+        case SB_MIX_LINE_LEVEL :
+        case SB_MIX_TREBLE_LEFT_LEVEL : /* bass/treble */
+        case SB_MIX_TREBLE_RIGHT_LEVEL :
+        case SB_MIX_BASS_LEFT_LEVEL :
+        case SB_MIX_BASS_RIGHT_LEVEL :
+        {
+            if ( Level >= 0x10 )
+                return STATUS_INVALID_PARAMETER_2;
+
+            *PackedLevel = Level << 4;
+            return STATUS_SUCCESS;
+        }
+
+        default :
+            return STATUS_INVALID_PARAMETER_1;
+    };
+}
+
+NTSTATUS
+SbMixerUnpackLevelData(
+    IN  UCHAR Line,
+    IN  UCHAR PackedLevel,
+    OUT PUCHAR Level)
+{
+    if ( ! Level )
+        return STATUS_INVALID_PARAMETER_3;
+
+    switch ( Line )
+    {
+        case SB_MIX_MASTER_LEFT_LEVEL :
+        case SB_MIX_MASTER_RIGHT_LEVEL :
+        case SB_MIX_VOC_LEFT_LEVEL :
+        case SB_MIX_VOC_RIGHT_LEVEL :
+        case SB_MIX_MIDI_LEFT_LEVEL :
+        case SB_MIX_MIDI_RIGHT_LEVEL :
+        case SB_MIX_CD_LEFT_LEVEL :
+        case SB_MIX_CD_RIGHT_LEVEL :
+        case SB_MIX_LINE_LEFT_LEVEL :
+        case SB_MIX_LINE_RIGHT_LEVEL :
+        case SB_MIX_MIC_LEVEL :
+        {
+            *Level = PackedLevel >> 3;
+            return STATUS_SUCCESS;
+        }
+
+        case SB_MIX_INPUT_LEFT_GAIN :
+        case SB_MIX_INPUT_RIGHT_GAIN :
+        case SB_MIX_OUTPUT_LEFT_GAIN :
+        case SB_MIX_OUTPUT_RIGHT_GAIN :
+        {
+            *Level = PackedLevel >> 6;
+            return STATUS_SUCCESS;
+        }
+
+        case SB_MIX_VOC_LEVEL :         /* legacy */
+        case SB_MIX_MASTER_LEVEL :
+        case SB_MIX_FM_LEVEL :
+        case SB_MIX_CD_LEVEL :
+        case SB_MIX_LINE_LEVEL :
+        case SB_MIX_TREBLE_LEFT_LEVEL : /* bass/treble */
+        case SB_MIX_TREBLE_RIGHT_LEVEL :
+        case SB_MIX_BASS_LEFT_LEVEL :
+        case SB_MIX_BASS_RIGHT_LEVEL :
+        {
+            *Level = PackedLevel >> 4;
+            return STATUS_SUCCESS;
+        }
+
+        default :
+            return STATUS_INVALID_PARAMETER_1;
+    };
+}
+
+NTSTATUS
+SbMixerSetLevel(
+    IN  PUCHAR BasePort,
+    IN  UCHAR Line,
+    IN  UCHAR Level)
+{
+    UCHAR PackedLevel = 0;
+    NTSTATUS Status;
+
+    Status = SbMixerPackLevelData(Line, Level, &PackedLevel);
+
+    switch ( Status )
+    {
+        case STATUS_SUCCESS :
+            break;
+
+        case STATUS_INVALID_PARAMETER_1 :
+            return STATUS_INVALID_PARAMETER_2;
+
+        case STATUS_INVALID_PARAMETER_2 :
+            return STATUS_INVALID_PARAMETER_3;
+
+        default :
+            return Status;
+    };
+
+    DbgPrint("SbMixerSetLevel: Line 0x%x, raw level 0x%x, packed 0x%x\n", Line, Level, PackedLevel);
+
+    WRITE_SB_MIXER_REGISTER(BasePort, Line);
+    WRITE_SB_MIXER_DATA(BasePort, PackedLevel);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+SbMixerGetLevel(
+    IN  PUCHAR BasePort,
+    IN  UCHAR Line,
+    OUT PUCHAR Level)
+{
+    UCHAR PackedLevel = 0;
+    NTSTATUS Status;
+
+    if ( ! Level )
+        return STATUS_INVALID_PARAMETER_3;
+
+    WRITE_SB_MIXER_REGISTER(BasePort, Line);
+    PackedLevel = READ_SB_MIXER_DATA(BasePort);
+
+    Status = SbMixerUnpackLevelData(Line, PackedLevel, Level);
+
+    switch ( Status )
+    {
+        case STATUS_SUCCESS :
+            break;
+
+        case STATUS_INVALID_PARAMETER_1 :
+            return STATUS_INVALID_PARAMETER_2;
+
+        case STATUS_INVALID_PARAMETER_2 :
+            return STATUS_INVALID_PARAMETER_3;
+
+        default :
+            return Status;
+    };
+
+    DbgPrint("SbMixerGetLevel: Line 0x%x, raw level 0x%x, packed 0x%x\n", Line, Level, PackedLevel);
+
+    return STATUS_SUCCESS;
+}



More information about the Ros-diffs mailing list