Summary: In this project you will create your own LabVIEW application that can produce a standard MIDI file. You will first develop a library of utility subVIs that produce the various components of the file (header chunk, track chunks, MIDI messages, meta-events, and delta times), as well as a subVI to write the finished binary file. You will then combine these into a a top-level VI (application) that creates a complete MIDI file based on an algorithm of your choosing.
If you have not done so already, please study the pre-requisite modules, MIDI Messages and Standard MIDI Files. You will need to refer to both of these modules in order to complete this activity. Also, you will find it helpful to have already worked through the mini-project MIDI File Parsing.
In this project you will create your own LabVIEW application that can produce a standard MIDI file. You will first develop a library of six subVIs that can be combined into a top-level VI that operates just like MIDI_UpDown.vi below (click the “Run” button (right-pointing arrow) to create the MIDI file, then double-click on the MIDI file to hear it played by your soundcard):
Download LabVIEW Source
MIDI_UpDown.vi produces a two-track MIDI file, with one track an ascending chromatic scale and the other a descending chromatic scale. You can select the voice for each track by choosing a tone number in the range 1 to 128. You can also select the duration of each note (“on time”) and space between the notes (“off time”).
Remember, MIDI_UpDown.vi is simply a demonstration of a top-level VI constructed from the subVIs that you will make. Once you have constructed your library of subVIs, you will be able to use them in a wide array of projects; here are some ideas:
These are just a few ideas – be creative! Remember to take advantage of your ability to control the sound type, note-on velocity, pitch bend, etc.
Click the image below to take a quick tour of the top-level block diagram of MIDI_UpDown.vi. The role of each subVI will be discussed in some detail, and you will have a better idea of the design requirements for each of the subVIs you will create.
You will create six subVIs in this part of the project. Develop them in the exact order presented! Also, make sure you test and debug each subVI before moving on to the next. Many of the concepts and techniques you learn at the beginning carry forward to the more sophisticated subVIs you develop toward the end.
The requirements for the subVIs are detailed in the following sections. Input Requirements specify the name of the front panel control, its data type, and default value, if needed). Output Requirements are similar, but refer to the front panel indicators. Behavior Requirements describe in broad terms the nature of the block diagram you need to design and build.
An interactive front panel is provided for each of the subVIs as an aid to your development and testing. By running the subVI with test values, you can better understand the behavioral requirements. Also, you can compare your finished result with the “gold standard,” so to speak.
Screencast videos offer coding tips relevant to each subVI. The videos assume that you are developing the modules in the order presented.
All right, time to get to work!
midi_PutBytes.vi accepts a string and writes it to a file. If the file already exists, the user should be prompted before overwriting the file.
error outYour finished subVI should behave like this one:
Download LabVIEW Source
Watch the screencast video to learn how to use the built-in subVIs Open/Create/Replace File, Write to Binary File, and Close File. Refer to the module Creating a subVI in LabVIEW to learn how to create a subVI.
Once all of the track strings have been created, midi_AttachHeader.vi will attach a header chunk to the beginning of the string to make a complete string prior to writing to a file. The header chunk requires the MIDI file type, number of tracks, and division (ticks per quarter note).
Your finished subVI should behave like this one:
Download LabVIEW Source
Watch the screencast video to learn how to use the Concatenate Strings node to join substrings together into a single string. You will also learn how use the nodes To Variant and Variant to Flattened String to convert a numerical value into its representation as a sequence of bytes in a string.
Once all of the delta-time/event pairs have been assembled into a string, midi_FinishTrack.vi will attach a track chunk header to the beginning of the string and append an end-of-track meta-event at the end of the string. The resulting string will represent a complete track chunk.
Your finished subVI should behave like this one:
Download LabVIEW Source
midi_ToVLF.vi accepts a 32-bit unsigned integer and produces an output string that is anywhere from one to four bytes in length (recall that VLF = variable length format). You may find this subVI to be one of the more challenging to implement! Review the module Standard MIDI Files to learn about variable-length format.
Your finished subVI should behave like this one:
Download LabVIEW Source
midi_MakeDtEvent.vi creates a delta-time / event pair. The subVI accepts a delta-time in ticks, a MIDI message selector, the channel number, and two data values for the MIDI message. The delta-time is converted into variable-length format, and the (typically) three-byte MIDI message is created. Both of these values are appended to the inbound string to produce the output string. Review the module MIDI Messages to learn more.
Your finished subVI should behave like this one:
Download LabVIEW Source
midi_MakeDtMeta.vi creates a delta-time / meta-event pair. The subVI accepts a delta-time in ticks, a meta-event selector, text string, and tempo value (only certain meta-events require the last two inputs). The delta-time is converted into variable-length format, and the meta-event is created. Both of these values are appended to the inbound string to produce the output string. Review the module Standard MIDI Files to learn about meta-events.
Your finished subVI should behave like this one:
Download LabVIEW Source
At this point you should have enough experience to proceed without assistance!
Congratulations! You now have assembled and tested six subVIs that can form the basis of many other projects. Now use your subVIs to build an application VI (top-level VI) to demonstrate that your subVIs work properly together. Two applications that you can easily build are described next.
The application block diagram pictured below produces a single-track MIDI file containing an ascending chromatic sweep over the entire range of note numbers (0 to 127). Before sounding the note, the Program Number (tone or voice selection) is set to the same value as the note number. Thus, the voice changes for each note, adding additional interest to the sound. The note duration is specified by a control whose unit is milliseconds. As an exercise, you will need to complete the grayed-out area to convert the units of “duration” from milliseconds to ticks.
![]() |
The application block diagram pictured below creates a MIDI file in which the same note is played repeatedly, but the velocity varies from the maximum to the minimum value in unit steps. When you play the MIDI file, you can record the soundcard’s audio output and measure its velocity profile, i.e., the mapping between the note’s velocity value and its waveform amplitude. The Audacity sound editing application works well for this purpose; choose “Wave Out Mix” as the input device to record the soundcard’s output.
![]() |
"Developed by Rose Hulman Prof Ed Doering, this collection is a multimedia educational resource for students and faculty that augments traditional DSP courses and courses that cover music […]"