How to manage MIDI DJ consoles
Active MIDI DJ Console for .NET, through the MidiDjConsole property which encapsulates functionalities of the ClassMidiDjConsole class, can interface with external MIDI DJ Consoles and Controllers by receiving MIDI events from the console and by sending MIDI commands to the console itself.
Connecting the MIDI DJ Console
The connection between the console and the component can be started in two steps:
|•||opening the input and output MIDI devices of the console through respective calls to the MidiDevices.Open method: each call will generate the unique identifiers of the corresponding device.|
|•||connecting the console to the component by providing the unique identifiers of the input and output devices to the MidiDjConsole.Connect method.|
The the console and the component can be disconnected at a later time in two steps:
|•||disconnecting the console from the component through the MidiDjConsole.Disconnect method|
|•||closing the input and output MIDI devices of the console through respective calls to the MidiDevices.Close method.|
At any time you can know if a connection is established through the MidiDjConsole.IsConnected method.
Profiling the MIDI DJ Console
As you may know, each MIDI DJ Console comes with its own set of MIDI commands for notifying that a button control has been pushed or that a slider control has been moved or that a rotary knob control has been rotated on the physical console; at the same time, each MIDI DJ Console comes with its own set of MIDI commands for switching a led on or off or for displaying numbers on one or more VFD (Vacuum Fluorescent Display) available on the physical console.
Due to the fact that each DJ console, also when coming from the same vendor/manufacturer, may use a different set of MIDI commands, Active MIDI DJ Console for .NET comes with a set of methods allowing to create, edit and modify profiles (also known as maps) for each of the connected DJ consoles: in this way the container application could virtually connect to any model of DJ console by allowing the final user to create his own profiles or by loading profiles created by other users.
Each instance of the control can manage one single profile so, in case the container application should need to manage at the same time multiple connections to DJ consoles connected to the system, there would be the need to allocate more instances of the control.
When the single instance of the control is initialized, an empty profile is immediately available for usage so there is no need to create a new one: in case a profile should have already been programmatically filled with items or loaded from a file, it could be emptied through the MidiDjConsole.ProfileReset method.
A profile contains the following elements which allow identifying the MIDI DJ Console for which the profile was written:
|•||the "friendly" name of the MIDI DJ console which can be obtained/modified through the MidiDjConsole.ProfileInfoStringGet and MidiDjConsole.ProfileInfoStringSet methods having the nStringType parameter set to PROF_INFO_STRING_DEVICE_NAME|
|•||the product's identifier (also known as "PID") and the vendor's identifier (also known as "VID" or "MID") of the console. These two elements are read-only, can be obtained through the MidiDjConsole.ProfileInfoIdentifiersGet method and are saved automatically inside the profile's output XML file when saved to disk through the MidiDjConsole.ProfileSave method; in order to save the current profile which will be specific for a single model of DJ Console, the control needs that a connection with the physical MIDI DJ Console is established as mentioned on the section "Connecting the MIDI DJ Console" described above. When the saved XML file containing the profile will be loaded at a later time through the MidiDjConsole.ProfileLoad method, the control will verify that the connected console declares the same PID and VID and will return an error code if these fields should not match. In case the DJ console shouldn't be physically connected, you could in any case save the profile on a XML file on disk through the MidiDjConsole.ProfileSaveWithoutDevice method: profile's items will be save but the PID and VID identifiers will be obviously missing.|
|•||the name of the profile which can be obtained/modified through the MidiDjConsole.ProfileInfoStringGet and MidiDjConsole.ProfileInfoStringSet methods having the nStringType parameter set to PROF_INFO_STRING_NAME|
|•||the description of the profile which can be obtained/modified through the MidiDjConsole.ProfileInfoStringGet and MidiDjConsole.ProfileInfoStringSet methods having the nStringType parameter set to PROF_INFO_STRING_DESCRIPTION|
|•||the author of the profile which can be obtained/modified through the MidiDjConsole.ProfileInfoStringGet and MidiDjConsole.ProfileInfoStringSet methods having the nStringType parameter set to PROF_INFO_STRING_AUTHOR|
|•||an URL to a web site containing further information about the profile which can be obtained/modified through the MidiDjConsole.ProfileInfoStringGet and MidiDjConsole.ProfileInfoStringSet methods having the nStringType parameter set to PROF_INFO_STRING_URL|
|•||a set of items describing each of the physical controls available on the MIDI DJ Console: each profiled item contains the type of item, the description and the MIDI event/command used to identify the physical control. See the "Items for console's physical controls" section below for details.|
|•||if supported by the specific console, a set of displays (also known as VFD) describing each of the physical VFD available on the MIDI DJ Console. See the "Displays" section below for details.|
Items for console's physical controls
A profile's item is identified through a string of characters containing its name: when developing a profile you have the possibility to define your own set of names but it's strongly recommended assigning to each item the same name contained inside the technical specifications of the MIDI DJ console. Profile's item can be:
|•||enumerated through the MidiDjConsole.ProfileItemCountGet method in conjunction with the MidiDjConsole.ProfileItemNameGet method|
|•||added to the profile through the MidiDjConsole.ProfileItemAdd method|
|•||modified through the MidiDjConsole.ProfileItemModify method|
|•||removed from the profile through the MidiDjConsole.ProfileItemRemove method|
|•||checked for presence through the MidiDjConsole.ProfileItemExistsByName method|
Each item belongs to a specific type; supported types are:
|•||push button: this input control is a two states button (pressed / released) and you can be informed about manual actions happening on it through the CallbackMidiDjConsoleEventButtonPressed and CallbackMidiDjConsoleEventButtonReleased delegates. After having added the button to the profile through the MidiDjConsole.ProfileItemAdd method you can set the short MIDI command for this type of control through the MidiDjConsole.ProfileButtonMidiCommandSet method and obtain the current one through the MidiDjConsole.ProfileButtonMidiCommandGet method.|
|•||push button with embedded led: mostly identical to the previous type of item and notified through the same delegates, this type of button differs from the previous one for the fact that it carries a led inside which can be switched on or off using exactly the same short MIDI command reported when the button is pressed or released. Most of times the MIDI event for indicating an action occurring on the button is a "note on" (hex 90) for button pressed and a "note off" (hex 80) for button released followed by the code identifying the specific button; when the embedded led can be switched on or off using exactly the same MIDI command then you can use this specific type of button: it's important to note that this condition is not mandatory so you are free to separate the push button from the led by using two different items inside the profile.|
|•||range control: this type is again an input control and is used for physical controls which may assume a range of values (typically from 0 to 127) like sliders and rotary knobs and for other controls which may report values indicating a specific action, for example if a jog wheel has been rotated clockwise or anti-clockwise. A manual action happening on one of these controls will be notified through the CallbaclMidiDjConsoleEventRangeMoved delegate. After having added the control to the profile through the MidiDjConsole.ProfileItemAdd method you can set the short MIDI command for this type of control through the MidiDjConsole.ProfileRangeMidiCommandSet method and obtain the current one through the MidiDjConsole.ProfileRangeMidiCommandGet method.|
|•||led control and VFD (Vacuum Fluorescent Display) led items: differently from previous types of controls which work has input controls, this ones work as an output control and identifies a led that can be switched on or off through the MidiDjConsole.ProfileLedSwitch method or that can be blinked at a specific rate through the MidiDjConsole.ProfileLedBlink method. After having added the control to the profile through the MidiDjConsole.ProfileItemAdd method you can set the short MIDI command for this type of control through the MidiDjConsole.ProfileLedMidiCommandSet method and obtain the current one through the MidiDjConsole.ProfileLedMidiCommandGet method.|
|•||VFD (Vacuum Fluorescent Display) items not behaving as a simple led: differently from previous VFD led items, this ones work as an output control but not with a simple on/off status: to this category usually belong elements displaying numbers, for example the track number or the position of the track. After having added the control to the profile through the MidiDjConsole.ProfileItemAdd method you can set the short MIDI command for this type of control through the MidiDjConsole.ProfileDisplayMidiCommandSet method and obtain the current one through the MidiDjConsole.ProfileDisplayMidiCommandGet method. Data to display can be sent to the proper item through the MidiDjConsole.ProfileDisplayDataSet method.|
In case a manual action should happen on a physical input control still not added to the profile, the container application would be in any case notified through the CallbackMidiDjConsoleEventUnmapped delegate. Under certain situations, for example inside an application that would allow the final user developing a new profile or modifying an existing one, you may have the need to get an unmapped event also for items already stored inside the profile; for example, if a specific button should be already mapped inside the profile, when pressing the button you would receive the CallbackMidiDjConsoleEventButtonPressed delegate but you would no more get the specific short MIDI command used to map the button; by disabling events for already mapped items you could get the CallbackMidiDjConsoleEventUnmapped delegate for all of the physical controls and, if needed, you may modify the item inside the profile accordingly: this can be done by disabling mapped events through the MidiDjConsole.EnableMappedEvents method. The "ProfileEditor" project available inside the samples works exactly like this.
For each item contained inside the profile you can obtain the specific type (push button, led, etc.) through the MidiDjConsole.ProfileItemTypeGet and other information through the MidiDjConsole.ProfileItemInfoStringGet method.
At the beginning of this section dedicated to profile's items, we have already seen that we can enumerate items stored inside the profile through the MidiDjConsole.ProfileItemCountGet method in conjunction with the MidiDjConsole.ProfileItemNameGet method: these methods don't make distinctions about the type of control to which the item belongs: if you should need enumerating a specific type of control, for example push buttons only, you may use the combination of MidiDjConsole.ProfileTypedItemCountGet and MidiDjConsole.ProfileTypedItemNameGet methods.
If you need to verify if a specific short MIDI command has already been assigned to a specific type of control, you can use one between the MidiDjConsole.ProfileButtonNameGetByMidiCommand method for push buttons (with or without embedded led), MidiDjConsole.ProfileRangeNameGetByMidiCommand method for range controls and MidiDjConsole.ProfileLedNameGetByMidiCommand method for led controls.
VFD display segments
As already mentioned before, displays are usually known as VFD (Vacuum Fluorescent Display) and may contain one or more segments having a certain number of variable characters (each segment allowing to display a word or a very short sentence) and a certain number of leds which may switch on/off a fixed word or character. The image below shows the VFD belonging to deck A of a Denon DN-HC4500 console.
VFD leds can be switched on/off or blinked by adding them inside the profile as described inside the "Items for console's physical controls" section above; management of VFD segments is a bit more complex and the possibility to display variable words using an embedded character set is quite difficult to profile; the number of manufacturers using this kind of display on some of their console models is quite limited so, for this reason, the component doesn't allow adding VFD segments to the profile but their management is embedded directly inside the control itself.
At the moment Active MIDI DJ Console for .NET comes with native support for displays of the Denon DN-HC4500 console only: other models may be added upon specific request by sending us the technical specifications of the console.
Displays segments can be enumerated through the MidiDjConsole.DisplaySegmentCountGet method in conjunction with the MidiDjConsole.DisplaySegmentInfoGet method; once enumerated you can show single characters or strings of characters using the following methods:
|•||the MidiDjConsole.ProfileDisplaySymbol method allows displaying a character's symbol inside a specific cell of the given segment.|
|•||the MidiDjConsole.ProfileDisplayString method allows displaying a string of characters on the given segment|
|•||the MidiDjConsole.ProfileDisplayStringScroll method allows scrolling a string of characters on the given segment|
A sample of usage of MIDI DJ Consoles profiling and testing can be found inside the "ProfileEditor" Visual Basic.NET and Visual C# projects installed with the component's setup package.