Introduction
MIDI provides a common interface that allows interconnecting a vast array of electronic devices. Getting those devices working cooperatively is an entirely different story. This project aims to provide a solution to that specific problem.
This article describes ProjectMIDI
, a set of small, cooperative MIDI applications. I'll try to explain how the code works and give a high level description of how it is implemented. To keep the size of this article manageable, I'll refer you to the actual source files instead of copying the code into this article. I apologize that this means that you may need to flip back and forth between this article and the source code.
One of my reasons for writing this article is to solicit your feedback. So please email me with your suggestions.
ProjectMIDI
is a non-commercial software project designed to provide extensible control of MIDI devices in a live performance environment. The purpose of this project is to build software which will integrate the latest, readily available technologies into a leading edge MIDI setup for live performance.
Some of this code is still being extended. I have tried to clean it up, but I apologize for any loose ends I may have left laying about in the code.
I'm hoping that other programming hobbyists will be interested in writing their own assemblies to extend the project. That is why I am making it open and extensible, and documenting how the pieces work and interact with each other. I'm working primarily in C#, but I believe that any .NET language could be used. I am also providing a VB .NET sample assembly.
One of my key design points is to provide an architecture and function in the core assemblies that makes it very simple to create additional functional assemblies.
Quick Start
To play with the code, download and unzip the executables file. This file contains a set of directories and sample files. Then launch the ProjectMidi.exe file. It will prompt you for the path to your files. Simply select the same directory.
Background
I am a musician and a programmer. I love doing both. Frankly, I probably enjoy the technology more than just the musical aspects of playing. Ah, give me a control panel with a whole bunch of knobs that make sound...
That said, I've never found any software that really allows me to use much of the capability of my MIDI equipment in a live performance environment. Sure, some things can be done using programs like Cakewalk Sonar or Tascam Gigastudio. But whenever I use one of these programs I am always left wanting to do more. I am very familiar with what MIDI hardware can do, and I want to be able to exploit that capability. I am writing this software to allow really taking advantage of the MIDI hardware that I own.
I also want others to participate if they feel so inclined. I am making the source code openly available. I have also created this website to serve as the meeting place for anyone interested in ProjectMIDI
.
What can you do with ProjectMIDI?
A tutorial on using ProjectMIDI
is available on the ProjectMIDI
website.
I'm using ProjectMIDI
each Sunday drumming and playing keyboards for my church band. Here are some of the things that the software currently does for me:
-
It displays sheet music or lyric sheets during live performance
I scan my music and use this software to display it during performance. I have a small tablet PC that mounts to my drum kit, and a laptop that sits above my MIDI keyboard. I use MIDI to flip pages and advance songs. I can program the cow bell pad to do this, but usually use the TD8's Inc/Dec buttons or a foot switch.
-
I organize my songs into "sets"
This allows me to easily advance from song to song during a gig. The SongSet
dialog is shown to the right. The song listing on the right side helps me remember the order of songs in the set. The left side shows all of the sets I've created. I organize these by date.
-
Set patches for each song and/or page
When 'flipping pages' as described above, set the voicing of each of my MIDI instruments for each song and page. I can set different drum sounds to my pads based on song and page.
-
Annotate my music using the Tablet PC's Stylus
This is way cool. I simply write on the tablet over the displayed music to make performance notes. The software then saves this and displays it each time I display that page.
-
Play an associated MP3 file
Sometimes during practice we need to hear the original recording to get a part down. I can record an MP3 file of the song and associate it with the music. All I need to do is hit a play button while displaying that song. I can also use this to practice with the song.
-
Quickly assign drum sounds to any drum pad and patches to the keyboard
Although I tend to use the same drum kits for most songs, I often want to reassign one or two pads for a unique sound. I can use the TD8's controls to do this, but it is complicated and slow, and changes get easily lost. Using this program makes it quick and easy, and my changes will be remembered for the next time I display the song.
ProjectMIDI Modular Approach
What I've realized (and the subject of a lot of programming books) is that since there is "so" much that one can do with MIDI, it becomes extremely important to break the programming up into small manageable pieces.
-
ProjectMIDI Application
This is the main program. It is responsible for locating and loading all of the other pieces. These other pieces are implemented as .NET assemblies. The technical details of these assemblies, including instructions for creating new assemblies is discussed on the ProjectMIDI website and will be discussed later in these articles.
-
Connections Assembly
Connections between events and actions between assemblies are established dynamically. The Connections assembly provides the controls for making and remembering these connections.
-
Songset Assembly
Songset
provides the functionality to organize songs into sets. It communicates with other modules using events to keep them in sync. Each module typically operates based on the song and page currently selected.
-
SubMenu Assembly
This assembly implements multiple level custom menus.
-
PDF Assembly
The PDF Applet displays sheet music (or anything for that matter) from PDF files. This would typically be the primary user interface used during live performance.
-
TIFF Assembly
Alternatively, the TIFF Applet can be used to display the sheet music from TIFF files.
-
Ink Assembly
The Ink Applet allows writing on top of the sheet music displayed by PDF or TIFF using a tablet PC's stylus. This requires Windows XP Tablet PC Edition. This is a really great way to annotate and mark up your music for live performance.
-
MIDI Assembly
This assembly will connect to all of the MIDI ports present on the system and other assemblies to connect to them.
-
MIDI Device Assemblies
Support for a specific MIDI device is provided by a "device assembly". The device assembly can implement whatever device specific functionality is desired. Typically it will contain a dialog to allow specific voices (patches) to be associated with specific songs and even pages. Dialogs can be implemented to allow programming new voices if desired. This of course depends on the capabilities of the particular device.
Input controls present on a MIDI device are named and identified to ProjectMIDI
by the device assembly. These can then be connected by the user to appropriate "actions".
ProjectMIDI Connections
ProjectMIDI
allows you to control the way that the different input "events" on your system are connected to output "actions".
Each assembly publishes the "events" that it generates and the "actions" that it can respond to. This is done in a manner that does not requires "a priori" knowledge of other modules. ProjectMIDI
then provides several mechanisms to connect "events" to "actions".
Events include such things as:
- MIDI Events: These includes keys, drum pads, knobs, foot pedals, and buttons
- Windows dialog controls: These include sliders and pushbuttons
- Custom menus:
ProjectMIDI
provides the ability to create your own menus
For example, you may wish to use a MIDI keyboard's foot switch to change the displayed music page. Or you may wish to launch a frequently used MIDI device editor from one or more convenient custom menus. This can be done easily by mapping the particular event to the desired action.
ProjectMidi Events
Events are things which are caused by user interaction. This includes MIDI events which result when you operate your MIDI equipment, and events caused by interacting with the software.
ProjectMidi Actions
Actions which things that can be controlled or triggered by events. This includes selecting songs, pages, or patches and launching a MIDI device voice editor.
Connections
You can make "connections" between "events" and "actions". Some connections will have been created by default when you installed the program. Other connections will be specific to your setup and depend on the MIDI equipment that you use.
The "Connections Editor" pictured here allows you to change or create new connections.
Sorting Connections
The connections list can be sorted by clicking on the column headings. Clicking on the "ID" column heading will sort the connections by ID number.
Clicking on the "Source" or "Event" column heading will sort the connections by the Source Assembly name and Event.
Likewise, clicking on the "Dest" or "Actions" column heading will sort the connections list by the Destination Assembly and Action.
Adding a Connection
You can add new connections by right-clicking anywhere in the list, and selecting the 1st menu item 'Add New Connection'. A new connection will be created at the end of the list. You will then need to select a source event and destination action for the new connection.
Deleting a Connection
You can delete unused or unwanted connections by selecting the connection, then right-clicking on it and selecting the 'Delete Selected Connection' menu item.
Changing a Connections Source Assembly or Event
You can change the Source Assembly or Event by selecting the connection, then right-clicking on the Source or Event field. The context menu displayed will contain a list of assembly names or event names.
Changing a Connections Destination Assembly or Action
You can change the Destination Assembly or Action by selecting the connection, then right-clicking on the Destination or Action field. The context menu displayed will contain a list of assembly names or event names.
ProjectMIDI Customizable Menus
ProjectMIDI
allows you to customize any of its menus. Menus are defined by the "connections" made between a menu event and an action. By default, the name appearing on the menu will be the name of the action.
You can use the menu editor dialog to rearrange the items in a menu, as well as to change the text that appears on the menu.
You can directly edit the text of each menu item.
Right-clicking on a menu item displays a context menu allowing you to add or remove a separator line, or move the menu item up or down.
Song Sets, Songs, Pages, and Patches
ProjectMIDI
organizes music into Song Sets, Songs, Pages, and Patches.
Song Sets
Song sets are a collection of songs. You can group songs together any way you like. Typically this would be a set of songs to be played at a particular gig. Alternatively, it can be songs of a particular theme, or by an artist, etc.
Songs
A song is the basic unit of organization. Each of the assemblies in ProjectMIDI
typically associate a group of settings with each song. This could be for example a mapping of sounds to keyboard zones or drum pads.
Pages
Songs can be divided up into pages. Each page can have its own sounds and settings associated with it.
Patches
Pages can be further divided up into Patches. This would be done for example if you wanted to have different sounds associated with a verse and a chorus, but both of those appeared on the same sheet music page.
Saving Your Sets
Song sets are saved in files in the SongSets folder. These can then be reloaded at a later time for reuse. Use the 'Files' menu item in the SongSets assembly dialog to load and save your sets.
Using the code
In this section I will describe how ProjectMIDI
is implemented and how you can extend it with your own code. I will provide source code examples to allow you to create your own MIDI applets or device modules.
What you will need
You will need Visual Studio .NET. ProjectMIDI
is implemented as a set of .NET assemblies. Creating a new Applet or Device Module involves creating a new .NET assembly which contains a class which implements particular interfaces defined by ProjectMIDI
. It also uses custom attributes to allow ProjectMIDI
to interconnect events and actions (special event handlers) using reflection.
ProjectMIDI
implements "late binding" of .NET assemblies. Therefore, new assemblies can be created, and ProjectMIDI
will work with them without having to know about them.
Architecture
ProjectMIDI
works by dividing its functionality up into multiple DLL .NET assemblies. These assemblies are "late binding" meaning that ProjectMIDI
will search for and load any assemblies which contain a class that implements an interface known to it. I'll refer to these DLL files simply as "assemblies" within these pages.
The primary executable is ProjectMIDI.exe. This is the core program which in turn locates and loads all other assemblies.
Sets, Songs, Pages and Patches Data Model
ProjectMidi.exe implements the basic structure which organizes data into Song Sets, Songs, Pages and Patches.
Song Sets
A group of 1 or more song names can be organized into a collection referred to as a "Song Set". This can be the set of songs played for a particular gig, or maybe a set of songs related by theme or style. In fact, it doesn't even really need to be a collection of songs at all, but could be a set of MIDI setups.
Songs
These are the "names" which are passed to each assembly. The existing PDF and TIFF applets assume that this is the name of a PDF or TIFF file (minus the file extension). All of the other existing assemblies treat this strictly as a filename used to its data.
Pages
Songs can be broken down into multiple pieces referred to as pages. The PDF, TIFF and Ink assemblies will use this to display a different music page and notes. Device modules can select a separate patch or other settings.
Patches
Patches allow breaking a page into multiple sections, each with a different set of patches. PDF, TIFF and Ink assemblies ignore this parameter. However, a device module should allow selecting a different patch or group of settings for each patch.
Response to Song, Page or Patch changes
Assemblies can choose to be notified whenever the song, page or patch changes. How the assembly responds is left to each assembly to decide and implement.
Events and Actions Model
ProjectMIDI
attempts to provide a very high degree of flexibility and extensibility. One of the ways that it does this is by "generalizing" the way that user inputs or events are associated with the resultant action.
Events
Each assembly can define and publish a set of events that it supports. For an Applet this might be a menu or pushbutton, while for a Device Assembly it could be a hardware control (slider or knob) or foot pedal or MIDI trigger.
Events are exposed to ProjectMIDI
by giving them predefined "custom attributes". These attributes specify the name to display to the user as well as the number of values that the input provides.
The name given by the attribute is important in order to make using them easy and intuitive. For example, I've worked with MIDI software in the past which allows connecting a particular MIDI data type (eg. program change) to an action. It isn't at all clear though what this means. I'd much rather be able to specify that the "TD8 Inc/Dec Buttons" will cause an action instead of having to look up and specify the MIDI data type and value.
In addition to providing a name to an input, the custom attribute also specifies the number of possible input values. This allows better matching of inputs to outputs. For example, connecting a 128 position knob to a simple on/off type action might require interpreting values 0-63 as "off" and 64-127 as "on".
Events can have an "autoconnect" name associated with them. ProjectMIDI
will automatically connect events and actions with matching autoconnect names at startup.
Actions
Each assembly also defines and publishes a set of actions which it implements. These are things like "Next page", "Display TD8 Patch Editor", and so forth. This is limited only by our imaginations.
Actions are methods with a signature that matches that needed for handling the events described above. A custom attribute is used to specify the friendly name and number of values the action can handle.
The data passed to actions from events is passed in an EventArgs
or a class derived from it.
Connection lists
Inputs can be connected to actions in a couple of ways:
- Using matching autoconnect names
- By using the Connections dialog
A dialog is provided to allow the user to manually specify additional connections, or to disable autoconnections.
Assembly defined Event/Action Associations
In addition the 2 methods described above, different assemblies can communicate with each other in a couple other ways:
- Expose Events, Actions, Methods, or Properties
ProjectMIDI
provides a mechanism for assemblies to view and connect with other assemblies provided they have flagged these using ProjectMIDI
's custom attributes.
- Use multiple interface derivation
In addition to deriving from IProjectMidi
, an assembly's ProjectMIDI
class can derive from additional interfaces. Another assembly can search the list of ProjectMIDI
loaded assemblies using a mechanism provided by ProjectMIDI
. Each can be tested to see if it derives from the desired interface. Once found, the custom interface can be used directly.
Persistence
User specified connections are persisted to an XML file actions.xml in the ProjectMIDI
root folder. These will be restored each time ProjectMIDI
starts.
ProjectMIDI Main Executable
ProjectMIDI.exe is the primary application file. When it is started, it in turn loads all of the other ProjectMIDI
assemblies.
It loads as a TaskBar icon. It displays a list of the assemblies that it has loaded in the 'Assemblies' submenu. Assemblies which can display a dialog can be shown or hidden by clicking on its name in the 'Assemblies' submenu.
ProjectMIDI.exe provides startup sequencing to allow assemblies to start in an orderly fashion. For example, it may be necessary for an assembly to perform some startup initialization after all assemblies have been loaded. Or it may need to wait even further until all connections have been established between assemblies.
All ProjectMIDI
assemblies derive from the IProjectMidi
interface. This fact is used by ProjectMIDI.exe to identify ProjectMIDI
assemblies.
public interface IProjectMidi
{
IProjectMidiParent ProjectMidiParent { set; }
void PerformStartProcessing( StartPhase phase );
}
public enum StartPhase {
AfterLoading,
AllAssembliesLoaded,
StartConnecting,
FirstTimeEver,
AllAssembliesConnected,
InitDone,
Terminating
};
ProjectMIDI
provides the following interface to assist assemblies in performing startup sequencing and connecting with other assemblies:
public interface IProjectMidiParent : IProjectMidi
{
string ProjectMidiPath { get; }
RegistryKey ProjectMidiKey { get; }
IIProjectMidiCollection IProjectMidis { get; }
void CreateAConnection(string eventAsmName, string eventName,
string actionAsmName, string actionName,
string connType, string connIntData,
string connEnabled, string connFollowsSeparator,
string connStringData);
}
This interface is passed to the ProjectMidiParent
property of each assembly immediately after it is loaded.
ProjectMidiPath
indicates the file path to the root ProjectMIDI folder. Any folders created and used by ProjectMIDI
assemblies should be created beneath this folder.
Likewise any registry information created and used should be located under the ProjectMidiKey
.
IProjectMidis
provides a standard collection of IProjectMidi
interface pointers allowing all other loaded assemblies to be accessed. Note that other assemblies may not have been loaded at the time that the constructor is run. In order to ensure that the other assembly has been loaded, wait for PerformStartProcessing
to be called with the phase
parameter set to AllAssembliesLoaded
.
The CreateAConnection
method is used by an assembly to create connections. This will typically be done only the first time that it is loaded. Connections are persisted by the Connections assembly.
SongSet Assembly
This assembly manages the song set collection. Other assemblies can connect to this assembly in order to control or receive notifications regarding changes to the current song set, song number, or patch.
ProjectMIDI Song Parameter Persistence
Most assemblies will need to persist settings related to each song. The SongSet
assembly provides a set of persistence methods which can be used to do this.
In order to use the ISongSet
interface, an assembly must wait until all assemblies are loaded, then search the list of assemblies for one that implements the ISongSet
interface. You can find an example of this is the PDF.cs file. PerformStartProcessing
is called, and when passed the AllAssembliesLoaded
parameter it in turn calls the AllAssembliesLoaded()
method. This method then searches the IProjectMidis
collection for the assembly which implements ISongSet
.
The ISongSet
interface can be used to determine the current song, page, and patch. It also provides methods to save and restore custom song parameters. These parameters will be saved by the SongSet
assembly in a songdata.xml file.
public interface ISongSet
{
string CurrentSongName { get; }
int CurrentSongNum { get; set; }
int CurrentPageNum { get; set; }
int CurrentPatchNum { get; set; }
string GetSongParameter( string name, string defaultdata );
void SetSongParameter( string name, string data );
ISongCollection Songs { get; }
}
Once you have the ISongSet
interface pointer, it can be used to call the SetSongParameter()
and GetSongParameter()
methods.
Since all assemblies can use the persistence methods, select the name parameter such that it will not conflict another assembly's parameters. This can be done by using the assembly name as part of the parameter name.
Connections Assembly
The Connections assembly provides late-binding of connections between assembly events and event handlers (actions).
Reflection is used to identify those events and actions that are intended to be used for this purpose.
ProjectMidi Events
Events which happen within an assembly can be exposed to the rest of the assemblies by giving them the [ProjectMidiEventAttribute]
attribute. This attribute informs ProjectMIDI
that this event can be connected to "ProjectMidi
Actions". This event must conform to the following signature:
public delegate void ProjectMidiEventHandler(object sender, EventArgs e);
public event ProjectMidiEventHandler EventName;
Refer to the ProjectMidiInterfaces.cs file for the definition of classes derived from EventArgs
which may be used within ProjectMIDI
.
ProjectMidiEventAttribute
This attribute identifies an event as a ProjectMIDI
event. It can optionally specify the following parameters:
-
Name
Gives a name to the event. This name will be displayed in the Connections
dialog.
-
Number of values
Specifies the number of different values which this event can generate. For menu item, this would be 1. For a device slider this could be 128.
-
Auto-Connection Name
The first time that ProjectMIDI
loads an assembly, it will search for events and actions with matching "Auto-Connect" names and automatically connect them.
-
Connection Type
This identifies the "type" of connection. This information is used internally by ProjectMIDI
. For most connections this should be ConnectionType.Normal
.
-
Tooltip string
This string will be displayed in the "Connections
Dialog" when the mouse hovers over this event.
Dynamic Events
Some events may need to be created dynamically. For example, Midi Input Port events will be created depending on the particular MIDI hardware installed.
Classes which need to implement "dynamic events" must implement the IProjectMidiDynamicEvent
interface.
To create a dynamic event, use the IProjectMidiConnection
interface to add a new PMEventInfo
object to the IProjectMidiConnection.AllEvents
collection.
Refer to the IProjectMidiDynamicEvent
code in MidiPort.cs.
ProjectMidi Actions
Actions which are implemented within an assembly are exposed to the rest of the assemblies by giving them the [ProjectMidiActionAttribute]
attribute. This attribute informs ProjectMIDI
that ProjectMidi
Events can be connected to them. These actions must conform to the following signature:
public void HandlerName(object sender, EventArgs e);
As you can see, this signature matches the ProjectMidiEventHandler
delegate signature listed above it.
Refer to the sample source code for actual code listings and comments.
Dynamic Actions
Some actions may need to be created dynamically. For example, Midi Output Port actions will be created depending on the particular MIDI hardware installed.
Classes which need to implement "dynamic actions" must implement the IProjectMidiDynamicActions
interface.
To create a dynamic action, use the IProjectMidiConnection
interface to add a new PMActionInfo
object to the IProjectMidiConnection
.AllActions
collection.
Refer to the IProjectMidiDynamicAction
code in MidiPort.cs.
Automatic Connections
Some connections will need to be connected automatically when ProjectMIDI
starts. For example, connecting a source of trace messages to the Trace Message assembly, which then displays the messages. This is accomplished by specifying a common connection name in the attributes for both the events and the actions.
The first time that ProjectMIDI
loads an assembly, it will search for events and actions that specify the same "autoconnect" name. When found, they will be automatically connected.
Existing connections will be saved to connections.xml. When ProjectMIDI
starts, it will load connections.xml and reconnect events and actions previously connected.
SubMenu Assembly
This assembly implements multilevel context menus. A action is exposed which can be connected to an assembly's menu event.
Midi Assembly
The Midi assembly provides connections to and from the MIDI ports present on the system. It opens all MIDI ports and dynamically creates events and actions to each of them.
GMSynth Assembly
This assembly provides support for a GM synth. It interfaces with the songset assembly's ISongSet
interface to provide a program change for each song selected.
This assembly provides a good starting point for creating your own MIDI device assembly.
PDF Assembly
This assembly interfaces with Adobe Acrobat to display a PDF file based on the currently selected song and page.
TIFF Assembly
This assembly is similar to the PDF assembly. It displays a TIFF file based on the currently selected song and page.
Sample Assembly
This assembly is provided as an example of how to expose events and actions. It is a good starting point for writing your own ProjectMIDI
assembly.
TD8 Assembly
This assembly interfaces with a Roland TD8 drum module. It allows specifying the drum pad patches for each song and page.
This module is fairly large. I don't recommend using to create your own assembly. It does provide an example of how to generate system exclusive messages though.
XP30 Assembly
This assembly interfaces with a Roland XP30 MIDI keyboard. It selects an XP30 voice based on the currently selected song.
Ink Assembly
This assembly uses and requires the Microsoft Tablet PC SDK. It will connect itself to the PDF or TIFF assembly to "collect ink". It allows drawing notes on the displayed PDF or TIFF. The ink will then be displayed along with PDF or TIFF associated with the currently selected song and page.
It searches all assemblies looking for one which implements the IHasDisplaySurfaces
interface. When found, it will use this interface to hook its OnDisplayResize
event and get its display handle for use by the Microsoft Table PC SDK InkOverlay
object.
Building and running the code
Building the code should be very straight forward if you do not rearrange the folders. Building might become a bit tricky if you do because there are multiple executables with some interdependencies. These dependencies are as follows:
- All assemblies derive from
IProjectMidi
which is defined in ProjectMidiInterfaces.dll. If you rearrange the location of the various directories, this reference may become invalid. If this happens then you will need to correct the reference to ProjectMidiInterfaces.dll in order to resolve this.
- MP3 requires the Quartz library: This should be included with Windows XP
- Ink requires that the Microsoft Tablet PC SDK be installed: This can be obtained from the Microsoft MSDN site.
After downloading and extracting the files, open either the ProjectMidiAll.sln or the ProjectMidiCore.sln file. This should launch Visual Studio .NET and display the solution containing all or just the required project files. I recommend that you copy the ProjectMidiAll.sln file, and remove the projects that you do not want from it.
Note that you will probably not want to include and build every project. Only include those that are applicable to your system.
Project Name |
Executable Created |
Description |
Notes |
ProjectMIDI |
ProjectMidi.exe |
Main executable |
Required |
Connections |
Connections.dll |
Manages connections between assemblies |
Required |
GMSynth |
GMSynth.dll |
Example MIDI device assembly |
Include for sample purposes, or to interface with a General MIDI device |
Ink |
Ink.dll |
Adds ability to scribble notes over displayed PDFs or TIFFs. |
Include if you have a Tablet PC or digitizer pad and have installed the MS Tablet PC SDK. |
Midi |
Midi.dll |
Provides communication with MIDI ports. |
Required if MIDI will be used |
MP3 |
MP3.dll |
Provides MP3 playback functions |
Include if MP3 playback is desired. Requires Quartzlib. |
PDF |
PDF.dll |
Provides the PDF display functions |
Requires the full version of Acrobat be installed. |
ProjectMidiInterfaces |
ProjectMidiInterfaces.dll |
Provides several key interface implementations |
Required. Used by most other DLLs |
SampleAssembly |
SampleAssembly.dll |
This is a sample assembly that you can use to rename and start your own assembly |
Optional |
SongSet |
SongSet.dll |
Provides the song Set, Song, and Patch functions. |
Required |
SubMenu |
SubMenu.dll |
Provides the customizable menu functions. |
Required |
TD8 |
TD8.dll |
Provides interface to Roland TD8 MIDI drum device |
Include if you own a Roland TD8 drum module |
TIFF |
TIFF.dll |
Provides .tif display functions. This is provided as an alternative to PDF |
Include if you do not have PDF installed |
TraceWindow |
TraceWindow.dll |
Provides a window to display trace messages from ProjectMIDI.exe and other assemblies. |
Optional |
us428 |
us428.dll |
Provides interface with Tascam US-428 control surface |
Include if you own a Tascam US-428 control surface |
VBAssembly |
VBAssembly.dll |
This is a sample VB assembly |
Include as a sample if you plan on working in VB |
XP30 |
XP30.dll |
Provides interface to Roland XP30 MIDI keyboard |
Include if you own a Roland XP30 keyboard |
Running the code the first time
Before running ProjectMIDI
, you will need to copy all of the created assemblies (.DLLs) to the Assemblies folder. I've setup a post-build batch file to perform this copy automatically to the Runtime/Assemblies folder. If you move this folder then you will need to either update each of these batch files, or else copy the files manually before launching ProjectMidi.exe.
When the ProjectMIDI.exe executable is run the first time, it will search for its environment variables. In particular, it needs to know the FoldersPath
. It will prompt the user for this path if not found. If the full installer is used, this path will be created. If you are building the code from scratch without having run the installer, then you will need to create these folders and copy your files to them. Be sure to copy all of the .DLLs created to the /Assemblies folder. When ProjectMIDI.exe is run the first time, it will ask where the ProjectMidi folder is located. Select the folder which contains all of these other folders. This variable points to the path which contains the following folders:
Folder Name |
Folder Contains |
Used by Assembly |
Assemblies |
All ProjectMIDI assembly DLLs |
ProjectMIDI.exe |
Ink |
Tablet PC Ink files |
Ink.dll |
PDFs |
All PDF files |
PDF.dll |
Sets |
All .set song set files |
SongSet.dll |
TD8 |
All .td8 drum voice files |
TD8.dll |
TIFFs |
All .tif files |
TIFF.dll |
Which of these folders you need will depend on which of the DLLs you include on your system. You probably will not want to include both PDFs and TIFFs. Choose PDFs if you have Acrobat installed on your system, otherwise use TIFFs.
Likewise, include Ink and the Ink.dll if you have a Tablet PC and have installed the Table PC SDK.
Points of Interest
I learned a lot about .NET executable files during this project. I think it was worth it though. The platform I've created allows very quick creation of MIDI applets which I will use to fully exploit the capability of my existing and future MIDI hardware.
History
Date |
Description |
8 Jan 2006 |
Initial document creation using combined content from www.ProjectMIDI.com pages |