Tenori-On : Project Introduction and Goals

Tenori-On : Project Introduction and Goals

The Yamaha Tenori-on, designed in collaboration between the performance artist Toshio Iwai and Yamaha, is a wonderful piece of hardware.

However, Yamaha seem to have given up supporting the hardware version in preference to the (iOS only ๐Ÿ˜ž ) TNR-i and TNR-e. For the hardware (TNR-w, TNR-o), the v2.10 firmware was released back in 2011 and nothing has happened since.

The software (firmware) running on it has some issues. It isn’t well optimised (I mainly blame the Toshiba TLCS-900 compiler for that) which is an issue when under load. Also, to use the device fully as part of a live setup, requires some extensions/modifications to play nice, if it is going to be used as a midi controller. Fortunately, it is possible to safely update the “application” software, without touching the boot code that actually loads/saves the application software, so it is possible to perform test updates without brick the device (it is always possible to go back to the stock application software).

NB : Updating the boot software may brick your TNR! Don’t do it!

This project is therefore an attempt to patch the software (starting with v2.1 as a base) to improve/modify the functionality. A major rewrite is not really possible : although there is lots of information about the CPU, quite a lot of the action occurs in the SWL-01 chip, on which I can find no information, so the “API” to the SWL-01 in the code has to remain. As a result this is really just patching the code.

This page acts to track the goals, provide some context, and try to say what I’m doing.

The mods are divided into:

  • Minor : Where a small change could have a big effect
  • Major : Where significant rewrites are needed


Title Class Status
Quiet Mode Minor Complete : Midi quiet
Block change Minor Not started
Code optimisation Minor Ongoing
Assignable Midi channels Major Complete : Per layer midi channel
Per-layer scales Major Complete : Per layer scales
Wider range Major Not started
Arpeggiator Major Not started
Controller output Major Not started
Sequencer Major Not started
Velocity control Major Not started
Sound length control Major Not started

Minor : Quiet mode

Problem : Sysex messages are sent whenever keys are pressed/

In normal mode, pressing a key emits sysex codes. This is unnecessary traffic (and buffer handling in the TNR), and in the worst case, seems to confuse other bits of kit.

Solution : Include a menu setting for not sending SysEx codes when in normal mode, but leave remote mode alone, since that is how one TNR controls another.

Status : Completed in vA009. See Midi quiet

Minor : Block change in normal mode

Problem : TNR only responds to block change requests in remote mode.

It would be good to be able to change the block playing from a different midi controller, while in normal mode. In my case, to allow a foot controller to change the block number, so that swaps between verses and chorus can be done with the feet rather than with the hands. This is of course possible in remote mode, by sending sysex messages (providing that you have a foot controller that can send arbitrary sysex messages, which the Behringer FCB1010 can’t but the Roland FC-300 can). Unforunately, in remote mode, no note on/note off messages are produced by the TNR, defeating the point of its use as a controller.

Solution_1 : When midi messages are parsed from the incoming buffer, there is a check to see whether the TNR is in remote mode or not. This has to be suppressed, at least for some message types, so that response in normal mode is possible.

Solution_2 : More convenient would be to change the “change block” command from a sysex to a MIDI CC code, or MIDI system message. I have been considering using F3 “Song Select”; I can’t find any examples of other kit using this.

Status : Open

Minor : Code optimisation

Problem : TNR code is not well optimised

As far as I can tell from the assembler, the code produced by the TLCS-900 compiler is very poorly optimised. This can range from the trivial (there are several occasions where unnecessary jumps and stack pushes are done, probably coming from variable type casting) to the complex (e.g. searching an instrument array every time a note is played). The tenori-on is not a high power machine, so the more that can be done to optimise the code, the better.

Solution : Remove redundant code. Optimise where possible.

Status : Ongoing

Major : Assignable Midi channels

Problem : Layers do not have assignable midi channels

Layer 1 is Midi channel 1, Layer 2 is Midi channel 2, etc. If both layer 1 & 2 were set to the same midi channel, very interesting effects could be generated.

Solution : In fact, in the code, there is an array interpreted as midi-channel-per-layer. However I haven’t yet sorted out how to provide an easy user interface, nor how to save/load the data from a layer or song. Layers can certainly only output on one channel (adding output on multiple channels is too difficult). An approach where the tenori-on main grid can be used to do the map - e.g. the Y axis is the layer, and the X-axis is the channel (like the volume sliders) would be good.

