Technical Documentation For File Formats?

Hey folks!

I’m new around here, but I’m so happy to have found these forums as someone who is in love with my OP-1 and OP-Z!

I’ve been looking to build a little app to easily back up my OP-1 and OP-Z directly to my iPad, but figured it might also be useful to mirror some of the functionality that tools like the OP-1 Drum Utility provide for folks as well.

The only problem is I’m having trouble finding technical documentation as to how these samples are formatted/glued together in a way that the OP-1 can easily understand. I can certainly make a more naive implementation that doesn’t let you set any kind of settings (i.e. pitch, gain, etc) but I’d like to understand more about the inside of the way the OP-1 reads these files.

Does anyone have any technical documentation on the way these .aif files are encoded or setup? Thank you in advance for any info you can point me towards, I tried searching through this forum first, but maybe I didn’t have the terms right to locate what I’m looking for.

all the settings info is in the header of the .aiff file i believe

Thank you! I’ve found more of the documentation and it seems there’s a chunk in the aif file called appl which may include some information that I can dig through hopefully.

Also I think it’s just a bit obscure since the AudioToolbox framework from Apple is a bit under documented so there will be a bunch of trial and error. I’ll hopefully have something useful for the community soon!

2 Likes

I’d love something like this.

So just responding to myself for posterity. I’ve been looking more specifically at the APPL header within each AIFF file and have published an initial rewrite up on a page in Notion (just to keep documentation for myself and others https://www.notion.so/AIFF-APPL-Chunk-Header-Format-51233bdb0e914c979222978a01bc9d3c)

As I work on this app I’ll probably replace the Notion page with an actual wiki on GitHub when I have more of the project working. However, I figured I’d share this as there isn’t a lot of documentation out there for this op-1 specific values.

I mention in a few of the comments about the values that I’m not exactly sure what start/end times actually are and they might be something more akin to data samples rather than time specifically, so I’m going to keep digging there.

1 Like

There is also a thread somewhere on this forum called “Custom Firmware on the OP-1” or something like that. There’s a ton of info in there maybe. And welcome! You’ll find this forum very helpful.

1 Like

nice work man!
start/end times are likely in samples.
edit: na actually seems to be a higher resolution if 44100 is the sample rate

i dunno the math doesn’t totally add up.
96kHz makes more sense mathematically based on the numbers in your example
its close but not exactly 12 seconds.

using the largest number in your example 1153253906
divide by 96000 = 12013.0615208 millisec or 12.013 seconds which is really really close
not even sure if that number is all the way to the end of a 12 sec sample or what.
i mean a drum kit might not be exactly 12 seconds.

96kHz ADC/DAC is mentioned in the specs on the website :man_shrugging:

Ohhh I think you’re on to something though. I also found that op1.fun puts the sample markers in the right place so I’m going to see if I can find out what they are doing to try to bring this all to light and document it for folks as well.

Thanks!

What!!! Hey @brianmichel I was doing the exact same thing this week for the OP-1. I’ve pretty much reverse engineered the Drum patch .aif files.

For a quick rundown, here’s what I’ve learned. First consider a normal .aif file (non OP-1):

00000000: 464f 524d 0008 c4ee 4149 4646 434f 4d4d  FORM....AIFFCOMM
00000010: 0000 0012 0002 0002 3130 0010 400e bb80  ........10..@...
00000020: 0000 0000 0000 5353 4e44 0008 c4c8 0000  ......SSND......

You’ll see the FORM header followed by four bytes. These four bytes are the total size of the file - 8 bytes (the first four plus the four for the size). Then you’ll see the COMM header and finally the SSND header followed by the PCM audio data. To make this OP-1 compatible all you need to is inject a payload right before the SSND tag. What is the payload? Let’s take a look at the OP-1 .aif file.

Here is an OP-1 compatible file:

00000000: 464f 524d 000f 4e6e 4149 4643 4656 4552  FORM..NnAIFCFVER
00000010: 0000 0004 a280 5140 434f 4d4d 0000 0040  ......Q@COMM...@
00000020: 0001 0007 a49c 0010 400e ac44 0000 0000  ........@..D....
00000030: 0000 736f 7774 2953 6967 6e65 6420 696e  ..sowt)Signed in
00000040: 7465 6765 7220 286c 6974 746c 652d 656e  teger (little-en
00000050: 6469 616e 2920 6c69 6e65 6172 2050 434d  dian) linear PCM
00000060: 4150 504c 0000 04c6 6f70 2d31 7b22 6472  APPL....op-1{"dr
00000070: 756d 5f76 6572 7369 6f6e 223a 322c 2264  um_version":2,"d
...
000004f0: 3139 322c 3831 3932 2c38 3139 322c 3831  192,8192,8192,81
00000500: 3932 2c38 3139 322c 3831 3932 2c38 3139  92,8192,8192,819
00000510: 322c 3831 3932 2c38 3139 322c 3831 3932  2,8192,8192,8192
00000520: 2c38 3139 322c 3831 3932 5d7d 0a20 5353  ,8192,8192]}. SS
00000530: 4e44 000f 4940 0000 0000 0000 0000 0000  ND..I@..........
00000540: 0000 0000 f5ff e0ff bcff 90ff 57ff 14ff  ............W...

