Start a new topic

Orba hacking knowledge base

This thread is intended to gather the feedback of Orba tinkerers.

27 people like this idea

I don't think that would work since those appear to be channel level settings. Do you have the eventData that matches the log (Channel 1)?

...I've tried adding stuff like:

    <SynthPatch mode="Lead" quantizationMode="1" loopBarEndTolerance="2" quantStartSnapTicks="2"

                quantizationStartSnapTicks="2" ccA="2" thinnerMode="2" allowRecordingSilenceEnd="2" the presets, though that XML doesn't actually appear anywhere, but it doesn't seem to have any effect. I suspect that running the App may turn quantisation off again, though I think it survives power-off.

I can't find the loop info parameters anywhere except in 0x8000000.bin, where they look like this:

   Looper Configuration:

   loopBarEndTolerance: %u

   beatLengthTicks: %u

   notesPerBar: %u

   quantMode: %u

   quantStartSnapTicks: %u

   quantBarEndSnapTicks: %u

   allowRecordingSilenceStart: %u

   allowRecordingSilenceEnd: %u

   thinnerMode: %u

   cc_error_limit: %lu

   pbend_error_limit: %lu

   ccA: %u

   ccB: %u

   ccC: %u

   thickenerMode: %u

   thickenerEmitPrd: %u

   thickenerMaxDt: %u

   noteStartWindow: %u

The Orba.exe app starts with:

quantStartSnapTiMZ the first data, and that's about it.

...not as far as I can tell; I tried playing a song at 120 and 60 and the data looked the same. (Attached.)


If you change the Tempo does it change the beatLengthTicks value? 

>"I'm thinking this 1/16 note quantization. To make it more obvious, I think we could change the 120 to 240 or even 480. This would snap all notes to 1/8 notes or even 1/4 notes. This would be great to make sure this is configurable and to make absolutely sure that quantize is working."

Here's another quick example; at this tempo the quantise only works on very small errors, much more than this and beats start moving. Yes, will be interesting to try and change the snap settings... 


@BJG145 Hoping you have Excel.. Here is a spreadsheet (with formulas which completely validates the 8-byte note structure)

(11.7 KB)

1 person likes this

Thanks! Did you post the DPC header info in CSV? I think its going to be important to map those. I think its 18 bytes and will somehow line up with the serial log header info. What I'm most interested in at the moment is beatLengthTicks and quantStartSnapTicks. In the DPC example, these are 480 and 120. So I'm thinking this 1/16 note quantization. To make it more obvious, I think we could change the 120 to 240 or even 480. This would snap all notes to 1/8 notes or even 1/4 notes. This would be great to make sure this is configurable and to make absolutely sure that quantize is working. I'm also wondering if the developers left a secret way in the Orba app to flip the quantize setting. :) 

...great work @Subskybox, and thanks for the explanations. It'll take me a little while to understand it all. In the meantime, I've been taking another look at the "q" quantisation mode in the console, and it does actually seem to work. It doesn't change the data in the Orba; just the playback. "q" turns all four channels on and off at once, but I'll do some experimenting with the quantisation mode tags in the XML files and see if they do anything. I also need to experiment to see what might turn quantisation off again when it's been switched on in the console; eg power off, new song, etc. 

Here's a demo of a quantised loop. It was recorded with some notes slightly out; eg the third note from the end is fractionally late. It plays twice. Then there's a gap, and the quantised version plays twice.

(1.37 MB)


1 person likes this

Okay I've got it figured out :) Let's use DPC as the example. BeatLengthTicks = 480, so 480 ticks per quarter note. The correct 8 byte sequence is:

  1. Command (16 is PlayNote but there are likely other for CC values etc..)
  2. Relative Start Tick [LSB] since last (event or note unknown)
  3. Relative Start Tick [MSB]
  4. MIDI Note #
  5. Velocity ON (1-127 follows 7 bit MIDI standard)
  6. Velocity OFF (1-127 follows 7 bit MIDI standard)
  7. Duration in Ticks [LSB]
  8. Duration in Ticks [MSB]

Let's look at the first 2 DPC notes. 

