2012-12-31

Dissecting the Multitimbral Patch Format of the Waldorf Blofeld Using midisnoop

Lately, I've been interested in writing a software editor for my Waldorf Blofeld. In particular, I wanted to be able to edit multi-timbral patches on my Blofeld. Unfortunately, while Waldorf has released a system exclusive message specification that contains the format for mono-timbral patches, they have not released information on the format for multi-timbral patches.

A couple days ago, I released a program called midisnoop that allows a user to send custom messages to a MIDI port and to monitor the messages that come out of another MIDI port. I wrote this program with the intention of probing my MIDI-enabled hardware, and the first hardware I decided to probe was my Blofeld.

I started by doing a little research. The Blofeld system exclusive specification contain data regarding the format of system exclusive messages that can be used to communicate with the Blofeld. Here's the basic format:

HexDescription
f0Start of sysex message
3eWaldorf Music manufacturer ID
13Blofeld ID
(DD)Device ID
(MM)Message Type ID
(HH)Location High Byte
(LL)Location Low Byte
(Data Bytes)Data Bytes pertaining to the type of message (not always necessary)
(CS)Checksum byte (not always necessary)
f7End of sysex message

The document also defines some message types:

HexDescription
00Sound Data Request
10Sound Data Dump
20Sound Parameter Change
04Global Data Request
14Global Data Dump

The sound data types above are for monotimbral patches.  The document also goes into how you can access sound parameters from each part of the currently loaded multitimbral patch, but doesn't go into how to access the actual parameters of a multitimbral patch.

There's more data in the document too, on the format of monotimbral patches, the exact format of the above message types, the format of global data, and how a Blofeld responds to device inquiry messages.  I'm not going into that here.

This data is helpful, but it didn't solve my problem.  I started looking for documentation on other multitimbral synths made by Waldorf, and came across this fantastic document on Waldorf synthesizers.  This document contained information on the MIDI implementations of the Waldorf Q, Q+, and microQ.  In particular, all three of the synths used the same general message format as the Waldorf Blofeld, and used the same message type byte to request multitimbral patch data, which is:

HexDescription
f0Start of sysex message
3eWaldorf Music manufacturer ID
13Blofeld ID
(DD)Device ID
01Multitimbral Patch Request ID
(BB)Location High Byte
(LL)Location Low Byte
f7End of sysex message

Cool!  I fired up my Blofeld, and started midisnoop.  I connected midisnoop to my Blofeld, making sure that system exclusive events won't be ignored:


... composed my MIDI message:


... and sent it off:


The Blofeld sent me back something!  Let's disect the data.  Here's the data contained in the system exclusive message:

3e 13 00 11 00 00 49 6e 69 74 20 4d 75 6c 74 69 20 20 20 20 20 20 00 7f
37 01 00 02 04 0b 0c 00 00 00 00 00 00 00 00 00 64 40 00 40 40 02 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 03 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 04 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 05 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 06 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 07 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 08 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 09 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0a 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0b 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0c 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0d 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0e 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0f 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 10 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 11 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 7b

This might seem overwhelming at first, but there are patterns here.  See the row of '7f' at the end there?  And there's another row of '00' next to it.  There's a method to this madness.

Let's start by eliminating the bytes that belong to the message and not the multitimbral patch itself.  Using the basic Blofeld message format I referenced above, I can see that the first 6 bytes belong to the MIDI message:

HexDescription
3eWaldorf Music manufacturer ID
13Blofeld ID
(DD)Device ID
11Multitimbral Patch Dump ID
(HH)Location High Byte
(LL)Location Low Byte

... and the last byte also belongs to the MIDI message:

HexDescription
CSChecksum byte

So, let's eliminate those bytes and see what we have left:

49 6e 69 74 20 4d 75 6c 74 69 20 20 20 20 20 20 00 7f
37 01 00 02 04 0b 0c 00 00 00 00 00 00 00 00 00 64 40 00 40 40 02 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 03 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 04 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 05 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 06 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 07 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 08 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 09 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0a 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0b 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0c 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0d 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0e 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0f 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 10 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 11 00 7f
01 7f 07 3f 01 3f 00 00 00 00 00 00 00 00

Now, let's look in the Blofeld manual.  There's a section on multis, and their parameters.  A multi has the following parameters:

  • Name
  • Tempo
  • 16 parts