This one comes directly from the OP-1. I’m not sure what the FVER flag is, but you don’t need it. I’ve uploaded things without it no problem. The thing to notice is the AAPL flag. That denotes OP-1 metadata. After the APPL flag, there are 4 bytes that have the size of the APPL contents until the SSND flag. Then there is the op-1 flag, and then there is the JSON data for the OP-1 meta data.

Typical OP-1 meta data looks like tihs:

{"drum_version":2,"dyna_env":[0,8192,0,8192,0,0,0,0],"end":[97643143,165163892,211907777,282025634,313446583,372916297,413167412,454132733,478541489,492549640,582028126,642634075,642634075,642634075,642634075,642634075,642634075,642634075,642634075,642634075,642634075,642634075,642634075,2032606256],"fx_active":false,"fx_params":[8000,8000,8000,8000,8000,8000,8000,8000],"fx_type":"delay","lfo_active":false,"lfo_params":[16000,16000,16000,16000,0,0,0,0],"lfo_type":"tremolo","name":"boombap1","octave":0,"pitch":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"playmode":[8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192],"reverse":[8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192],"start":[0,97647201,165167950,211911835,282029692,313450641,372920355,413171470,454136790,478545547,492553698,582032184,582032184,582032184,582032184,582032184,582032184,582032184,582032184,582032184,582032184,582032184,582032184,642638133],"type":"drum","volume":[8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192]}

The “start” and “end” are the markers. Each marker is the seconds * 44100 * 4096.

To make an .aif file with metadata all you have to do is inject those bytes, starting with the APPL flag before the SSND flag

One tricky bit is that when you inject the op-1 metadata you have to add filler bytes so that the .aif file has a multiple of four bytes (I do not know why this is. Maybe its not quite true, but when I do it it works). You can see those filler bytes above at 5d7d 0a20 5353, the 0a20 are filler bytes.

I wrote code to do all this in Go. Perhaps that would be much easier to understand than these rambling notes. Send me your github name and I’ll add you to my repo so you can check it out… (It’s private right now until I’m finished with what I’m working on).

I have no idea if this is the same for the op-z (I don’t have one to fiddle with). If someone can send me a op-z .aif file I can check it out.

2 Likes

WHOA! you solved the thing I was trying to figure out, thank you so much!!! Let me know what you think of this little wiki https://www.notion.so/AIFF-APPL-Chunk-Header-Format-51233bdb0e914c979222978a01bc9d3c I’ll move it into GitHub for https://github.com/brianmichel/operator after that project becomes a bit more functional.

Wiki looks good! I would add something in about changing the bytes after FORM (total bytes - 8). When you change the metadata you often have to change the total bytes in the file and it will corrupt the AIF if you don’t (I’ve done that a few times lol).

I just went ahead and made my repo public. Here’s a link to the code for injecting OP-1 metadata: https://github.com/schollz/teoperator/blob/39c9a71566c29e93c5575f1530de3fdd43ed0d32/src/op1/op1.go#L84-L118 (I find it really amusing that you named your repo “operator” and I named mine “teoperator”, great minds!)

The code I have thusfar will take any audio file and split it up into 12 second segments and automatically assign keys to markers determined from the waveform transients. That way I can generate a bunch of drum tracks from one long vocal sample (e.g. poetry readings from the library of congress) with premade assignments. If there is interest I can build a server so its easy for others to use.

1 Like

Really intrigued by all this! I recently got an OP-1 as a graduation gift (how friggin’ sweet is that??) and have been trying to find any technical documentation I can about the OP-1. I’ve also been trying to think up cool web app ideas for the community to hack on in my free time, so let me know if you guys want to collaborate or if anyone has any ideas!

2 Likes

Thanks to the info from @yakczar I was able to get the start and end markers parsed correctly to finish laying out part of the drum utility in the app. Also I decided to give SwiftUI + Catalyst a try so it would make an iPhone, iPad, and macOS app! Still pretty rough, but getting there!


(you can toggle between “relative” sizing of each section, or a fixed width)

4 Likes

@brianmichel That looks SO cool. Reminds me of LCARS from Star Trek, the best UI ever IMO.

One more thing I’ve found is that you should make sure the start/end markers are multiples of 8192 (13 bits). It wasn’t working right until I made that change. Here’s the updated code: https://github.com/schollz/teoperator/blob/a7bba7a57d9bd9c8914dae05083d3f279dd11e59/src/op1/op1.go#L79-L85

1 Like

You’re in for a treat! There is so much to discover! Enjoy. HMU if you have ideas, I love streamlining my workflows on the OP-1. I think a cool thing would be a browser based MIDI CV effects controller…

2 Likes

Made some progress over the long weekend of being able to load existing drum kits (and probably just about any other sound) into the app as well as playing them back. This makes a nice drag-in-from-icloud-drive kind of workflow. Checkout the video! (apologies for the crappy sound, was recording directly on the iPad)

4 Likes