# Generating MIDI files

**URL:** <https://forum.juce.com/t/generating-midi-files/1558>\
**Category:** General JUCE discussion\
**Created:** [March 15, 2007, 8:44pm UTC](https://forum.juce.com/t/generating-midi-files/1558 "2007-03-15T20:44:51Z")\
**Posts on this page:** 8\
**Page:** 2

<div class="post-metadata">

**Author:** ![imekon](https://avatars.discourse-cdn.com/v4/letter/i/3da27b/32.png) [@imekon](https://forum.juce.com/u/imekon)\
**Post date:** [February 15, 2014, 9:56pm UTC](https://forum.juce.com/t/generating-midi-files/1558/21 "2014-02-15T21:56:57Z")

</div>

True - it might cause some other apps to try to read the garbage. I've switched to deleteFile.

---

<div class="post-metadata">

**Author:** ![imekon](https://avatars.discourse-cdn.com/v4/letter/i/3da27b/32.png) [@imekon](https://forum.juce.com/u/imekon)\
**Post date:** [February 16, 2014, 4:01pm UTC](https://forum.juce.com/t/generating-midi-files/1558/22 "2014-02-16T16:01:21Z")

</div>

As I wanted to output title and other text into MIDI files with JUCE, I created a helper class:

```
class MidiMessageHelper
{
public:
    static MidiMessage trackTitle(const String &title);
    static MidiMessage trackCopyright(const String &copyright);
private:
    static MidiMessage trackText(int type, const String &text);
};

MidiMessage MidiMessageHelper::trackText(int type, const String &text)
{
    char titleTrack[128];
    sprintf_s(titleTrack, 128, "%c%c%c%s", 0xff, type, text.length(), text.toRawUTF8());
    MidiMessage result(titleTrack, strlen(titleTrack));
    return result;
}

MidiMessage MidiMessageHelper::trackTitle(const String &title)
{
    return trackText(3, title);
}

MidiMessage MidiMessageHelper::trackCopyright(const String &copyright)
{
    return trackText(2, copyright);
}
```

Seems to be working well in my application so far (with unit tests).

---

<div class="post-metadata">

**Author:** ![oxxyyd](https://avatars.discourse-cdn.com/v4/letter/o/e47c2d/32.png) [@oxxyyd](https://forum.juce.com/u/oxxyyd)\
**Post date:** [February 16, 2014, 6:07pm UTC](https://forum.juce.com/t/generating-midi-files/1558/23 "2014-02-16T18:07:58Z")

</div>

Like the copyright notice meta event (type = 2) or the track name meta event (type = 3) .

---

<div class="post-metadata">

**Author:** ![imekon](https://avatars.discourse-cdn.com/v4/letter/i/3da27b/32.png) [@imekon](https://forum.juce.com/u/imekon)\
**Post date:** [February 17, 2014, 10:31am UTC](https://forum.juce.com/t/generating-midi-files/1558/24 "2014-02-17T10:31:18Z")

</div>

The functions I used are the only ones I could see in the documentation - there are others?

---

<div class="post-metadata">

**Author:** ![imekon](https://avatars.discourse-cdn.com/v4/letter/i/3da27b/32.png) [@imekon](https://forum.juce.com/u/imekon)\
**Post date:** [February 17, 2014, 10:31am UTC](https://forum.juce.com/t/generating-midi-files/1558/25 "2014-02-17T10:31:18Z")

</div>

The functions I used are the only ones I could see in the documentation - there are others?

---

<div class="post-metadata">

**Author:** ![oxxyyd](https://avatars.discourse-cdn.com/v4/letter/o/e47c2d/32.png) [@oxxyyd](https://forum.juce.com/u/oxxyyd)\
**Post date:** [February 18, 2014, 8:25am UTC](https://forum.juce.com/t/generating-midi-files/1558/26 "2014-02-18T08:25:00Z")

</div>

Juce might benefit from some more midimessage constructors. I misread your message on my smartphone.

---

<div class="post-metadata">

**Author:** ![oxxyyd](https://avatars.discourse-cdn.com/v4/letter/o/e47c2d/32.png) [@oxxyyd](https://forum.juce.com/u/oxxyyd)\
**Post date:** [February 18, 2014, 9:24pm UTC](https://forum.juce.com/t/generating-midi-files/1558/27 "2014-02-18T21:24:29Z")

</div>

your code will only work for smaller texts. The string length in midi text meta events is a variable length quantity and should be calculated as such:

```
MidiMessage MyMidiMessage::textMetaEvent(int type, String text)
{
    jassert(type > 0 && type < 16)

    //const int textLength = text.length();
    const int textLength = CharPointer_UTF8::getBytesRequiredFor (text.getCharPointer());

    HeapBlock<uint8> m (textLength + 2 + 4); //allocate for text, 0xff, type and max 4 length bytes

    int n = 6;

    m[--n] = textLength & 0x7f;
    
    for (int lengthLeft = textLength; lengthLeft >>= 7;)
        m[--n] = lengthLeft & 0x7f | 0x80;

    m[--n] = (uint8)type;
    m[--n] = 0xff;

    memcpy(m + 6, text.getCharPointer(), textLength);

    return MidiMessage (m + n, 6 - n + textLength, 0);
}
```

While this is not entirely trivial, maybe Jules might even consider adding it to the MidiMessage class :)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [May 12, 2017, 8:57pm UTC](https://forum.juce.com/t/generating-midi-files/1558/28 "2017-05-12T20:57:13Z")

</div>



[Previous page](https://forum.juce.com/t/generating-midi-files/1558.md?page=1)
