Start a new topic

Orba hacking knowledge base

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

28 people like this idea

I just tried deleting a bunch of the standard Lead presets, then running the App and quitting it again to let it rebuild them.

The synth patch definition for "1981" ends with:

<Compatibility audioEngineMajor="1" audioEngineMinor="4" samplePlayback="0"/>


...but most (all?) the others seem to be missing those lines...?

Maybe the opening <SynthPatch> only needs a closing pair if it contains an additional entry, like this one, but since Artiphon didn't implement sample playback it doesn't do anything anyway.

Tilt Lead has that extra entry too, so that explains it.

<Compatibility audioEngineMajor="1" audioEngineMinor="0" samplePlayback="0"/>


I expect I imagined any change it made and the difference is elsewhere.

I've always been aware of the "you have to rename it" thing, but I've only just realised this is where it comes from. (?) The App automatically "repairs" any of the standard presets. If you edit "1981", then open it in the App and quit it, you'll find it back how it started. But if you work with differently named copies that it doesn't know about, it leaves them alone and the edits remain. 

(...and I take it back about the dodgy XML, the App devs clearly understood XML syntax better than I do, I'll give them that...)

It's the Vibrato Modifier/Seeker pair, corresponding to the gestureUUID beginning 38ca5c83, that introduces the split pad weirdness when combined with the (Tilt) pitchbend pair.

(I don't think the value of these gestureUUIDs is particularly relevant, but it's a useful handle for referring to the pairs; I usually have the "Ian repo" utility list open as a reference.)

I guess Pitchbend and Vibrato tread on each other because they're both trying to change pitch. Without the other pair, both work as expected. 

I hoped vibrato range might respond to the same value in the seekerData string that worked for pitchbend range (no. 23), which it does. By changing it from the standard value of 31 to 39 in Grapefruit, as in the attached preset, you get a vibrato range of three semitones across a pad. However, there's a catch when you begin to increase the range...zipper noise, stepped modulation, which kicks in fast. 

With slow, careful finger movements, you can hear a fairly gradual change, but with brisk movements with this pitch range it moves in a series of jumps; it's probably hitting the limits of the sensor's ability to interpret the data. 


The two-pitch effect of the "weird patch" is probably connected with this; I think it's extreme zipper noise that jumps straight from the smallest value to the largest. 

I'm still wondering how vibrato and pitchbend clash to produce this strange combined effect. Perhaps the effect of the two lots of seekerData is somehow cumulative.

@BJG145 On closing </SynthPatch>. These do not need closing tags. Look closely and notice how the opening tag ends with "/>". There is an XHTML standard for non-container tags so if there is no content in-between opening and closing tags, then the opening tag can end with this special ending. When a patch introduces content (i.e.<Compatibility audioEngineMajor="1" audioEngineMinor="0" samplePlayback="0"/>) then there must be a matching closing </SynthPatch> tag.

From the internet:

  • A few tags are called non-container tags, because they don't contain any content - they stand alone. Examples are images and line breaks. XHTML is more strict than HTML, and requires that all open tags must be closed, even if they're not container tags. Therefore, non-container tags end in />. For example, the tag for a line break is <br />. HTML does not have this same requirement, but it's a good habit to get into in case you ever need to code in XHTML.

I'm wondering how Tilt can be assigned to Pitch in some cases or to other synth params from Orba Synth? I noticed that loading Tilt Lead in OrbaSynth does not pitch bend.

>"How does the SeekerData bind a gesture with a control? I'm thinking index 1 because its unique across all seekerData"

Yep - we have remap. Changing index 1 for a tilt-bend-only preset from 35 to 41 (Shake CC) gives you "Shake to bend" (attached). It reponds to pitch scaling. 

(They're not quite unique; Tap/Press and Move/ShakeCC share this index. I guess it's because the action is the same.)  

(...although, looking at the table I posted, the "Move" and "Shake CC" columns are identical. I'll double-check that in case I made a mistake...)   

...yep, that was an error. The Move index is 40. Here's the corrected table with a new Move column.


>"I'm wondering how Tilt can be assigned to Pitch in some cases or to other synth params from Orba Synth? I noticed that loading Tilt Lead in OrbaSynth does not pitch bend"

Could it be that the whole Modifier/Seeker thing is all about changing pitch...? Does it do anything else...? Most effects work through parameters in the synth patch, but pitch-based effects are handled differently.

...I think I see what you mean though; I don't know how you'd combine tilt-pitchbend with another tilt effect.

Here's a patch with some curious behaviour. All it does is play a "Bump" note, but Pad 1 changes the pitch of the note by an amount that responds to scaling.

IIRC it's basically the tilt-pitchbend seekerData edited for the "Tap" gesture index, matched with a "Tap" Modifier entry. The Modifier/Seeker list also includes the standard Bump entry but nothing else.

I had another go at getting the PC to talk to the Orba directly, without the App. I still haven't succeeded, but I thought I’d post up a few more scraps of information FWIW.


Three processors

The last time I tried this, I gave up because I couldn’t figure out what IC I was trying to talk to, which was mainly why I broke it open.

We now know that it’s based on:

ESP-SOLO-1 which seems to be main processor, and maybe runs the synth engine?

ARMSTM32F730. I think of this as the secondary processor. Maybe it does some of the UI handling, talking to LEDs and things.

CY8C4045AZI on the back of the sensor board, apparently dedicated to processing the input from the capacitive touch sensor.


DFU Mode

To recap, “DFU mode” stands for Device Firmware Update, and it’s how you get your Orba back on its feet when OrbaModifierDataFiddler has landed a punch. The Orba looks like it’s in a coma. You can make sure it’s off by holding down Vol- then power. You can put it in DFU mode by holding down Vol+ then power.

Artiphon have some notes on this here.


If you run the App with the Orba in DFU mode, it offers to revive it. Sometimes it fails. At this point most users would give up and put it on eBay.

There’s a more drastic option beyond this, which you can sometimes only access by getting to the Settings page in the App before the Orba is connected. Then you can boot the Orba into DFU mode, and drag the firmware file across as per the instuctions. If this doesn’t work, nothing will.

At this point the process is presented as a log (attached). Basically the App runs various commands with various parameters to “flash” the Orba, downloading various files to it.


Windows Device Manager

On my Windows PC, I get two different entries in Device manager depending on whether the Orba is connected normally or in DFU mode. When it’s connected normally, I see: “USB Serial Device (COM13)” under “Ports”. (Also “Artiphon Orba MIDI” and “Artiphon Orba Speaker” in “Sound, video and game controllers".) When it’s connected in DFU mode, I see: “STM32 Bootloader” under “Universal Serial Bus Devices” instead, and none of the others.

(I’ve installed a bunch of different drivers on my PC in the course of trying to communicate with this thing, and I don’t know if that’s what you’d see normally. I can try and identify them if needed.)

My current theory is that the “STM32 Bootloader” entry is the STM32 processor and the COM13 entry is the ESP32. But it’s difficult to get to talk to the ESP32. The STM seems slightly more accessible.


The Log

I’ve been studying the flash log that appears in the App and trying to carry out the steps individually. Some of them work, and some don’t. I think some of the things that Artiphon’s flash procedure do happen off camera, and some of the files involved are difficult to pin down. This is usually stuff that is automatically executed by the Orba App when you use the Settings page to apply the firmware update file to an Orba in DFU mode.


Installing the App installs a folder called: C:\Users\<username>\AppData\Roaming\Artiphon\Orba\UpdateUtilities which includes “dfu-util”.


The first command in the log is uses this to run:

dfu-util.exe -l

This lists any attached devices that are in a DFU state. You can run that at the command prompt on a Windows PC and it works just like in the log, reporting some info about the Orba in its DFU state.

We then see the following set of commands:

dfu-util.exe -d 0483:df11 -a 1 -s 0x1fff0000:44:force -U option_bytes.bin
dfu-util.exe -d 0483:df11 -a 1 -s 0x1fff0000:will-reset:force -D option_bytes.bin
dfu-util.exe -d 0483:df11 -a 0 -s 0x20010000:force -D 0x20010000.bin

I’ve edited out the paths to the DFU-UTIL utility and these files. Some of them are quite elusive. What happens is that that the App creates a temporary folder under C:\Users\<username>\AppData\Local\Temp and puts various things like “0x20010000.bin” there, but by the time it’s finished they’ve all been cleared out again. 

In order to grab a copy, I had to wait for the path to flash up in the log (it changes each time; you need to use the mouse to click and hold the readout near the top), and once they appeared, I grabbed a copy of the folder before it got wiped.

One of the files that briefly appears is “0x8000000.bin”, which is slightly interesting because when you edit it in Notepad++ you can find various references to things that were never finished or released, like quantization. Eg:


Toggling looper quantize mode

Using %lu of %u bytes of looper memory available (%u %%)

Looper Configuration:

loopBarEndTolerance: %u

beatLengthTicks: %u

notesPerBar: %u

quantMode: %u

quantStartSnapTicks: %u

quantBarEndSnapTicks: %u

allowRecordingSilenceStart: %u

allowRecordingSilenceEnd: %u

thinnerMode: %u

cc_error_limit: %lu



(During the reset procedure, a whole bunch of files like this get sent to a bunch of different areas of memory, in different ICs probably. It would be impossible to understand the original ideas for quantisation, or get anything working from these scraps of compiled code.)

Yhis carries on for a while, flashing various files here and there in DFU mode, all of which can be reproduced from commands on the PC.

Lights flash, the Orba resets a couple of times; eventually we get to this bit:

Executing: orba_capsense_bootloader.exe \\.\COM12  21_X0_CY8C_Touch_A0_2988ebe.cyacd

These utilities and files can all be found in the UpdateUtilities folder or the copy stolen from Temp files. The syntax for addressing the COM port puzzled me, but this seems to be the standard way of referring to COM12 in some of these flashing utilities. On my PC, the entry in Device Manager is actually COM13, and to get this working from a Windows command prompt I had to substitute “\\.\COM13”. But it always still works when I let the program do it automatically. Maybe it automatically changes the port behind the scenes or something; dunno.

Perhaps this “Capsense bootloader” is about flashing the chip that drives the capacitive touch sensor. 





At first I thought the fine traces were the active part; then I realised that they were just wavy grooves slicing each of the eight sensor pads in half. I imagine these are just copper or something. Bringing a finger near it generates a signal, and this is then analysed to deduce velocity, position and pressure; very clever. I think these are calculated from changes in the “coverage”; basically how your finger squashes out against the plastic when you tap, move and press.

 After that the flashing routine gets down to business.

Executing: artiphon_esp32_programmer.exe \\.\COM12

This seems to be the process of flashing the ESP32 chip at the heart of the Orba.

Running esptool v2.8-dev

This looks like MicroPython stuff; a version of Python designed to run on microcontrollers.

Espressif, the company behind the ESP32, are all over Micropython.

I think that all we get to see in these files is the compiled “Micropython Bytecode”.

I think I’d read somewhere something about how if you want to talk the ESP32 it has to be in a different mode. I was interested in this log entry:

Exiting BLE programming mode

I got the idea that I didn’t want it to automatically exit BLE programming mode like it usually does; I wanted to keep it there. The only way I could think of to do this was to pull the USB cable out shortly before this log event. This result in the Orba spinning its white LED wheels, on in a circle, off in a circle, repeat. It still didn’t’ seem receptive to any attempts to communicate with it via programs like Putty though.


Looking at this again I realise that “BLE Programming mode” is the Bluetooth side and probably has nothing to do with what state the ESP32 is in.

…so, it was quite interesting, but I give up on the firmware exploration at that point. Programming simple microcontrollers like Teensy is trivial by comparison; the Orba is far more difficult. I was hoping to open a Micropython REPL and try doing some sums on it, but, not this time.

>"@BJG145 Are Radiate & Bump really both Index 9?"

...hmm, I'll check...

Login or Signup to post a comment