OP-1滚筒贴片的逆向工程

2020-05-19 15:10:40

我对青少年工程OP-1鼓补丁进行了逆向工程,这样我就可以自动制作我自己的自定义补丁。

尽管如此,我还是设法对青少年工程公司(Teenage Engineering)制造的OP-1合成器的一种音频文件格式进行了反向工程。

最终结果是一个很好的小网站,允许您为OP-1采样器构建补丁:https://op1.schollz.com.。我在这里谈论的所有代码都是开源的,也可以在Github上获得。

OP-1是一个很棒的合成器,可以做很多事情。其中一个很棒的东西就是取样器,也就是滚筒取样器引擎。此采样器允许您录制最多12秒的声音,然后可以在任意两点之间拼接。然后可以将这些拼接分配给合成器的24个键中的一个,以便轻松回放。通常取样器是用来打鼓的,但我喜欢用它来做口语或诗歌。

事实上,我喜欢用它来写很多口语和诗歌。我的上一张专辑有超过30分钟的NASA录音。我目前的专辑是一小时的诗歌朗诵样本。最终需要使用OP-1滚筒取样器引擎拼接和切割数百个12秒的样品。

对于每个12秒的样本,我需要通过线路输入将其记录到OP-1中。记录每一次至少需要大约一分钟的时间来设置电平并找到正确的位置。录制完后,我开始拼接,这又要花一两分钟的时间。对于几个12秒的样本来说,这是一个简单的工作流程。但是,对于数百个12秒的样本,我查看的是工作时间和工作时间。

我相信在这种情况下,我为这项任务编写一些软件的时间比这项任务的工作时间要少。..这意味着:是时候进行一些自动化了!

我对file.mp3中的样本所做的第一件事是将其转换为正确的OP-1文件类型,并截断为12秒(OP-1的Drum采样器引擎的最大值)。

我知道OP-1有一种特殊的文件类型-.aif文件,这在采样器中很流行。我所要做的就是提取12秒的音频并将其转换为.aif文件。这可以通过一个ffmpeg命令轻松完成:

接下来,为了自动生成按键分配,我想要拼接声音。拼接的一种方式是使用瞬变,或者在静默结束时使用。原来ffmpeg也是这样做的!我编写了一些运行ffmpeg的代码,用于打印出检测到静音的地方。对于-22db处至少0.2秒的静音,对于file.mp3,用于检测静默的ffmpeg命令是:

然后,我可以使用像Audiowaveform这样的花哨工具来制作波形的图像,并使用imagemagick对其进行颜色编码,这样我就可以将拼接可视化。因此,在静音中拆分后,给定的音频片段可能如下所示:

太好了,现在我有了OP-1补丁patch.aif,这是上传到Drum engine采样器的当前长度和格式。下一步是设置patch.aif文件的元数据,使其包含OP-1鼓采样器引擎可以用来将键分配给每个接头的信息。

向我的新patch.aif注入元数据需要一些侦察/研究,因为我不知道.aif文件是如何工作的。有一个1988年的文件规范,但非常诚实地说,我使用神奇的Unix工具xxd和一些二流的猜测找到了我需要知道的一切。

xxd工具允许您可视化任何文件的十六进制转储。所以我使用它来查看一个普通的.aif文件,并将其与OP-1.aif文件(我从合成器下载的)进行比较。

$xxd file.aif|head-n 300000000:464f 524d 0008 c4ee 4144646 434f 4d4d表单.AIFFCOMM00000010:0000 0012 0002 0002 3130 0010 400e [email protected]:0000 0000 0000 5353 4e44 0008 c4c8 0000.snd.。

显然,标题中有标题(Form、AIFF、COMM、SSND)。我猜SSND就是PCM数据。Form看起来很特别,因为它后面紧跟着4个字节。对于该特定文件,我将这些字节转换为十进制(0008c4ee),它们相当于文件大小减去8字节,所以我假设它只是一个文件大小。

$xxd op1.aif00000000:464f 524d 000f 4e6e 4149 4643 4656 4552表单..NnAIFCFVER00000010:0000 0004 a280 5140 434f 4d4d 0000 0040.q@comm.@00000020:0001 0007 a49c 0010 400e ac44 0000 [email protected]:0000 736f 7774 2953 6967 6e65 6420 696e.。dr00000070:756d 5f76 6572 7369 6f6e 223a 322c 2264 um_version";:2,";d.000004f0:3139 322c 3831 3932 2c38 3139 322c 3831 192,8192,8192,8100000500:3932 2c38 3139 322c 3831 3932 2c38 3139 92,8192,8192,81900000510:322c。SS00000530:4e44 000f 4940 0000 0000 0000 [email protected]:0000 0000 f5ff e0ff bcff 90ff 57ff 14ff.W.。

