Closed scuba156 closed 4 years ago
Hi,
DryWetMIDI uses right constants. MIDICAPS_ constants are not same as WAVECAPS_ ones (used by NAudio for audio managing rather than MIDI managing).
Constants are listed in MIDIOUTCAPS structure official docs: https://docs.microsoft.com/en-us/previous-versions/dd798467(v=vs.85) (see dwSupport field description). Values of the constants can be found on the web.
So constants are absolutely right. Please describe your problem in more details with exact errors descriptions and code if possible. I'm pretty sure that it's not related with the library but maybe I'm wrong :)
I just double-checked and you are correct, that is my bad. As I stated, I have no experience working with MIDI, and the above is what came out of a little bit of searching.
The issue is I currently have no reliable way to check if the volume is able to be set for a device. Basically, I am attempting to set the volume on an OutputDevice using OutputDevice.Volume only if OutputDevice.SupportsVolumeControl returns true, but it always returns the following exception:
MidiDeviceException: This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.
Melanchall.DryWetMidi.Devices.MidiDevice.ProcessMmResult (System.UInt32 mmResult) (at <67b7321d99db425791cba940e49a6525>:0)
Melanchall.DryWetMidi.Devices.OutputDevice.set_Volume (Melanchall.DryWetMidi.Devices.Volume value) (at <67b7321d99db425791cba940e49a6525>:0)
I'm not testing with any hardware devices, just Windows built-in 'GS Wavetable Synth' and CoolSoft's 'VirtualMIDISynth 2'
Code I use for setting the volume:
// Variables being used
private OutputDevice midiDevice;
private ushort musicVolume;
// Code used to set volume after setting the OutputDevice
if (midiDevice.SupportsVolumeControl) {
midiDevice.Volume = new Volume(musicVolume);
}
Yes, volume control should be supported but volume changing fails indeed. I suppose it's related to those software synths. I've created question on midi.org: https://www.midi.org/forum/4733-microsoft-gs-wavetable-synth-and-midioutsetvolume. Maybe someone will help us with this behavior.
Thank you for taking the time to help with this issue, I appreciate it. Your library is the only one I could find that simply works and does not have timing/precision issues.
I've responded to the thread you created on midi.org with any information I could to help find out the cause of this issue. While my knowledge on the subject matter is limited, I am happy to help out where I can.
Setting the velocity on each note to change the volume seems to be a workaround for now, but is clunky and far from ideal.
Please note that velocity is not the same thing as volume. Using velocity as volume control can be workaround in some cases, but won't work in general case. How velocity handled is completely up to synth you use to make sound from your MIDI data. There are a lot of synths and presets inside them that ignore velocity.
Finally it's a bug in the library. I forgot to call EnsureHandleIsCreated
in Volume
get/set.
Thank you a lot for this issue!
@scuba156 Please take new version and let me know if the problem is solved.
Thank you for the information regarding velocity. And thank you for taking the time to investigate this bug as well.
I've compiled your latest commit and tested it, and it does indeed now work with GS Wavetable Synth which is great. It still seems to fail with Virtual MIDI Synth, but that appears to be an issue with that specific virtual synth driver, as I also tested with another called omniMIDI and volume control works with that.
Virtual MIDI Synth does have it's own volume control mixer so a user could control volume through that if they wish.
It's my first time playing around with MIDI so I am no expert on this subject but it seems to me like MidiOutWinApi.MidiCaps has the incorrect flags set as I am having issues when determining the supported features of a Midi device.
I am attempting to check if Volume is supported on my device by checking MidiDevice.SupportsVolumeControl which returns true but MidiDevice.Volume returns an exception saying either no was driver found or the function is not supported (Tested with 2 devices - 'gs wavetable synth' and a VirtualMIDISynth device).
mmeapi.h defines WAVECAPS as the following:
NAudio also appears to be using the same above values.
Compared to the values in DryWetMidi: https://github.com/melanchall/drywetmidi/blob/6ae83106199758571fef86d732bed40ca9036bd1/DryWetMidi/Devices/OutputDevice/MidiOutWinApi.cs#L26-L33