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.