Status : Completed in vA008. See Per layer midi channel

Major : Assignable scales

Problem : Layers do not have assignable scales

All layers work on the same scale (Dorian, Ionian, Chromatic, etc.). This is limiting

Solution : Per layer scales are implemented in A006. In addition, a few extra scales have been added (Harmonic Minor, Melodic Minor, Bebop Dominant, 6-note Blues, 9-note Blues, Whole Tone). Using “Master scale” works like “Master loop point” - at the moment it is set (via OK), all scales of all layers will be overwritten to this one.

Status : Completed in vA006. See Per layer scales

Major : Wider Playable range

Problem : If using a chromatic scale, the range is limited to just over an octave. This is quite limiting.

Solution : In score mode, at least, one could imaging using the rotary dial to scroll up and down, so that the enterable range is larger. (e.g. +1/-1 scale extent). Since this is lots more notes in the scale, this would require the scale definitions to be extended to cover more than 16 notes.

Status : Open

Major : Arpeggiator

Problem : I want an arpeggiator.

In particular, to allow singificant rythmic infill without “using up” so much of a blocks time allocation.

Solution : The approach here is to define a new type of instrument, one that doesn’t produce audible notes, but that does set the scale for a different layer. Here the midi-mapping would indicate which layers scale was intended, rather than actually producing any MIDI messages. This would allow one layer to contain chords, with a very slow loop speed, and another layer to contain an arpeggio pattern. Assignable scales is a precursor to this mod.

Status : Open

Major : Controller output

Problem : Only note on/note off messages can be produced

Solution : One way is to be able to “tag” any layer as being a controller layer, rather than a note layer. Different instruments would correspond to production of different controllers (volume, pan, filters, etc.). Instead of “note on/off” events, midi CC messages would be produced. If block change is a controller number, and some midi messages are reflected internally (e.g. volume), then this would also be a way to do a sequencer (i.e. the TNR can issue its own block change messages).

Status : Open

Major : Sequencer

Problem : The TNR can not chain blocks together

Solution 1 : The “easiest” way to do this might be to have a new layer mode (Score,Random,Draw,…,Sequencer) that somehow allows block changes to be done. In particular, there isn’t anything in the code that prevents different layers running on different blocks - it’s just that there is no way for the user to differentiate between block-change-all, or block-change-layer. This is a tricky thing to provide a UI for.

Solution 2 : Using a block-change controller instrument.

Status : Open

Major : Direct Velocity control

Problem : The TNR just produces notes with the same velocity

Interestingly, the underlying SWL-01 will produce audio with variable volume/velocity - as can be seen when sending note-on from somewhere else - and the TNR SW stores velocity, it’s just that you can’t input velocity via the UI.

Solution 1 : Possibly use the variable brightness to allow 3-state velocity (full, 23, 13, off) via multiple presses.

Solution 2 : Alternatively, the Controller Output mod above could also have a “velocity” controller, to update the internal velocity, although this might be tricky to coordinate. One layer running the notes in draw mode with another layer running the velocity in bounce mode could produce some nice effects

Solution 3 : Another approach, only really useful in score mode, is to have a “split screen” where the top N (say 12) rows are notes, and the bottom 4 are the velocity.

Status : Open

Major : Variable sound length

Problem : Each layer has a set sound length.

There isn’t a way to have variable sound lengths within a layer. There isn’t any underlying reason why; when a new note comes up, tne TNR pushes it, and a timer count, into a “notes on” buffer, and then simply down-counts throught the buffer to see when to send the note-off. So long as the note length is known at the time the note-on appears, then there could be a way of having variable note lengths. An approach whereby the notes duration is a “bar” on the grid - i.e. play the note until there is no LED lit - is not easy to implement, and only really valid in Score mode.

Solution 1 : Possibly use the variable brightness to allow 3-state note lenths (full, 23, 13, off) via multiple presses.

Solution 2 : Alternatively, the Controller Output mod above could also have a “note length” controller, to update the note length, although this might be tricky to coordinate.

Solution 3 : A similar “split screen” to the Direct Velocity control above.

Status : Open

Pika Blue avatar
About Pika Blue
Pika Blue is overly obsessed with midi controllers, especially unsupported ones with blinky lights .