您将看到它有一个AIFC(压缩格式),而不是AIFF,但这并不重要,因为我的ffmpeg转换后的文件没有压缩。最大的区别在于APPL标记后面有一些JSON数据。在APPL之后有四个字节,它们再次与SSND标记之前的大小完全对应。这看起来很简单,我所要做的就是插入APPL,然后是4字节大小,然后是OP-1,然后是我的JSON数据-就在SSND标记之前。

然而,当我这样做的时候,我损坏了我的OP-1声音几次。所以别那么做!事实证明,在SSND标记之前和JSON右括号之后有几个字节非常重要。在打开几个OP-1文件时,我注意到有时是0a20,有时只是0a。我推测它可能需要保持块的一致性,可能是4的倍数(因为否则您将只有1个字节或0,而不是2或1)。

这很管用!因此,在注入OP-1元数据之后,您必须插入0A或20,直到文件的总大小是4的倍数。(也许这是胡说八道,有人请让我知道)。

最后,现在我知道了如何将OP-1数据注入到.aif文件中,我只需计算出OP-1数据将是什么。

我使用xxd检查.aif文件时发现,OP-1元数据本身如下所示:

{";鼓_版本";:2,";类型";:";鼓";,";名称";:";用户";,";八度";:0,";音高";:[6144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],";start";:[0,35186754,73270908,193926863,262863847,282963028,327734734,374604417,422374972,456892160,477153660,548131809,570661720,597144106,696446963,726788489,830413096,918041142,955370511,1001935845,1053265249,1053265249,1053265249,1053265249],";end";:[35182696,73266850,193922805,262859789,282958970,327730676,374600359,422370914,456888102,477149602,548127751,570657662,597140048,696442905,726784431,830409038,918037084,955366453,1001931787,1053261191,1153253906,1153253906,1153253906,1153253906],";播放模式";:[8192,16384,8192,8192,8192,8192,16384,8000,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192],";反转";:[8192,16384,8192,8192,8192,16384,8192,8192,8192,8192,16384,8192,8192,8192,8192,8192,16384,8192,8192,8192,8192,8192,8192],";音量";:[9195,8192,5190,8192,8192,4969,8192,8192,16384,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,";dyna_env";:[0,8192,0,8192,0,0,0],";FX_ACTIVE";:FALSE,";FX_TYPE";:";DELAY";,";FX_PARAMS";:[8000,8000,8000,8000,8000,8000],";LFO_ACTIVE";:FALSE,";LFO_TYPE";:";颤音";,";LFO_PARAMS&#。:[16000,16000,16000,16000,0,0,0,0]}。

看起来很简单!有一个开始和结束,每个数组中有24个点,我猜这将对应于24个键!我注意到这些数字绝对很大,比如2053253906,太大了,相当于最大秒数(~12)或毫秒。所以我把最大的数字除以一些随机数,比如44100(典型的采样率)和4096(最大12位),最大的数字是~11.8,这非常接近您可以在OP-1上设置的最远端点(12秒)!很好,所以我所需要做的就是从ffmpeg静音分析中获取我的起点/终点,然后将秒数乘以44100和4096.

结果证明我错了。事实证明,当我这样做的时候,它没有把我的OP-1砌成砖块,但我认为我已经设置的标记完全偏离了。经过进一步思考,我发现OP-1JSON数据中有很多8192个。我猜这是它能识别的最小数字,所以我更改了所有标记,使它们对应于最接近的倍数8192(最多13位)。

因此,以下是如何获取任何声音并制作带有自动键分配的OP-1鼓补丁的方法:

使用ffmpeg将声音截断为~12秒并将声音转换为.aif,使用ffmpeg查找静音,使用静音开始/结束点生成OP-1\f25 JSON-1(注意仅使用13位精度),在SSND标记之前将JSON注入.aif文件,并更新填充符和格式字节以使其有效。

就这样!。它短到足以告诉别人,并不是说我在开始之前就知道这些。现在我可以编写一个程序来同时对几十个样本自动完成这项工作。

我从这个项目中得到的主要收获是ffmpeg和xxd非常强大,我真正需要的就是获得最终结果。最好的部分是我可以在几个小时的音频上运行代码,这将自动生成完美的12秒剪辑,可以用样例键绑定加载到OP-1上。

如果你想使用我的最终结果,它现在可以在https://op1.schollz.com上找到,所有的源代码都可以在Github上找到。如果你想听我的音乐,去看看我的乐队夏令营吧。

Go中的←🏊工作人员池