![]() | Getting started |
This topic contains the following sections:
This guide will give a gentle introduction to how to start creating music with MIDI Gremlin.
![]() |
---|
This guide goes somewhat in dept, not only explaining how, but also the what and why. If you just want to get started creating music, you can read [8c0c97d0-c968-4c15-9fe9-e8f3a443c50a] for a crash course. |
The first step to playing music is creating an Orchestra and an Instrument.
All Orchestras require an IMidiOut interface. This interface is in most cases a WinmmOut that plays MIDI commands over Windows Multi Media dll, but it is possible to substitute it with something else.
const int midiDeviceId = 0; //Most computers will only have this one. const int beatsPerSecond = 60; //Tempo of the music. 60 beats per second 1 one beat equals 1 second. IMidiOut output = new WinmmOut(midiDeviceId, beatsPerSecond); Orchestra orchestra = new Orchestra(output); Instrument piano = orchestra.AddInstrument(InstrumentType.BrightAcousticPiano);
Once you have created an Instrument we can test it by playing a single sound. If you are using WinmmOut and not another implementation of IMidiOut that sound should come out of your speakers. If it dosen't, check your audio setup.
//Play a single sound piano.Play(Tone.C, 1); orchestra.WaitForFinished();
Normally you won't be sending Tones directly to an Instrument but it is the quickest way to get started.
Now that we have a connection to your speakers, we can start creating some simple MusicObjects. MusicObjects are composite objects building a tree structure of music.
The first MusicObject we are going to use is the Note class. A Note is one of the fundemental MusicObject representing a single keypress.
![]() |
---|
This is not quite true. A Note contains a Keystroke and a Pause. For more details, see Note documentation. For our pourposes, however, this is a quite reasonable abstraction. |
MusicObject longF = new Note(Tone.F, 1); MusicObject shortF = new Note(Tone.F, 0.5); MusicObject longA = new Note(Tone.A, 1); MusicObject shortA = new Note(Tone.A, 0.5); MusicObject longG = new Note(Tone.G, 1); MusicObject shortG = new Note(Tone.G, 0.5); Console.WriteLine("Press enter to play a single sound"); Console.ReadLine(); //We can play any of those on an instrument if we wish piano.Play(shortG); orchestra.WaitForFinished();
Once we have some pieces of music, we are going to use them to create larger pieces. These can be made as large as you wish.
![]() |
---|
Make sure not add a MusicObject to any of its own children. MidiGremlin does not detect this and parsing is going to cause a StackoverflowException if you try to play or transform it. |
//Create 2 smaller MusicObjects made out of the base pieces MusicObject sequence1 = new SequentialMusicList(longF, shortA, longG, shortA); MusicObject sequence2 = new SequentialMusicList(shortA, shortA, shortA, longA, shortF); //Now create a bigger MusicObject made of those 2 smaller ones and one new SequentialMusicList bigMusicObject = new SequentialMusicList(sequence1, sequence1, sequence2, new Note(Tone.D, 2)); //We can play this too //We can play any of those on an instrument if we wish Console.WriteLine("Press enter to play a longer sequence of sound"); Console.ReadLine(); piano.Play(bigMusicObject); orchestra.WaitForFinished();
Finally we are going to look at transformations. Transformations allow you to copy a MusicObject while applying a function to all children of a specified type.
//Make the 1st object a little lower on the scale, using a transform int[] offsets = { 0, -3, -3, -2 }; bigMusicObject[1] = bigMusicObject[1].Select<Note>((x,y) => x.OffsetBy(Scale.MajorScale, offsets[y])); //Play our final piece. Console.WriteLine("Press enter to play \"Drømte mig en drøm i nat\", "); Console.ReadLine(); piano.Play(bigMusicObject); orchestra.WaitForFinished(); //You have just heard https://en.wikipedia.org/wiki/Dr%C3%B8mde_mik_en_dr%C3%B8m_i_nat
If a piano is not your cup of tea, playing on an other instrument is as simple as creating it and telling it what to play.
![]() |
---|
Due to the limitations of the MIDI standard, playing more than 15 normal instruments and 1 drum at the same time is going to result in an error. |
//Create a flute Instrument flute = orchestra.AddInstrument(InstrumentType.Flute); Console.WriteLine("Press enter to play \"Drømte mig en drøm i nat\" on a flute"); Console.ReadLine(); flute.Play(bigMusicObject); orchestra.WaitForFinished();
using System; using MidiGremlin; namespace GettingStarted { class Program { static void Main(string[] args) { #region Orchestra const int midiDeviceId = 0; //Most computers will only have this one. const int beatsPerSecond = 60; //Tempo of the music. 60 beats per second 1 one beat equals 1 second. IMidiOut output = new WinmmOut(midiDeviceId, beatsPerSecond); Orchestra orchestra = new Orchestra(output); Instrument piano = orchestra.AddInstrument(InstrumentType.BrightAcousticPiano); #endregion #region SingleSound //Play a single sound piano.Play(Tone.C, 1); orchestra.WaitForFinished(); #endregion #region MusicObjects MusicObject longF = new Note(Tone.F, 1); MusicObject shortF = new Note(Tone.F, 0.5); MusicObject longA = new Note(Tone.A, 1); MusicObject shortA = new Note(Tone.A, 0.5); MusicObject longG = new Note(Tone.G, 1); MusicObject shortG = new Note(Tone.G, 0.5); Console.WriteLine("Press enter to play a single sound"); Console.ReadLine(); //We can play any of those on an instrument if we wish piano.Play(shortG); orchestra.WaitForFinished(); #endregion #region LargeMusicObject //Create 2 smaller MusicObjects made out of the base pieces MusicObject sequence1 = new SequentialMusicList(longF, shortA, longG, shortA); MusicObject sequence2 = new SequentialMusicList(shortA, shortA, shortA, longA, shortF); //Now create a bigger MusicObject made of those 2 smaller ones and one new SequentialMusicList bigMusicObject = new SequentialMusicList(sequence1, sequence1, sequence2, new Note(Tone.D, 2)); //We can play this too //We can play any of those on an instrument if we wish Console.WriteLine("Press enter to play a longer sequence of sound"); Console.ReadLine(); piano.Play(bigMusicObject); orchestra.WaitForFinished(); #endregion #region Transformation //Make the 1st object a little lower on the scale, using a transform int[] offsets = { 0, -3, -3, -2 }; bigMusicObject[1] = bigMusicObject[1].Select<Note>((x,y) => x.OffsetBy(Scale.MajorScale, offsets[y])); //Play our final piece. Console.WriteLine("Press enter to play \"Drømte mig en drøm i nat\", "); Console.ReadLine(); piano.Play(bigMusicObject); orchestra.WaitForFinished(); //You have just heard https://en.wikipedia.org/wiki/Dr%C3%B8mde_mik_en_dr%C3%B8m_i_nat #endregion #region OtherInstrument //Create a flute Instrument flute = orchestra.AddInstrument(InstrumentType.Flute); Console.WriteLine("Press enter to play \"Drømte mig en drøm i nat\" on a flute"); Console.ReadLine(); flute.Play(bigMusicObject); orchestra.WaitForFinished(); #endregion #region TransformToChords //Using Select<>() it's also possible to change the type of a MusicObject. ChordVariety minor = ChordVariety.Minor; MusicObject asChords = bigMusicObject.Select<Note>(n => minor.WithBaseTone(n.Keystroke.Tone, n.Pause.Duration)); Console.WriteLine("Press enter to play \"Drømte mig en drøm i nat\" as minor."); Console.ReadLine(); piano.Play(asChords); orchestra.WaitForFinished(); #endregion } } }