Each of the 16 parts has the following parameters:

  • Sound Bank (A ... H)
  • Sound Number (0 ... 127)
  • Mixer Volume (0 ... 127)
  • Pan (L64 - R63)
  • Transpose (-48 - +48)
  • Detune (-64 - +63)
  • Channel (Global, Omni, 1 - 16)
  • Low Key (0 ... 127)
  • High Key (0 ... 127)
  • Low Velocity (1 ... 127)
  • High Velocity (1 ... 127)
  • Status (play/mute)
  • MIDI (ignore/receive)
  • USB (ignore/receive)
  • Local (ignore/receive)
  • Pitch Bend (ignore/receive)
  • Mod Wheel (ignore/receive)
  • Pressure (ignore/receive)
  • Sustain (ignore/receive)
  • Edits (ignore/receive)
  • Prg Change (ignore/receive)

Let's start by finding the name.  Names of Blofeld patches are 16 letters long.  We'll change the name of the first multi using the Blofeld to "ABCDEFGHIJKLMNOP", save the multi, fetch the data again using midisnoop, and look for a series of 16 ascending hex bytes:


Here's the next mass of hex bytes, sans message data:

41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 00 7f 37 01 00 02 04 0b
0c 00 00 00 00 00 00 00 00 00 64 7f 00 70 7f 02 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 03 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 04 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 05 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 06 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 07 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 08 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 09 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0a 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0b 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0c 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0d 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0e 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 0f 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 10 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 00 00 64 40 00 40 40 11 00 7f 01 7f 07 3f 01 3f
00 00 00 00 00 00 00 00 32

Right at the beginning, there are 16 hex bytes in ascending order.  We now know where the name is stored!

We can do this with the rest of the parameters, changing them one at a time to figure out the Blofeld's multitimbral patch format.  I'm not going to go into detail about how to find every parameter in this post.  Suffice to say that I meticulously went through the parameters, and used midisnoop to check the Blofeld's data for each parameter.

Here are the results:

Multi Format

BytesDescription
0-15Name
16?
17Multi Volume
18Tempo
19-24?
25-31(Reserved?)
32-55Part 1
56-79Part 2
80-103Part 3
104-127Part 4
128-151Part 5
152-175Part 6
176-199Part 7
200-223Part 8
224-247Part 9
248-271Part 10
272-295Part 11
296-319Part 12
320-343Part 13
344-367Part 14
368-391Part 15
392-415Part 16

Multi Part Format

BytesDescription
0Sound Bank
1Sound Number
2Mixer Volume
3Pan
4(Reserved?)
5Transpose
6Detune
7Channel - Global (0), Omni (1), 1 - 16 (2-17)
8Low Key
9High Key
10Low Velocity
11High Velocity
12Bitfield: XS???LUM
  • S - Status: play/mute
  • ?
  • ?
  • ?
  • L - Local ignore/receive
  • U - USB ignore/receive
  • M - MIDI ignore/receive
13Bitfield: X?RESpMP
  • ?
  • R - Prg Change ignore/receive
  • E - Edits ignore/receive
  • S - Sustain ignore/receive
  • p - Pressure ignore/receive
  • M - Mod Wheel ignore/receive
  • P - Pitch Bend ignore/receive
14 - 15?
16 - 23(Reserved?)

As you can see, there are some bytes that I'm still not sure about.  I suspect that bytes 14 and 15 in the part above are the send equivalents of bytes 12 and 13 respectively, and that they only pertain to the Blofeld Keyboard (I own a Blofeld Desktop).

2012-12-30

Announcing midisnoop-0.1.0!

I'm happy to announce the first release of midisnoop!



midisnoop is a simple MIDI monitor and prober. You can use it to monitor a MIDI device and/or software, and to send MIDI messages to a MIDI port to see how the device/software responds. midisnoop supports both ALSA and JACK MIDI ports using the RtMidi library.

`midisnoop` is available at:

    http://midisnoop.googlecode.com/

Please report bugs using the issue tracker:

    http://code.google.com/p/midisnoop/issues/list

If you like `midisnoop` and have ideas that can make it better and/or want to keep up with its progress, join the users group:

    http://groups.google.com/group/midisnoop-users

If you're a developer and want to contribute to `midisnoop`, join the development group:

    http://groups.google.com/group/midisnoop-development

2012-12-21

Announcing synthclone-0.3.0!

I'm happy to announce the release of synthclone-0.3.0!

synthclone is a tool that allows you to create sample-based instruments. You can create sample-based instruments by sending MIDI messages to your MIDI-capable gear or software that instructs an instrument to emit sounds for a series of notes, velocities, controls, and aftertouch values, or by recording your own samples. After the sampling is done, you can apply effects to your samples, and finally save this data as a sample-based instrument that can be loaded by sampler software.