MemIdx = 0 - MIDI Note at tick 7, channel 1, note 62, duration 501, von 120, voff 90
  1. 16 (Play Note Command)
  2. 7 [LSB]
  3. 0 [MSB]
  4. 62 (MIDI Note)
  5. 120 Von
  6. 90 Voff
  7. -11 [LSB]
  8. 1 [MSB]

To calculate the value they are using two's compliment for negative numbers. I'll skip the calculation for the first start Tick (7&0) at position 2&3 as it trivial to derive 7. Now let's look at the first duration -11 & 1. This can be calculated as (11^255)+1+1<8 = 501. You can use the Windows Calculator to work this out quite easily in Programmer Mode:


Let's look at the next:
MemIdx = 8 - MIDI Note at tick 1888, channel 1, note 64, duration 495, von 127, voff 92
  1. 16
  2. 89
  3. 7
  4. 64
  5. 127
  6. 92
  7. -17
  8. 1
Let's start with the start Ticks. This can be calculated as 89+7<8 + 7(lastStartTick) = 1888


And finally the second duration (17^255)+1+1<8 = 495


With this knowledge it would be fairly straightforward to write a script to quantize a song file but doing it on the device would not be possible.

The fact that they used relative tick values was a really poor choice in my opinion. I feel this way because quantizing one note would have an impact on all the notes that follow since they are all relative to the previous. I suspect they will convert this to absolute for the Orba 2.

2 people like this

I'm just trying to absorb some of the MIDI programming info. 

When experimenting with duration and then timing, I got the idea that one of the values represented a count of an eighth of the bar, ie a quaver, and the other value was a +ve/-ve offset from that.

With duration, this seemed to work, and I was able to get fixed length notes by counting quavers and zeroing offsets.

With timing, the "fine" control got more complicated. At one point the loop lost a note or two and started playing at double speed. I also found that even if notes were playing back accurately on the metronome, there was still an offset. With one loop I also found that the first note got moved to the end again. I'm wondering if maybe this happens if the first "trigger" note that starts the recording is played fractionlly behind the beat.

I was also thinking that there was something different about the timing values for the first note in the list, and possibly the last. The data for these two might represent something different. Perhaps there are tick values at the start and ending but the middle values are relative, or something. 

The tempo change was strange; the loop was still counting the same length round the dial but it was mostly squashed into the first half, followed by silence. Perhaps there might be some kind of calculation going on between the timing values for the start and finish to work out what the time signature is.

The next thing I was going to try was playing a loop in time, then moving the offsets for notes in the middle of the loop around slightly to see the result.

Here's the serial log for the above test I called "DPC". 

* * * * *

I've found that the "coarse" setting for timing (3rd value in each note block) moves the note and subsequent notes around by a quaver when you increment/decrement it, so note timing is relative rather than measured on a clock that runs for the duration of the loop. 

The "fine" setting will take a bit more experimenting; I think it's basically an offset like with duration, but there's a complication around the overall timing of the loop.

(1.29 KB)

I copied a sample from above:

MemIdx = 0 - MIDI Note at tick 12, channel 1, note 62, duration 496, von 99, voff 85

MemIdx = 8 - MIDI Note at tick 944, channel 1, note 62, duration 464, von 127, voff 87

MemIdx = 16 - MIDI Note at tick 1908, channel 1, note 62, duration 960, von 121, voff 87

MemIdx = 24 - MIDI Note at tick 3845, channel 1, note 62, duration 996, von 117, voff 80

I can see that 16 is a proprietary message for NoteOn. I suspect the next two values define the start tick since two bytes would be required to define a number greater than 255.

Let's look at the tick number 1908. This requires two bytes which I highlighted below:


There is a concept in midi referred to as MSB/LSB (Most Significant Byte / Least Significant Byte). The MSB in the case in binary is a 7 which I saw in often following PlayNote (16). and the LSB is 116. So I suspect that the pattern is

PlayNote, StartTickMSB, StartTickLSB,NoteNumber, VelocityOn, VelocityOff, DurationMSB, DurationLSB

Hopefully I'll get more time this week, but I feel this is very likely what's happening without doing the actual proof.

1 person likes this

What I really need is the serial log that matches the csv. I'm going to attempt to predict the log output.

Login or Signup to post a comment