aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2024-08-22 18:26:45 +0300
committerWohlstand <admin@wohlnet.ru>2024-08-22 18:26:45 +0300
commitb00d3f8d933fc7de26b954bedf841cb484139562 (patch)
treef2a7d6b2ee45cece57fdbe78a944b41c459a5c0a /utils
parentc68dc6970d5b4abab13e138ac977f7212ef32e4a (diff)
downloadlibADLMIDI-b00d3f8d933fc7de26b954bedf841cb484139562.tar.gz
libADLMIDI-b00d3f8d933fc7de26b954bedf841cb484139562.tar.bz2
libADLMIDI-b00d3f8d933fc7de26b954bedf841cb484139562.zip
WinMM: Added gaining function
Diffstat (limited to 'utils')
-rw-r--r--utils/winmm_drv/config/regconfig.c19
-rw-r--r--utils/winmm_drv/config/regconfig.h6
-rw-r--r--utils/winmm_drv/cpl/adlconfig.rc60
-rw-r--r--utils/winmm_drv/cpl/config_dialog.c15
-rw-r--r--utils/winmm_drv/cpl/resource.h2
-rw-r--r--utils/winmm_drv/src/MidiSynth.cpp39
-rw-r--r--utils/winmm_drv/src/MidiSynth.h7
-rw-r--r--utils/winmm_drv/src/winmm_drv.cpp21
8 files changed, 132 insertions, 37 deletions
diff --git a/utils/winmm_drv/config/regconfig.c b/utils/winmm_drv/config/regconfig.c
index 6e35df0..a049a7d 100644
--- a/utils/winmm_drv/config/regconfig.c
+++ b/utils/winmm_drv/config/regconfig.c
@@ -163,11 +163,13 @@ void setupDefault(DriverSettings *setup)
setup->flagFullBrightness = BST_UNCHECKED;
setup->volumeModel = 0;
- setup->chanAlloc = 0;
+ setup->chanAlloc = -1;
setup->numChips = 4;
setup->num4ops = -1;
setup->outputDevice = (UINT)-1;
+
+ setup->gain100 = 100;
}
@@ -224,6 +226,9 @@ void loadSetup(DriverSettings *setup)
if(readUIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"outputDevice", &uVal))
setup->outputDevice = uVal;
+
+ if(readUIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"gain100", &uVal))
+ setup->gain100 = uVal;
}
void saveSetup(DriverSettings *setup)
@@ -246,8 +251,20 @@ void saveSetup(DriverSettings *setup)
writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"numChips", setup->numChips);
writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"num4ops", setup->num4ops);
writeUIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"outputDevice", setup->outputDevice);
+ writeUIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"gain100", setup->gain100);
+}
+
+void getGain(DriverSettings *setup)
+{
+ UINT uVal;
+ if(readUIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"gain100", &uVal))
+ setup->gain100 = uVal;
}
+void saveGain(DriverSettings *setup)
+{
+ writeUIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"gain100", setup->gain100);
+}
static const PWCHAR s_regPathNotify = L"SOFTWARE\\Wohlstand\\libADLMIDI\\notify";
diff --git a/utils/winmm_drv/config/regconfig.h b/utils/winmm_drv/config/regconfig.h
index 7c49bd6..2dac28a 100644
--- a/utils/winmm_drv/config/regconfig.h
+++ b/utils/winmm_drv/config/regconfig.h
@@ -30,6 +30,8 @@ typedef struct DriverSettings_t
int num4ops;
UINT outputDevice;
+
+ UINT gain100;
} DriverSettings;
extern const WCHAR g_adlSignalMemory[];
@@ -38,9 +40,13 @@ extern void setupDefault(DriverSettings *setup);
extern void loadSetup(DriverSettings *setup);
extern void saveSetup(DriverSettings *setup);
+extern void saveGain(DriverSettings *setup);
+extern void getGain(DriverSettings *setup);
+
#define DRV_SIGNAL_RELOAD_SETUP 1
#define DRV_SIGNAL_RESET_SYNTH 2
+#define DRV_SIGNAL_UPDATE_GAIN 3
// Client
/**
diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc
index ff7fcf2..edc5048 100644
--- a/utils/winmm_drv/cpl/adlconfig.rc
+++ b/utils/winmm_drv/cpl/adlconfig.rc
@@ -14,41 +14,43 @@
// Dialog resources
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-IDD_CONFIG_BOX DIALOGEX 0, 0, 247, 281
+IDD_CONFIG_BOX DIALOGEX 0, 0, 247, 307
STYLE DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU
CAPTION "libADLMIDI settings"
FONT 8, "MS Shell Dlg", 400, 0, 1
BEGIN
COMBOBOX IDC_AUDIOOUT, 81, 7, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- AUTORADIOBUTTON "Internal bank", IDC_BANK_INTERNAL, 13, 35, 63, 8, WS_GROUP | WS_TABSTOP, WS_EX_LEFT
- COMBOBOX IDC_BANK_ID, 81, 32, 155, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- AUTORADIOBUTTON "External bank", IDC_BANK_EXTERNAL, 13, 51, 63, 8, WS_TABSTOP, WS_EX_LEFT
- EDITTEXT IDC_BANK_PATH, 81, 49, 107, 14, WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT
- PUSHBUTTON "Browse...", IDC_BROWSE_BANK, 192, 48, 45, 14, 0, WS_EX_LEFT
- COMBOBOX IDC_EMULATOR, 81, 77, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- COMBOBOX IDC_NUM_CHIPS, 81, 95, 34, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- COMBOBOX IDC_NUM_4OPVO, 201, 95, 40, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- COMBOBOX IDC_VOLUMEMODEL, 81, 114, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
- COMBOBOX IDC_CHANALLOC, 81, 133, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT
- AUTOCHECKBOX "Full-panning stereo", IDC_FLAG_SOFTPAN, 8, 154, 227, 10, 0, WS_EX_LEFT
- AUTO3STATE "Deep tremolo (Auto/Enable/Disable)", IDC_FLAG_TREMOLO, 8, 169, 227, 10, 0, WS_EX_LEFT
- AUTO3STATE "Deep vibrato (Auto/Enable/Disable)", IDC_FLAG_VIBRATO, 8, 184, 227, 10, 0, WS_EX_LEFT
- AUTOCHECKBOX "Scalable modulation", IDC_FLAG_SCALE, 8, 199, 227, 10, 0, WS_EX_LEFT
- AUTOCHECKBOX "Full-range brightness (CC74)", IDC_FLAG_FULLBRIGHT, 8, 214, 227, 10, 0, WS_EX_LEFT
- PUSHBUTTON "About...", IDC_ABOUT, 6, 234, 50, 14, 0, WS_EX_LEFT
- PUSHBUTTON "Reset synth now", IDC_RESET_SYNTH, 71, 234, 80, 14, 0, WS_EX_LEFT
- PUSHBUTTON "Restore defaults", IDC_RESTORE_DEFAULTS, 153, 234, 88, 14, 0, WS_EX_LEFT
- DEFPUSHBUTTON "OK", IDOK, 85, 251, 50, 14, 0, WS_EX_LEFT
- PUSHBUTTON "Cancel", IDCANCEL, 138, 251, 50, 14, 0, WS_EX_LEFT
- PUSHBUTTON "Apply", IDC_APPLYBUTTON, 191, 251, 50, 14, 0, WS_EX_LEFT
- GROUPBOX "Instruments bank", IDC_INS_BANK, 7, 22, 233, 51, 0, WS_EX_LEFT
- LTEXT "Chip emulator type:", IDC_CHIPEMU_LABEL, 9, 79, 67, 10, SS_LEFT, WS_EX_LEFT
- LTEXT "Number of chips", IDC_CHIPNUM_LABEL, 9, 97, 67, 8, SS_LEFT, WS_EX_LEFT
- LTEXT "Number of 4OP voices", IDC_4OPSNUM_LABEL, 126, 97, 72, 8, SS_LEFT, WS_EX_LEFT
- LTEXT "Volume model:", IDC_VM_LABEL, 9, 116, 67, 8, SS_LEFT, WS_EX_LEFT
- RTEXT "Settings will be applied immediately", IDC_BOTTOMNOTE_LABEL, 4, 266, 235, 8, SS_RIGHT, WS_EX_LEFT
- LTEXT "Channels allocation:", IDC_CA_LABEL, 9, 135, 64, 8, SS_LEFT, WS_EX_LEFT
+ CONTROL "", IDC_GAIN, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 84, 21, 155, 20, WS_EX_LEFT
+ AUTORADIOBUTTON "Internal bank", IDC_BANK_INTERNAL, 13, 61, 63, 8, WS_GROUP | WS_TABSTOP, WS_EX_LEFT
+ COMBOBOX IDC_BANK_ID, 81, 58, 155, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
+ AUTORADIOBUTTON "External bank", IDC_BANK_EXTERNAL, 13, 77, 63, 8, WS_TABSTOP, WS_EX_LEFT
+ EDITTEXT IDC_BANK_PATH, 81, 75, 107, 14, WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT
+ PUSHBUTTON "Browse...", IDC_BROWSE_BANK, 192, 74, 45, 14, 0, WS_EX_LEFT
+ COMBOBOX IDC_EMULATOR, 81, 103, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
+ COMBOBOX IDC_NUM_CHIPS, 81, 121, 34, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
+ COMBOBOX IDC_NUM_4OPVO, 201, 121, 40, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
+ COMBOBOX IDC_VOLUMEMODEL, 81, 140, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT
+ COMBOBOX IDC_CHANALLOC, 81, 159, 160, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT
+ AUTOCHECKBOX "Full-panning stereo", IDC_FLAG_SOFTPAN, 8, 180, 227, 10, 0, WS_EX_LEFT
+ AUTO3STATE "Deep tremolo (Auto/Enable/Disable)", IDC_FLAG_TREMOLO, 8, 195, 227, 10, 0, WS_EX_LEFT
+ AUTO3STATE "Deep vibrato (Auto/Enable/Disable)", IDC_FLAG_VIBRATO, 8, 210, 227, 10, 0, WS_EX_LEFT
+ AUTOCHECKBOX "Scalable modulation", IDC_FLAG_SCALE, 8, 225, 227, 10, 0, WS_EX_LEFT
+ AUTOCHECKBOX "Full-range brightness (CC74)", IDC_FLAG_FULLBRIGHT, 8, 240, 227, 10, 0, WS_EX_LEFT
+ PUSHBUTTON "About...", IDC_ABOUT, 6, 260, 50, 14, 0, WS_EX_LEFT
+ PUSHBUTTON "Reset synth now", IDC_RESET_SYNTH, 71, 260, 80, 14, 0, WS_EX_LEFT
+ PUSHBUTTON "Restore defaults", IDC_RESTORE_DEFAULTS, 153, 260, 88, 14, 0, WS_EX_LEFT
+ DEFPUSHBUTTON "OK", IDOK, 85, 277, 50, 14, 0, WS_EX_LEFT
+ PUSHBUTTON "Cancel", IDCANCEL, 138, 277, 50, 14, 0, WS_EX_LEFT
+ PUSHBUTTON "Apply", IDC_APPLYBUTTON, 191, 277, 50, 14, 0, WS_EX_LEFT
+ GROUPBOX "Instruments bank", IDC_INS_BANK, 7, 48, 233, 51, 0, WS_EX_LEFT
+ LTEXT "Chip emulator type:", IDC_CHIPEMU_LABEL, 9, 105, 67, 10, SS_LEFT, WS_EX_LEFT
+ LTEXT "Number of chips", IDC_CHIPNUM_LABEL, 9, 123, 67, 8, SS_LEFT, WS_EX_LEFT
+ LTEXT "Number of 4OP voices", IDC_4OPSNUM_LABEL, 126, 123, 72, 8, SS_LEFT, WS_EX_LEFT
+ LTEXT "Volume model:", IDC_VM_LABEL, 9, 142, 67, 8, SS_LEFT, WS_EX_LEFT
+ RTEXT "Settings will be applied immediately", IDC_BOTTOMNOTE_LABEL, 4, 292, 235, 8, SS_RIGHT, WS_EX_LEFT
+ LTEXT "Channels allocation:", IDC_CA_LABEL, 9, 161, 64, 8, SS_LEFT, WS_EX_LEFT
LTEXT "Audio output:", IDC_AUDIOOUT_LABEL, 11, 9, 65, 8, SS_LEFT, WS_EX_LEFT
+ LTEXT "Output gain:", IDC_GAIN_LABEL, 11, 29, 65, 8, SS_LEFT, WS_EX_LEFT
END
diff --git a/utils/winmm_drv/cpl/config_dialog.c b/utils/winmm_drv/cpl/config_dialog.c
index 3f5c66d..cc2d553 100644
--- a/utils/winmm_drv/cpl/config_dialog.c
+++ b/utils/winmm_drv/cpl/config_dialog.c
@@ -99,6 +99,11 @@ static void syncWidget(HWND hwnd)
else
SendDlgItemMessage(hwnd, IDC_BANK_INTERNAL, BM_SETCHECK, 1, 0);
+ SendDlgItemMessage(hwnd, IDC_GAIN, TBM_SETRANGE, TRUE, MAKELPARAM(0, 1000));
+ SendDlgItemMessage(hwnd, IDC_GAIN, TBM_SETPAGESIZE, 0, 10);
+ SendDlgItemMessage(hwnd, IDC_GAIN, TBM_SETTICFREQ, 100, 0);
+ SendDlgItemMessage(hwnd, IDC_GAIN, TBM_SETPOS, TRUE, g_setup.gain100);
+
syncBankType(hwnd, g_setup.useExternalBank);
SendDlgItemMessage(hwnd, IDC_FLAG_TREMOLO, BM_SETCHECK, g_setup.flagDeepTremolo, 0);
@@ -265,6 +270,16 @@ INT_PTR CALLBACK ToolDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPar
syncWidget(hwnd);
return TRUE;
+ case WM_HSCROLL:
+ if(lParam == GetDlgItem(hwnd, IDC_GAIN))
+ {
+ g_setup.gain100 = SendMessageW((HWND)lParam, (UINT)TBM_GETPOS, (WPARAM)0, (LPARAM)0);
+ saveGain(&g_setup);
+ sendSignal(DRV_SIGNAL_UPDATE_GAIN);
+ break;
+ }
+ break;
+
case WM_COMMAND:
switch(LOWORD(wParam))
{
diff --git a/utils/winmm_drv/cpl/resource.h b/utils/winmm_drv/cpl/resource.h
index 27b17e5..78461c5 100644
--- a/utils/winmm_drv/cpl/resource.h
+++ b/utils/winmm_drv/cpl/resource.h
@@ -32,5 +32,7 @@
#define IDC_CA_LABEL 1029
#define IDC_AUDIOOUT 1030
#define IDC_AUDIOOUT_LABEL 1031
+#define IDC_GAIN 1032
+#define IDC_GAIN_LABEL 1033
#define IDC_DRIVERNAME 40000
#define IDC_DRIVERDESC 40001
diff --git a/utils/winmm_drv/src/MidiSynth.cpp b/utils/winmm_drv/src/MidiSynth.cpp
index a03ee42..e559a4f 100644
--- a/utils/winmm_drv/src/MidiSynth.cpp
+++ b/utils/winmm_drv/src/MidiSynth.cpp
@@ -464,6 +464,16 @@ void MidiSynth::Render(float *bufpos, DWORD totalFrames)
adl_generateFormat(synth, framesToRender * s_audioChannels,
(ADL_UInt8*)bufpos, (ADL_UInt8*)bufpos + synthAudioFormat.containerSize,
&synthAudioFormat);
+
+ // Apply the volume
+ float g_l = volumeFactorL * gain;
+ float g_r = volumeFactorR * gain;
+ for(size_t i = 0; i < framesToRender * s_audioChannels; i += s_audioChannels)
+ {
+ bufpos[i + 0] *= g_l;
+ bufpos[i + 1] *= g_r;
+ }
+
synthEvent.Release();
framesRendered += framesToRender;
bufpos += s_audioChannels * framesToRender; // each frame consists of two samples for both the Left and Right channels
@@ -484,15 +494,19 @@ void MidiSynth::CheckForSignals()
switch(cmd)
{
- case 1: // Reload settings on the fly
+ case DRV_SIGNAL_RELOAD_SETUP: // Reload settings on the fly
this->loadSetup();
LoadSynthSetup();
break;
- case 2:
+ case DRV_SIGNAL_RESET_SYNTH:
adl_reset(synth);
break;
+ case DRV_SIGNAL_UPDATE_GAIN:
+ this->loadGain();
+ break;
+
default:
break;
}
@@ -513,6 +527,9 @@ void MidiSynth::LoadSettings()
chunkSize = MillisToFrames(10);
midiLatency = MillisToFrames(0);
useRingBuffer = false;
+ volumeFactorL = 1.0f;
+ volumeFactorR = 1.0f;
+ gain = 1.0f;
if(!useRingBuffer)
{
@@ -621,9 +638,27 @@ void MidiSynth::PlaySysex(Bit8u *bufpos, DWORD len)
synthEvent.Release();
}
+void MidiSynth::SetVolume(DWORD vol)
+{
+ volumeFactorR = (float)0xFFFF / HIWORD(vol);
+ volumeFactorL = (float)0xFFFF / LOWORD(vol);
+}
+
+DWORD MidiSynth::GetVolume()
+{
+ return MAKELONG((DWORD)(0xFFFF * volumeFactorL), (DWORD)(0xFFFF * volumeFactorR));
+}
+
void MidiSynth::loadSetup()
{
::loadSetup(&m_setup);
+ gain = (float)m_setup.gain100 / 100.f;
+}
+
+void MidiSynth::loadGain()
+{
+ ::getGain(&m_setup);
+ gain = (float)m_setup.gain100 / 100.f;
}
void MidiSynth::LoadSynthSetup()
diff --git a/utils/winmm_drv/src/MidiSynth.h b/utils/winmm_drv/src/MidiSynth.h
index a590a77..0442f7b 100644
--- a/utils/winmm_drv/src/MidiSynth.h
+++ b/utils/winmm_drv/src/MidiSynth.h
@@ -52,6 +52,9 @@ private:
Bit8u reverbMode;
Bit8u reverbTime;
Bit8u reverbLevel;
+ float volumeFactorL;
+ float volumeFactorR;
+ float gain;
float *buffer;
DWORD framesRendered;
@@ -82,7 +85,11 @@ public:
void PushMIDI(DWORD msg);
void PlaySysex(Bit8u *bufpos, DWORD len);
+ void SetVolume(DWORD vol);
+ DWORD GetVolume();
+
void loadSetup();
+ void loadGain();
void LoadSynthSetup();
};
diff --git a/utils/winmm_drv/src/winmm_drv.cpp b/utils/winmm_drv/src/winmm_drv.cpp
index 7f65dda..9baa56a 100644
--- a/utils/winmm_drv/src/winmm_drv.cpp
+++ b/utils/winmm_drv/src/winmm_drv.cpp
@@ -201,6 +201,7 @@ EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize)
CHAR synthName[] = "libADLMIDI synth\0";
WCHAR synthNameW[] = L"libADLMIDI synth\0";
+ DWORD support = MIDICAPS_VOLUME | MIDICAPS_LRVOLUME;
switch(capsSize)
{
@@ -214,7 +215,7 @@ EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize)
myCapsA->wVoices = 0;
myCapsA->wNotes = 0;
myCapsA->wChannelMask = 0xffff;
- myCapsA->dwSupport = 0;
+ myCapsA->dwSupport = support;
return MMSYSERR_NOERROR;
case(sizeof(MIDIOUTCAPSW)):
@@ -227,7 +228,7 @@ EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize)
myCapsW->wVoices = 0;
myCapsW->wNotes = 0;
myCapsW->wChannelMask = 0xffff;
- myCapsW->dwSupport = 0;
+ myCapsW->dwSupport = support;
return MMSYSERR_NOERROR;
case(sizeof(MIDIOUTCAPS2A)):
@@ -240,7 +241,7 @@ EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize)
myCaps2A->wVoices = 0;
myCaps2A->wNotes = 0;
myCaps2A->wChannelMask = 0xffff;
- myCaps2A->dwSupport = 0;
+ myCaps2A->dwSupport = support;
return MMSYSERR_NOERROR;
case(sizeof(MIDIOUTCAPS2W)):
@@ -253,7 +254,7 @@ EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize)
myCaps2W->wVoices = 0;
myCaps2W->wNotes = 0;
myCaps2W->wChannelMask = 0xffff;
- myCaps2W->dwSupport = 0;
+ myCaps2W->dwSupport = support;
return MMSYSERR_NOERROR;
default:
@@ -316,7 +317,8 @@ LONG CloseDriver(Driver *driver, UINT uDeviceID, UINT uMsg, DWORD_PTR dwUser, DW
return MMSYSERR_NOERROR;
}
-EXTERN_C DWORD __declspec(dllexport) __stdcall modMessage(DWORD uDeviceID, DWORD uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+EXTERN_C DWORD __declspec(dllexport) __stdcall
+modMessage(DWORD uDeviceID, DWORD uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
MIDIHDR *midiHdr;
Driver *driver = &drivers[uDeviceID];
@@ -377,6 +379,15 @@ EXTERN_C DWORD __declspec(dllexport) __stdcall modMessage(DWORD uDeviceID, DWORD
DoCallback(uDeviceID, dwUser, MOM_DONE, dwParam1, (DWORD_PTR)NULL);
return MMSYSERR_NOERROR;
+ case MODM_GETVOLUME:
+ if(dwParam1)
+ *(DWORD *)dwParam1 = midiSynth.GetVolume();
+ return MMSYSERR_NOERROR;
+
+ case MODM_SETVOLUME:
+ midiSynth.SetVolume(dwParam1);
+ return MMSYSERR_NOERROR;
+
case MODM_GETNUMDEVS:
return 0x1;