Features:
  • Supports user-configurable per-zone sample time, release time, MIDI note, MIDI velocity, MIDI aftertouch, MIDI channel pressure, MIDI control changes, etc. via a table interface.
  • Audition samples and change zone parameters until you're happy with the data you're acquiring from your MIDI device.
  • Save and restore sessions.
  • Distributed with plugins that support the JACK Audio Connection Kit (with JACK Session support), PortAudio and PortMidi, trimming of samples, reversing samples, LV2 effects, the creation of HydrogenSFZ, and Renoise instruments, automated zone generation, and loading samples from your local filesystem!
  • Can create multiple targets in one session (i.e. a Renoise patch and an SFZ patch) from the same set of samples.
  • A well-documented plugin API is available for developers to write their own plugins to extend synthclone.
Important Changes Since 0.2.0:
  • Lots of bug fixes.
  • The new LV2 plugin allows you to use LV2 effects within synthclone
  • The new Renoise plugin allows you to save your instruments as Renoise instruments
  • The new Reverser plugin allows you to reverse the samples you load into synthclone
  • The new Sample Loader plugin allows you to load samples into synthclone from your local filesystem
  • Internal architecture changes for future expansion of the plugin API to handle main view manipulation
Future Development:
  • Consider capturing release of samples.
  • Figure out a good packaging scheme for Mac OSX.
  • Support the Non-Session Manager protocol.
  • Consider different ways to support the detection and/or creation of loops.
  • Get someone to design an icon that isn't ugly.
  • Extend the LV2 plugin to support more features so that it can load more LV2 plugins.
The new version of `synthclone` is available at:

    http://synthclone.googlecode.com/

Please report bugs using the issue tracker:

    http://code.google.com/p/synthclone/issues/list

If you like `synthclone` and have ideas that can make it better and/or want to keep up with its progress, join the users group:

    http://groups.google.com/group/synthclone-users

If you're a developer and want to write plugins for `synthclone` or contribute to the application itself, join the development group:

    http://groups.google.com/group/synthclone-development

2012-04-07

Announcing synthclone-0.2.0! Now in beta!

I'm happy to announce the first beta release of `synthclone`!

`synthclone` is a Qt-based application that can "clone" your MIDI-capable instruments. It does this by sending out MIDI data that instructs an instrument to emit sounds for a series of notes, velocities, controls, and aftertouch values. It then saves this data as a sample-based instrument that can be loaded by sampler software.

Features:

  • Supports user-configurable per-zone sample time, release time, MIDI note, MIDI velocity, MIDI aftertouch, MIDI channel pressure, MIDI control changes, etc. via a table interface.
  • Audition samples and change zone parameters until you're happy with the data you're acquiring from your MIDI device/software.
  • Save and restore sessions.
  • Distributed with plugins that support the JACK Audio Connection Kit (with JACK Session support), PortAudio and PortMidi, trimming of samples, the creation of patches for Hydrogen and SFZ, and automated zone generation.
  • Can create multiple targets in one session (i.e. a Hydrogen patch and an SFZ patch) from the same set of samples.
  • A well-documented plugin API is available for developers to write their own plugins to extend synthclone.

Important Changes Since 0.1.0:

  • Lots of bug fixes.
  • Added a "portable" semaphore implementation to the plugin API.
  • Added the new PortMedia plugin, which supports sampling via PortAudio and PortMidi.
  • Get `synthclone` to compile on Mac OSX.
  • Change build system to use traditional `./configure`, `make`, `make install` scheme.
  • Add new 'debian' target for building Debian packages (`./configure --prefix=/usr`, `make debian`).

Future Development:

  • Figure out a good packaging scheme for Mac OSX.
  • Support the Non-Session Manager protocol.
  • Write a plugin that creates Renoise instruments.
  • Write a plugin that loads LADSPA effects.
  • Write a plugin that loads LV2 effects.
  • Write a plugin that loads samples from the filesystem (expanding on the plugin created in this tutorial)
  • Consider different ways to support the detection and/or creation of loops.

2012-03-11

synthclone-0.1.10 is available for download!  This release includes sampling support via PortAudio and PortMidi, which brings synthclone one step closer to supporting non-UNIX platforms.

If you're interested in assisting me in porting synthclone to other platforms, please join the synthclone-development group and let me know.