├── nord ├── convert │ ├── dx7 │ │ ├── __init__.py │ │ └── dxtable.py │ ├── version.py │ ├── logic.py │ ├── __init__.py │ ├── seq.py │ ├── ctrl.py │ ├── inout.py │ ├── env.py │ ├── convert.py │ ├── mixer.py │ ├── lfo.py │ └── filter.py ├── g2 │ ├── temp.pch2 │ ├── __init__.py │ ├── categories.py │ ├── colors.py │ ├── misc.py │ ├── crc.py │ ├── bits.py │ ├── pprint.py │ └── _bits.pyx ├── nm1 │ ├── __init__.py │ └── colors.py ├── __init__.py ├── utils.py ├── types.py ├── module.py └── net.py ├── dx7.pch2 ├── initpatch.pch2 ├── setup.py ├── mkr ├── modck.py ├── shorten.py ├── ckg2demo.py ├── tests ├── testnotevelscale.pch ├── testformantosc.pch ├── testspectralosc.pch ├── testmorph.pch ├── testctrl.pch ├── testsinebank.pch ├── testkeyboardnote.pch ├── testseq.pch ├── testenv.pch ├── testlogic.pch ├── testmixer.pch ├── testfilter.pch ├── testmstslv.pch ├── testlfo.pch ├── testaudio.pch ├── testinout.pch └── testosc.pch ├── gplheader.py ├── .hgtags ├── pch2cat.py ├── lfos.pch ├── mkqr.py ├── prf2cat.py ├── README ├── units.py ├── nm2g2g.ui ├── pch2cmp.py ├── nmcat.py ├── nm2g2g_ui.py ├── nm2g2g.py ├── nm2g2.py └── pch2tog2.py /nord/convert/dx7/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dx7.pch2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msg/g2ools/HEAD/dx7.pch2 -------------------------------------------------------------------------------- /initpatch.pch2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msg/g2ools/HEAD/initpatch.pch2 -------------------------------------------------------------------------------- /nord/g2/temp.pch2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msg/g2ools/HEAD/nord/g2/temp.pch2 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | 2 | from distutils.core import setup 3 | import py2exe 4 | 5 | # run via: python.exe setup.py py2exe -b 1 6 | 7 | setup(console=['nm2g2.py'],zipfile=None) 8 | setup(console=['dx2g2.py'],zipfile=None) 9 | -------------------------------------------------------------------------------- /mkr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -lt 1 ]; then 4 | echo "usage: $0 " 5 | exit 1 6 | fi 7 | 8 | L=g2ools- 9 | V=${L}$1 10 | DEST=/v/www/files 11 | 12 | rm -rf ~/nord/${L}* 13 | hg clone . ..//${V} 14 | echo "version='$1'" >>../${V}/nord/convert/version.py 15 | (cd ..;zip -r ${V}.zip ${V}) 16 | rm ${DEST}/${L}* 17 | cp -v ~/nord/${V}.zip ${DEST} 18 | ls ${DEST} 19 | 20 | -------------------------------------------------------------------------------- /modck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from nord import printf 4 | from nord.g2.modules import * 5 | 6 | for m in modules: 7 | paramnms = [ p.name for p in m.params ] 8 | outputnms = [ o.name for o in m.outputs ] 9 | inputnms = [ i.name for i in m.inputs ] 10 | for name in paramnms: 11 | if name in outputnms: 12 | printf('%s: %s p and o\n', m.shortnm, name) 13 | if name in inputnms: 14 | printf('%s: %s p and i\n', m.shortnm, name) 15 | for name in inputnms: 16 | if name in outputnms: 17 | printf('%s: %s i and o\n', m.shortnm, name) 18 | -------------------------------------------------------------------------------- /shorten.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import sys 4 | from nord.g2.file import Pch2File, Prf2File 5 | 6 | prog = sys.argv.pop(0) 7 | while len(sys.argv): 8 | filename = sys.argv.pop(0) 9 | print(filename) 10 | if filename[-4:].lower() == 'prf2': 11 | prf2 = Prf2File(filename) 12 | for p in range(4): 13 | patch = prf2.performance.patches[p] 14 | patch.voice.shorten_cables() 15 | patch.fx.shorten_cables() 16 | prf2.write(filename) 17 | else: 18 | pch2 = Pch2File(filename) 19 | pch2.patch.voice.shorten_cables() 20 | pch2.patch.fx.shorten_cables() 21 | pch2.write(filename) 22 | -------------------------------------------------------------------------------- /ckg2demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import sys 4 | from nord.g2.file import Pch2File 5 | from nord import printf 6 | 7 | unavailable = [ 8 | '4-Out', 9 | '2-In', 10 | '4-In', 11 | 'Operator', 12 | 'DXRouter', 13 | 'Vocoder', 14 | 'CtrlSend', 15 | 'PCSend', 16 | 'NoteSend', 17 | 'CtrlRcv', 18 | 'NoteRcv', 19 | 'NoteZone', 20 | 'Automate', 21 | ] 22 | 23 | for arg in sys.argv[1:]: 24 | try: 25 | pch2 = Pch2File(arg) 26 | p = pch2.patch 27 | demo = True 28 | for module in p.voice.modules + p.fx.modules: 29 | if module.type.shortnm in unavailable: 30 | demo = False 31 | if demo: 32 | printf('%s\n', arg) 33 | except: 34 | printf('"%s" not a pch2.\n\n', arg) 35 | 36 | -------------------------------------------------------------------------------- /tests/testnotevelscale.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 115 0 0 8 | [/ModuleDump] 9 | [ModuleDump] 10 | 0 11 | [/ModuleDump] 12 | [CurrentNoteDump] 13 | 64 0 0 64 0 0 14 | [/CurrentNoteDump] 15 | [CableDump] 16 | 1 17 | [/CableDump] 18 | [CableDump] 19 | 0 20 | [/CableDump] 21 | [ParameterDump] 22 | 1 23 | 1 115 4 0 0 64 48 24 | [/ParameterDump] 25 | [ParameterDump] 26 | 0 27 | [/ParameterDump] 28 | [CustomDump] 29 | 1 30 | [/CustomDump] 31 | [CustomDump] 32 | 0 33 | [/CustomDump] 34 | [NameDump] 35 | 1 36 | 1 NoteVelScal1 37 | [/NameDump] 38 | [NameDump] 39 | 0 40 | [/NameDump] 41 | -------------------------------------------------------------------------------- /gplheader.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of g2ools. 3 | # 4 | # g2ools is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # g2ools is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with Foobar; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | # 18 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | a119ab71ba8bc77686fbf7ae0abc2f6b935304d1 g2ools-0.1 2 | a7926d64b94e65b4caeca11d3fd3314bf16f2a19 g2ools-0.2 3 | 20607f5f1361bbaa79e3829aabd1dd675e6b4277 g2ools-0.3 4 | d0fc5068c29cf23f28bbfa2489d04a762adac825 g2ools-0.4 5 | ae7613d383544707810d1debfa0d704f50fb5157 g2ools-0.5 6 | 57a0b11046e567f0f9bc3beb7dca2f2a38d1ffba g2ools-0.6 7 | 8a667943c8f1de77ea5a49055c48790f3a588293 g2ools-0.10 8 | 69e56025f2b957a9df7395b12b72d75ebc78e06f g2ools-0.11 9 | 59c7706ef4c066579a5cb21fa5bf6dae4b9765bd g2ools-0.90 10 | d7a13b7f3f6140127033b820e85e49ff1aed060d g2ools-0.91 11 | b681a059bf0c9ea8110326913141f1345c0fc0a9 before-remove-postmodule 12 | 767a82eaae142dc414f7ddca62ae102175a94a1b gtools-1.2 13 | 3eeb09f72f96c00fdffbba0ab038b6a4bbbfabca g2ools-1.3 14 | 18825f9c93611d448d57ffa0621527085fadb49f g2ools-1.4 15 | 65d8b1182f4ffa2e46896bfb6bd45d10ca15ae55 g2ools-1.5 16 | -------------------------------------------------------------------------------- /nord/g2/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2006,2007 Matt Gerassimoff 3 | # 4 | # This file is part of g2ools. 5 | # 6 | # g2ools is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # g2ools is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Foobar; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | -------------------------------------------------------------------------------- /nord/nm1/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2006,2007 Matt Gerassimoff 3 | # 4 | # This file is part of g2ools. 5 | # 6 | # g2ools is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # g2ools is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Foobar; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | -------------------------------------------------------------------------------- /nord/convert/version.py: -------------------------------------------------------------------------------- 1 | # 2 | # version.py - version stamp 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | version = 'dev' 23 | -------------------------------------------------------------------------------- /tests/testformantosc.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 96 0 4 8 | 2 1 0 1 9 | 3 11 0 9 10 | 4 4 0 13 11 | [/ModuleDump] 12 | [ModuleDump] 13 | 0 14 | [/ModuleDump] 15 | [CurrentNoteDump] 16 | 64 0 0 64 0 0 17 | [/CurrentNoteDump] 18 | [CableDump] 19 | 1 20 | 1 1 0 0 2 0 1 21 | 1 1 1 0 2 2 1 22 | 1 1 2 0 2 3 1 23 | 0 4 0 0 1 0 1 24 | 3 3 0 0 1 1 1 25 | [/CableDump] 26 | [CableDump] 27 | 0 28 | [/CableDump] 29 | [ParameterDump] 30 | 1 31 | 1 96 7 64 64 1 0 45 61 74 32 | 3 11 4 64 64 0 0 33 | 4 4 3 115 0 0 34 | [/ParameterDump] 35 | [ParameterDump] 36 | 0 37 | [/ParameterDump] 38 | [CustomDump] 39 | 1 40 | 1 1 0 41 | 3 1 0 42 | [/CustomDump] 43 | [CustomDump] 44 | 0 45 | [/CustomDump] 46 | [NameDump] 47 | 1 48 | 1 FormantOsc1 49 | 2 Keyboard1 50 | 3 OscSlvC1 51 | 4 2 outputs1 52 | [/NameDump] 53 | [NameDump] 54 | 0 55 | [/NameDump] 56 | -------------------------------------------------------------------------------- /tests/testspectralosc.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 2 1 0 0 8 | 1 107 0 5 9 | 3 2 0 2 10 | 4 4 0 11 11 | 5 11 0 14 12 | 6 107 1 5 13 | [/ModuleDump] 14 | [ModuleDump] 15 | 0 16 | [/ModuleDump] 17 | [CurrentNoteDump] 18 | 64 0 0 64 0 0 19 | [/CurrentNoteDump] 20 | [CableDump] 21 | 1 22 | 0 1 0 0 3 0 1 23 | 1 1 1 0 2 0 1 24 | 1 1 2 0 2 2 1 25 | 3 5 0 0 1 1 1 26 | 0 4 1 0 1 0 1 27 | 0 4 0 0 4 1 0 28 | 1 1 3 0 2 3 1 29 | [/CableDump] 30 | [CableDump] 31 | 0 32 | [/CableDump] 33 | [ParameterDump] 34 | 1 35 | 1 107 10 64 64 64 1 0 0 0 65 1 0 36 | 4 4 3 115 0 0 37 | 5 11 4 64 64 0 0 38 | 6 107 10 64 64 64 1 0 0 0 0 1 0 39 | [/ParameterDump] 40 | [ParameterDump] 41 | 0 42 | [/ParameterDump] 43 | [CustomDump] 44 | 1 45 | 1 1 0 46 | 5 1 0 47 | 6 1 0 48 | [/CustomDump] 49 | [CustomDump] 50 | 0 51 | [/CustomDump] 52 | [NameDump] 53 | 1 54 | 1 SpectralOsc1 55 | 2 Keyboard1 56 | 3 AudioIn1 57 | 4 2 outputs1 58 | 5 OscSlvC1 59 | 6 SpectralOsc2 60 | [/NameDump] 61 | [NameDump] 62 | 0 63 | [/NameDump] 64 | -------------------------------------------------------------------------------- /nord/nm1/colors.py: -------------------------------------------------------------------------------- 1 | # 2 | # colors.py - NM1 colors 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | from nord import Mapping 24 | 25 | nm1cablecolors = Mapping( 26 | red = 0, 27 | blue = 1, 28 | yellow = 2, 29 | grey = 3, 30 | green = 4, 31 | purple = 5, 32 | white = 6 33 | ) 34 | 35 | nm1conncolors = Mapping( 36 | audio = 0, 37 | control = 1, 38 | logic = 2, 39 | slave = 3 40 | ) 41 | 42 | -------------------------------------------------------------------------------- /pch2cat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import sys 23 | from nord.g2.file import Pch2File 24 | from nord.g2.pprint import printpatch 25 | from nord import printf 26 | 27 | prog = sys.argv.pop(0) 28 | try: 29 | while len(sys.argv): 30 | filename = sys.argv.pop(0) 31 | pch2 = Pch2File(filename) 32 | printf('"%s"\n', filename) 33 | printpatch(pch2.patch) 34 | except IOError: 35 | pass 36 | 37 | -------------------------------------------------------------------------------- /nord/g2/categories.py: -------------------------------------------------------------------------------- 1 | # 2 | # categories.py - g2 category definitions 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | from nord import Mapping 24 | 25 | g2categories = Mapping( 26 | no_cat = 0, 27 | acoustic = 1, 28 | sequencer = 2, 29 | bass = 3, 30 | classic = 4, 31 | drum = 5, 32 | fantasy = 6, 33 | fx = 7, 34 | lead = 8, 35 | organ = 9, 36 | pad = 10, 37 | piano = 11, 38 | synth = 12, 39 | audio_in = 13, 40 | user_1 = 14, 41 | user_2 = 15, 42 | ) 43 | 44 | -------------------------------------------------------------------------------- /tests/testmorph.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 97 0 0 8 | 2 19 0 4 9 | 3 23 0 7 10 | 4 8 0 14 11 | 5 4 0 22 12 | [/ModuleDump] 13 | [ModuleDump] 14 | 0 15 | [/ModuleDump] 16 | [CurrentNoteDump] 17 | 64 0 0 64 0 0 18 | [/CurrentNoteDump] 19 | [CableDump] 20 | 1 21 | 0 5 1 0 4 0 1 22 | 0 5 0 0 5 1 0 23 | 0 2 0 0 2 0 1 24 | [/CableDump] 25 | [CableDump] 26 | 0 27 | [/CableDump] 28 | [ParameterDump] 29 | 1 30 | 1 97 5 65 64 1 0 0 31 | 2 19 3 64 127 127 32 | 3 23 9 127 77 127 0 0 0 0 0 0 33 | 4 8 9 64 64 99 0 0 0 127 0 0 34 | 5 4 3 115 0 0 35 | [/ParameterDump] 36 | [ParameterDump] 37 | 0 38 | [/ParameterDump] 39 | [MorphMapDump] 40 | 17 73 0 0 41 | 1 1 0 0 0 1 1 1 0 63 1 2 0 1 -64 1 3 0 2 -127 1 4 6 3 -127 42 | [/MorphMapDump] 43 | [KeyboardAssignment] 44 | 0 0 0 2 45 | [/KeyboardAssignment] 46 | [KnobMapDump] 47 | 2 1 0 20 48 | 2 1 1 1 49 | 2 1 2 2 50 | 2 1 3 3 51 | [/KnobMapDump] 52 | [CustomDump] 53 | 1 54 | 1 1 0 55 | 4 1 0 56 | [/CustomDump] 57 | [CustomDump] 58 | 0 59 | [/CustomDump] 60 | [NameDump] 61 | 1 62 | 1 MasterOsc1 63 | 2 Mixer1 64 | 3 Mod-Env1 65 | 4 OscB1 66 | 5 2 outputs1 67 | [/NameDump] 68 | [NameDump] 69 | 0 70 | [/NameDump] 71 | -------------------------------------------------------------------------------- /tests/testctrl.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 43 0 3 8 | 2 39 0 6 9 | 3 48 0 9 10 | 4 16 0 12 11 | 5 72 0 15 12 | 6 75 0 18 13 | 7 98 0 21 14 | 9 66 1 6 15 | 10 115 1 9 16 | 11 1 0 0 17 | 8 66 1 17 18 | [/ModuleDump] 19 | [ModuleDump] 20 | 0 21 | [/ModuleDump] 22 | [CurrentNoteDump] 23 | 64 0 0 64 0 0 24 | [/CurrentNoteDump] 25 | [CableDump] 26 | 1 27 | 1 2 0 0 1 0 1 28 | 1 9 1 0 1 0 1 29 | 1 3 0 0 2 0 1 30 | 1 4 0 0 3 0 1 31 | 1 5 0 0 4 0 1 32 | 1 6 0 0 5 0 1 33 | 1 7 0 0 6 0 1 34 | 1 10 1 0 9 0 1 35 | 1 9 0 0 10 0 1 36 | 2 3 1 0 11 1 1 37 | 2 4 1 0 3 1 0 38 | 1 8 0 0 7 0 1 39 | 1 10 0 0 11 2 1 40 | [/CableDump] 41 | [CableDump] 42 | 0 43 | [/CableDump] 44 | [ParameterDump] 45 | 1 46 | 1 43 2 64 0 47 | 2 39 1 64 48 | 3 48 1 64 49 | 4 16 1 64 50 | 5 72 1 67 51 | 6 75 2 106 0 52 | 7 98 14 22 0 0 0 0 0 0 0 0 0 0 0 0 0 53 | 8 66 5 0 127 0 127 0 54 | 9 66 5 0 127 0 127 0 55 | 10 115 4 0 24 64 24 56 | [/ParameterDump] 57 | [ParameterDump] 58 | 0 59 | [/ParameterDump] 60 | [CustomDump] 61 | 1 62 | [/CustomDump] 63 | [CustomDump] 64 | 0 65 | [/CustomDump] 66 | [NameDump] 67 | 1 68 | 1 Constant1 69 | 2 Smooth1 70 | 3 PortamentoA1 71 | 4 PortamentoB1 72 | 5 NoteScaler1 73 | 6 NoteQuant1 74 | 7 KeyQuant1 75 | 8 ControlMixer2 76 | 9 ControlMixer1 77 | 10 NoteVelScal1 78 | 11 Keyboard1 79 | [/NameDump] 80 | [NameDump] 81 | 0 82 | [/NameDump] 83 | -------------------------------------------------------------------------------- /lfos.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 24 0 0 8 | 3 26 0 10 9 | 4 80 0 14 10 | 5 27 0 18 11 | 2 25 0 5 12 | 6 24 1 0 13 | 7 24 1 5 14 | 8 24 1 10 15 | 9 24 1 15 16 | 10 24 1 20 17 | 11 24 2 0 18 | 12 24 2 5 19 | 13 24 2 10 20 | 14 24 2 15 21 | 15 24 2 20 22 | [/ModuleDump] 23 | [ModuleDump] 24 | 0 25 | [/ModuleDump] 26 | [CurrentNoteDump] 27 | 64 0 0 64 0 0 28 | [/CurrentNoteDump] 29 | [CableDump] 30 | 1 31 | [/CableDump] 32 | [CableDump] 33 | 0 34 | [/CableDump] 35 | [ParameterDump] 36 | 1 37 | 1 24 8 64 1 3 0 0 0 0 0 38 | 2 25 8 64 1 0 0 0 0 0 64 39 | 3 26 6 64 1 0 0 0 0 40 | 4 80 5 64 64 0 0 0 41 | 5 27 1 64 42 | 6 24 8 64 1 0 0 0 0 64 0 43 | 7 24 8 64 1 1 0 0 0 64 0 44 | 8 24 8 64 1 2 0 0 0 64 0 45 | 9 24 8 64 1 3 0 0 0 64 0 46 | 10 24 8 64 1 4 0 0 0 64 0 47 | 11 24 8 64 1 0 0 0 0 64 0 48 | 12 24 8 64 1 1 0 0 0 0 0 49 | 13 24 8 64 1 2 0 0 0 0 0 50 | 14 24 8 64 1 3 0 0 0 0 0 51 | 15 24 8 64 1 4 0 0 0 0 0 52 | [/ParameterDump] 53 | [ParameterDump] 54 | 0 55 | [/ParameterDump] 56 | [CustomDump] 57 | 1 58 | 4 1 0 59 | 5 1 0 60 | [/CustomDump] 61 | [CustomDump] 62 | 0 63 | [/CustomDump] 64 | [NameDump] 65 | 1 66 | 1 LFOA1 67 | 2 LFOB1 68 | 3 LFOC1 69 | 4 LFOSlvA1 70 | 5 LFOSlvB1 71 | 6 LFOA2 72 | 7 LFOA3 73 | 8 LFOA4 74 | 9 LFOA5 75 | 10 LFOA6 76 | 11 LFOA2 77 | 12 LFOA3 78 | 13 LFOA4 79 | 14 LFOA5 80 | 15 LFOA6 81 | [/NameDump] 82 | [NameDump] 83 | 0 84 | [/NameDump] 85 | -------------------------------------------------------------------------------- /tests/testsinebank.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 2 1 0 2 8 | 3 2 0 0 9 | 1 106 1 0 10 | 4 97 0 4 11 | 5 7 0 7 12 | 6 4 1 10 13 | 7 106 2 0 14 | 8 106 3 0 15 | [/ModuleDump] 16 | [ModuleDump] 17 | 0 18 | [/ModuleDump] 19 | [CurrentNoteDump] 20 | 64 0 0 64 0 0 21 | [/CurrentNoteDump] 22 | [CableDump] 23 | 1 24 | 3 1 0 0 4 0 1 25 | 3 7 0 0 1 0 0 26 | 0 1 3 0 3 0 1 27 | 0 1 7 0 1 3 0 28 | 0 8 3 0 3 0 1 29 | 0 8 5 0 8 3 0 30 | 0 8 7 0 8 5 0 31 | 0 1 4 0 3 1 1 32 | 0 1 6 0 1 4 0 33 | 0 1 1 0 1 6 0 34 | 0 8 4 0 3 1 1 35 | 0 8 6 0 8 4 0 36 | 0 8 8 0 8 6 0 37 | 0 1 2 0 5 0 1 38 | 0 6 0 0 1 0 1 39 | 0 6 1 0 8 0 1 40 | [/CableDump] 41 | [CableDump] 42 | 0 43 | [/CableDump] 44 | [ParameterDump] 45 | 1 46 | 1 106 24 64 64 56 64 64 55 64 64 61 64 64 41 64 64 44 64 64 69 0 1 0 1 1 1 47 | 4 97 5 64 64 1 0 0 48 | 5 7 10 64 64 64 64 0 0 0 0 0 0 49 | 6 4 3 115 0 0 50 | 7 106 24 64 64 100 64 64 100 64 64 100 64 64 100 64 64 100 64 64 100 0 1 1 1 1 1 51 | 8 106 24 64 64 100 64 64 100 64 64 100 64 64 100 64 64 100 64 64 100 0 0 0 0 1 1 52 | [/ParameterDump] 53 | [ParameterDump] 54 | 0 55 | [/ParameterDump] 56 | [CustomDump] 57 | 1 58 | 4 1 0 59 | 5 1 0 60 | [/CustomDump] 61 | [CustomDump] 62 | 0 63 | [/CustomDump] 64 | [NameDump] 65 | 1 66 | 1 OscSineBank1 67 | 2 Keyboard1 68 | 3 AudioIn1 69 | 4 MasterOsc1 70 | 5 OscA1 71 | 6 2 outputs1 72 | 7 OscSineBank2 73 | 8 OscSineBank3 74 | [/NameDump] 75 | [NameDump] 76 | 0 77 | [/NameDump] 78 | -------------------------------------------------------------------------------- /mkqr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import nord.g2.modules 4 | 5 | pagemap = { 6 | 'In/Out': 0, 7 | 'Note': 1, 8 | 'Osc': 2, 9 | 'LFO': 3, 10 | 'Rnd': 4, 11 | 'Env': 5, 12 | 'Filter': 6, 13 | 'FX': 7, 14 | 'Delay': 8, 15 | 'Shaper': 9, 16 | 'Level': 10, 17 | 'Mixer': 11, 18 | 'Switch': 12, 19 | 'Logic': 13, 20 | 'Seq': 14, 21 | 'MIDI': 15, 22 | } 23 | 24 | pages = [ [] for p in range(16) ] 25 | for mod in nord.g2.modules.modules: 26 | pages[pagemap[mod.page.name]].append(mod) 27 | 28 | def byindex(a, b): 29 | return cmp(a.page.index, b.page.index) 30 | for page in pages: 31 | page.sort(byindex) 32 | 33 | def printdata(name, items): 34 | if len(items) == 0: 35 | return '' 36 | lines = [] 37 | s = '%s: ' % name 38 | for item in items: 39 | nm = item.name.lower() 40 | if len(s) + 5 + len(nm) > 80: 41 | lines.append(s) 42 | s = '' 43 | s += item.name.lower() + ' ' 44 | lines.append(s) 45 | return '\n '.join(lines) 46 | 47 | for page in pages: 48 | print '%s:' % page[0].page.name.lower() 49 | for mod in page: 50 | s = ' %s: ' % mod.shortnm.lower() 51 | ins = printdata('in', mod.inputs) 52 | outs = printdata('out', mod.outputs) 53 | params = printdata('params', mod.params) 54 | strs = [ins, outs, params] 55 | ns = ' %s ' % s.strip() 56 | for i in range(len(strs)): 57 | t = strs[i].strip() 58 | if not t: 59 | continue 60 | if len(ns) + len(t) + 1 > 80: 61 | ns = ns.rstrip() 62 | if ns[-1] == ',': ns = ns[:-1] 63 | print ns 64 | ns = ' ' 65 | ns += t + ', ' 66 | if ns.strip() != '': 67 | ns = ns.rstrip() 68 | if ns[-1] == ',': ns = ns[:-1] 69 | print ns 70 | -------------------------------------------------------------------------------- /tests/testkeyboardnote.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 1 0 0 8 | 2 97 0 2 9 | 3 7 0 5 10 | 4 8 0 11 11 | 5 9 0 17 12 | 6 96 1 0 13 | 7 95 1 4 14 | 8 58 1 8 15 | 9 97 2 0 16 | 10 7 2 3 17 | 11 8 2 9 18 | 13 96 2 15 19 | [/ModuleDump] 20 | [ModuleDump] 21 | 0 22 | [/ModuleDump] 23 | [CurrentNoteDump] 24 | 64 0 0 64 0 0 25 | [/CurrentNoteDump] 26 | [CableDump] 27 | 1 28 | 1 2 0 0 1 0 1 29 | 1 3 2 0 2 0 0 30 | 1 4 1 0 3 2 0 31 | 1 5 1 0 4 1 0 32 | 1 6 0 0 1 0 1 33 | 1 7 2 0 6 0 0 34 | 1 8 2 0 7 2 0 35 | 1 9 1 0 1 0 1 36 | 1 10 3 0 9 1 0 37 | 1 11 2 0 10 3 0 38 | 1 13 1 0 11 2 0 39 | [/CableDump] 40 | [CableDump] 41 | 0 42 | [/CableDump] 43 | [ParameterDump] 44 | 1 45 | 2 97 5 64 64 1 127 0 46 | 3 7 10 64 64 64 64 0 127 0 0 0 0 47 | 4 8 9 64 64 64 0 127 0 0 0 0 48 | 5 9 6 64 64 1 127 0 0 49 | 6 96 7 64 64 1 0 0 127 0 50 | 7 95 7 64 64 64 0 127 64 0 51 | 8 58 16 0 0 25 25 25 25 25 25 25 25 0 25 25 25 25 0 52 | 9 97 5 64 64 1 0 127 53 | 10 7 10 64 64 64 64 0 0 127 0 0 0 54 | 11 8 9 64 64 64 0 0 127 0 0 0 55 | 13 96 7 64 64 1 0 0 0 127 56 | [/ParameterDump] 57 | [ParameterDump] 58 | 0 59 | [/ParameterDump] 60 | [CustomDump] 61 | 1 62 | 2 1 0 63 | 3 1 0 64 | 4 1 0 65 | 5 1 0 66 | 6 1 0 67 | 7 1 0 68 | 9 1 0 69 | 10 1 0 70 | 11 1 0 71 | 13 1 0 72 | [/CustomDump] 73 | [CustomDump] 74 | 0 75 | [/CustomDump] 76 | [NameDump] 77 | 1 78 | 1 Keyboard1 79 | 2 MasterOsc1 80 | 3 OscA1 81 | 4 OscB1 82 | 5 OscC1 83 | 6 FormantOsc1 84 | 7 PercOsc1 85 | 8 DrumSynth1 86 | 9 MasterOsc2 87 | 10 OscA2 88 | 11 OscB2 89 | 13 FormantOsc2 90 | [/NameDump] 91 | [NameDump] 92 | 0 93 | [/NameDump] 94 | -------------------------------------------------------------------------------- /tests/testseq.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 477 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 17 0 5 8 | 2 91 0 11 9 | 3 15 2 5 10 | 4 90 2 13 11 | 5 35 0 0 12 | 6 35 0 2 13 | 7 73 1 5 14 | 8 73 1 7 15 | 9 73 1 9 16 | 10 73 1 11 17 | 12 40 1 18 18 | [/ModuleDump] 19 | [ModuleDump] 20 | 0 21 | [/ModuleDump] 22 | [CurrentNoteDump] 23 | 64 0 0 64 0 0 24 | [/CurrentNoteDump] 25 | [CableDump] 26 | 1 27 | 2 1 0 0 5 0 1 28 | 2 2 0 0 1 0 0 29 | 2 4 1 0 2 2 1 30 | 2 1 1 0 6 0 1 31 | 2 2 1 0 1 1 0 32 | 2 3 1 0 6 0 1 33 | 2 3 0 0 7 0 1 34 | 2 4 0 0 3 0 0 35 | 2 7 0 0 1 3 1 36 | 2 7 1 0 1 0 1 37 | 2 8 0 0 1 1 1 38 | 2 8 1 0 3 2 1 39 | 2 9 0 0 3 3 1 40 | 2 10 1 0 4 2 1 41 | 2 10 0 0 4 3 1 42 | 1 12 0 0 2 0 1 43 | 1 12 1 0 3 0 1 44 | 1 12 2 0 4 0 1 45 | [/CableDump] 46 | [CableDump] 47 | 0 48 | [/CableDump] 49 | [ParameterDump] 50 | 1 51 | 1 17 36 15 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 52 | 2 91 19 50 50 120 127 15 50 77 41 42 101 61 10 24 122 43 105 15 0 0 53 | 3 15 21 49 64 64 64 64 35 108 64 64 64 64 68 64 64 32 64 15 0 0 0 1 54 | 4 90 21 44 43 42 42 47 46 47 38 38 45 45 41 51 40 44 49 15 0 0 0 1 55 | 5 35 1 64 56 | 6 35 1 64 57 | 7 73 1 0 58 | 8 73 1 0 59 | 9 73 1 0 60 | 10 73 1 0 61 | 12 40 9 100 100 100 100 100 100 100 100 0 62 | [/ParameterDump] 63 | [ParameterDump] 64 | 0 65 | [/ParameterDump] 66 | [CustomDump] 67 | 1 68 | 4 2 1 0 69 | [/CustomDump] 70 | [CustomDump] 71 | 0 72 | [/CustomDump] 73 | [NameDump] 74 | 1 75 | 1 EventSeq1 76 | 2 CtrlSeq1 77 | 3 NoteSeqA1 78 | 4 NoteSeqB1 79 | 5 RndPulsGen1 80 | 6 RndPulsGen2 81 | 7 LogicProc1 82 | 8 LogicProc1 83 | 9 LogicProc1 84 | 10 LogicProc1 85 | 12 Mixer1 86 | [/NameDump] 87 | [NameDump] 88 | 0 89 | [/NameDump] 90 | -------------------------------------------------------------------------------- /tests/testenv.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 477 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 20 0 5 8 | 2 84 0 11 9 | 3 23 0 15 10 | 4 52 2 11 11 | 5 1 0 0 12 | 6 2 0 2 13 | 7 40 1 11 14 | 8 46 2 5 15 | 9 71 2 19 16 | 10 52 2 23 17 | [/ModuleDump] 18 | [ModuleDump] 19 | 0 20 | [/ModuleDump] 21 | [CurrentNoteDump] 22 | 64 0 0 64 0 0 23 | [/CurrentNoteDump] 24 | [CableDump] 25 | 1 26 | 1 1 3 0 5 0 1 27 | 1 3 7 0 1 3 0 28 | 1 4 2 0 3 7 0 29 | 1 10 2 0 4 2 0 30 | 1 2 2 0 5 2 1 31 | 1 3 2 0 1 0 1 32 | 1 8 5 0 1 0 1 33 | 1 3 3 0 2 0 1 34 | 1 8 1 0 2 0 1 35 | 1 3 4 0 4 0 1 36 | 1 8 3 0 4 0 1 37 | 0 1 0 0 6 0 1 38 | 0 2 1 0 1 0 0 39 | 0 3 6 0 2 1 0 40 | 0 8 4 0 6 1 1 41 | 0 4 1 0 8 4 0 42 | 0 9 0 0 4 1 0 43 | 0 7 0 0 1 1 1 44 | 0 7 1 0 2 1 1 45 | 0 7 2 0 3 1 1 46 | 0 7 3 0 8 1 1 47 | 0 7 4 0 4 1 1 48 | 1 7 5 0 9 0 1 49 | 1 3 5 0 9 0 1 50 | 2 1 1 0 5 1 1 51 | 2 3 0 0 1 1 0 52 | 2 8 0 0 5 1 1 53 | 2 4 0 0 8 0 0 54 | 2 2 0 0 4 0 0 55 | 2 10 0 0 4 0 0 56 | 1 8 2 0 3 0 1 57 | 1 1 2 0 8 0 1 58 | 1 3 1 0 1 2 0 59 | [/CableDump] 60 | [CableDump] 61 | 0 62 | [/CableDump] 63 | [ParameterDump] 64 | 1 65 | 1 20 6 2 0 77 127 0 0 66 | 2 84 3 0 77 0 67 | 3 23 9 0 77 127 0 0 0 0 0 0 68 | 4 52 11 127 45 64 0 0 30 30 30 0 3 2 69 | 7 40 9 100 100 100 100 100 100 100 100 0 70 | 8 46 6 0 32 77 0 0 0 71 | 9 71 2 0 20 72 | 10 52 11 50 45 64 0 0 30 30 30 0 4 1 73 | [/ParameterDump] 74 | [ParameterDump] 75 | 0 76 | [/ParameterDump] 77 | [CustomDump] 78 | 1 79 | [/CustomDump] 80 | [CustomDump] 81 | 0 82 | [/CustomDump] 83 | [NameDump] 84 | 1 85 | 1 ADSR-Env1 86 | 2 AD-Env1 87 | 3 Mod-Env1 88 | 4 Multi-Env1 89 | 5 Keyboard1 90 | 6 AudioIn1 91 | 7 Mixer1 92 | 8 AHD-Env1 93 | 9 EnvFollower1 94 | 10 Multi-Env2 95 | [/NameDump] 96 | [NameDump] 97 | 0 98 | [/NameDump] 99 | -------------------------------------------------------------------------------- /nord/g2/colors.py: -------------------------------------------------------------------------------- 1 | # 2 | # colors.py - g2 color definitions 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | from nord import Mapping 24 | 25 | g2modulecolors = Mapping( 26 | grey = 0, 27 | red1 = 6, 28 | red2 = 13, 29 | red3 = 14, 30 | red4 = 1, 31 | yellow1 = 9, 32 | yellow2 = 11, 33 | yellow3 = 15, 34 | yellow4 = 4, 35 | green1 = 10, 36 | green2 = 8, 37 | green3 = 16, 38 | green4 = 2, 39 | cyan1 = 17, 40 | cyan2 = 7, 41 | cyan3 = 18, 42 | cyan4 = 19, 43 | blue1 = 5, 44 | blue2 = 20, 45 | blue3 = 12, 46 | blue4 = 3, 47 | magenta1 = 21, 48 | magenta2 = 22, 49 | magenta3 = 23, 50 | magenta4 = 24 51 | ) 52 | 53 | g2cablecolors = Mapping( 54 | red = 0, 55 | blue = 1, 56 | yellow = 2, 57 | orange = 3, 58 | green = 4, 59 | purple = 5, 60 | white = 6 61 | ) 62 | g2cablecolors.add_mappings( 63 | audio = g2cablecolors.red, 64 | control = g2cablecolors.blue, 65 | logic_bg = g2cablecolors.yellow, 66 | logic_fg = g2cablecolors.orange, 67 | user1 = g2cablecolors.green, 68 | user2 = g2cablecolors.purple 69 | ) 70 | 71 | g2conncolors = Mapping( 72 | red = 0, 73 | blue = 1, 74 | yellow = 2, 75 | orange = 3, 76 | blue_red = 4, 77 | yellow_orange = 5 78 | ) 79 | -------------------------------------------------------------------------------- /tests/testlogic.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 36 0 3 8 | 2 64 0 6 9 | 3 1 0 0 10 | 4 38 0 9 11 | 5 37 0 12 12 | 6 70 0 15 13 | 7 73 1 3 14 | 8 59 1 6 15 | 9 89 1 9 16 | 10 69 1 12 17 | 11 36 1 21 18 | 12 77 1 18 19 | 13 36 1 23 20 | 14 36 1 25 21 | 15 36 1 27 22 | 16 73 0 24 23 | 17 7 0 18 24 | 18 68 1 15 25 | [/ModuleDump] 26 | [ModuleDump] 27 | 0 28 | [/ModuleDump] 29 | [CurrentNoteDump] 30 | 64 0 0 64 0 0 31 | [/CurrentNoteDump] 32 | [CableDump] 33 | 1 34 | 2 1 0 0 3 1 1 35 | 2 2 0 0 1 0 1 36 | 2 4 0 0 2 0 1 37 | 2 5 0 0 4 0 1 38 | 2 6 0 0 5 0 1 39 | 2 10 0 0 7 0 1 40 | 1 8 0 0 3 0 1 41 | 1 9 0 0 8 0 0 42 | 1 9 1 0 3 2 1 43 | 2 7 1 0 8 0 1 44 | 2 7 0 0 9 0 1 45 | 2 11 0 0 10 0 1 46 | 2 13 0 0 12 2 1 47 | 2 14 0 0 12 1 1 48 | 2 15 0 0 12 0 1 49 | 0 16 1 0 17 0 1 50 | 0 16 0 0 16 1 0 51 | 2 10 1 0 6 0 1 52 | 2 12 1 0 18 3 1 53 | 2 12 0 0 18 0 1 54 | [/CableDump] 55 | [CableDump] 56 | 0 57 | [/CableDump] 58 | [ParameterDump] 59 | 1 60 | 1 36 1 64 61 | 2 64 1 64 62 | 4 38 1 8 63 | 5 37 1 64 64 | 7 73 1 0 65 | 8 59 1 77 66 | 10 69 1 0 67 | 11 36 1 64 68 | 13 36 1 64 69 | 14 36 1 64 70 | 15 36 1 64 71 | 16 73 1 2 72 | 17 7 10 64 64 64 64 0 0 0 0 0 0 73 | 18 68 2 64 1 74 | [/ParameterDump] 75 | [ParameterDump] 76 | 0 77 | [/ParameterDump] 78 | [CustomDump] 79 | 1 80 | 17 1 0 81 | [/CustomDump] 82 | [CustomDump] 83 | 0 84 | [/CustomDump] 85 | [NameDump] 86 | 1 87 | 1 PosEdgeDly1 88 | 2 NegEdgeDly1 89 | 3 Keyboard1 90 | 4 Pulse1 91 | 5 LogicDelay1 92 | 6 LogicInv1 93 | 7 LogicProc1 94 | 8 CompareLev1 95 | 9 CompareAB1 96 | 10 ClkDiv1 97 | 11 PosEdgeDly2 98 | 12 ClkDivFix1 99 | 13 PosEdgeDly2 100 | 14 PosEdgeDly2 101 | 15 PosEdgeDly2 102 | 16 LogicProc2 103 | 17 OscA1 104 | 18 ClkGen1 105 | [/NameDump] 106 | [NameDump] 107 | 0 108 | [/NameDump] 109 | -------------------------------------------------------------------------------- /tests/testmixer.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 44 0 1 8 | 2 18 0 4 9 | 3 47 0 8 10 | 4 113 0 12 11 | 5 114 0 15 12 | 6 111 0 18 13 | 7 112 0 21 14 | 8 76 1 1 15 | 9 79 1 4 16 | 10 88 1 8 17 | 11 81 1 12 18 | 12 19 1 15 19 | 13 40 1 18 20 | [/ModuleDump] 21 | [ModuleDump] 22 | 0 23 | [/ModuleDump] 24 | [CurrentNoteDump] 25 | 64 0 0 64 0 0 26 | [/CurrentNoteDump] 27 | [CableDump] 28 | 1 29 | 0 2 0 0 3 0 1 30 | 0 12 1 0 3 0 1 31 | 0 13 1 0 12 1 0 32 | 0 2 1 0 3 1 1 33 | 0 12 0 0 3 1 1 34 | 0 13 0 0 12 0 0 35 | 0 3 0 0 2 0 1 36 | 0 1 0 0 2 0 1 37 | 0 1 1 0 2 0 1 38 | 0 12 2 0 2 0 1 39 | 0 13 2 0 12 2 0 40 | 0 5 0 0 4 0 1 41 | 0 5 1 0 4 1 1 42 | 0 13 3 0 4 1 1 43 | 0 4 0 0 5 0 1 44 | 0 13 4 0 5 0 1 45 | 0 6 0 0 7 0 1 46 | 0 7 0 0 6 0 1 47 | 0 13 5 0 6 0 1 48 | 0 2 2 0 1 0 1 49 | 0 3 1 0 2 2 0 50 | 0 9 0 0 10 0 1 51 | 0 9 1 0 10 1 1 52 | 0 9 2 0 10 2 1 53 | 0 9 3 0 10 3 1 54 | 0 10 0 0 9 0 1 55 | 0 11 0 0 8 0 1 56 | 0 8 0 0 11 0 1 57 | 0 13 6 0 12 0 1 58 | 0 13 7 0 13 0 1 59 | [/CableDump] 60 | [CableDump] 61 | 0 62 | [/CableDump] 63 | [ParameterDump] 64 | 1 65 | 1 44 1 0 66 | 2 18 2 65 64 67 | 3 47 2 63 64 68 | 4 113 1 127 69 | 5 114 1 0 70 | 6 111 2 102 0 71 | 7 112 2 64 1 72 | 8 76 1 1 73 | 9 79 6 2 127 86 53 127 0 74 | 10 88 3 1 81 0 75 | 11 81 1 64 76 | 12 19 3 127 127 127 77 | 13 40 9 100 100 100 100 100 100 100 100 0 78 | [/ParameterDump] 79 | [ParameterDump] 80 | 0 81 | [/ParameterDump] 82 | [CustomDump] 83 | 1 84 | [/CustomDump] 85 | [CustomDump] 86 | 0 87 | [/CustomDump] 88 | [NameDump] 89 | 1 90 | 1 GainControl1 91 | 2 X-Fade1 92 | 3 Pan1 93 | 4 1to2Fade1 94 | 5 2to1Fade1 95 | 6 LevMult1 96 | 7 LevAdd1 97 | 8 OnOff1 98 | 9 4-1Switch1 99 | 10 1-4Switch1 100 | 11 Amplifier1 101 | 12 Mixer1 102 | 13 Mixer2 103 | [/NameDump] 104 | [NameDump] 105 | 0 106 | [/NameDump] 107 | -------------------------------------------------------------------------------- /nord/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2006,2007 Matt Gerassimoff 3 | # 4 | # This file is part of g2ools. 5 | # 6 | # g2ools is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # g2ools is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Foobar; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | def printf(fmt, *a): 21 | import sys 22 | sys.stdout.write(fmt % a) 23 | 24 | def sprintf(fmt, *a): 25 | return fmt % a 26 | 27 | class Struct(object): 28 | '''Struct class for creating objects with named parameters.''' 29 | def __init__(self, **kw): 30 | '''Struct(**kw) -> Struct object 31 | 32 | \tmembers become **kw keys. 33 | ''' 34 | self.__dict__ = kw 35 | 36 | class Mapping(object): 37 | '''Mapping class for creating objects with named/value mappings.''' 38 | def __init__(self, **kw): 39 | '''Mapping(**kw) -> Mapping object 40 | 41 | \tname/value and value/name become **kw keys. 42 | ''' 43 | self.__dict = {} 44 | for name, value in kw.items(): 45 | self.add_mapping(name, value) 46 | 47 | def add_mappings(self, **kw): 48 | for name, value in kw.items(): 49 | self.add_mapping(name, value) 50 | 51 | def add_mapping(self, name, value): 52 | self.__dict__[name] = value 53 | self.__dict[value] = name 54 | 55 | def name(self, value): 56 | return self.__dict[value] 57 | 58 | def value(self, name): 59 | return self.__dict[name] 60 | 61 | def __getattr__(self, name): 62 | try: 63 | return self.__dict__[name] 64 | except: 65 | return self.__dict[name] 66 | 67 | def __getitem__(self, name): 68 | return self.__getattr__(name) 69 | 70 | -------------------------------------------------------------------------------- /prf2cat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import sys 23 | from nord.g2.file import Prf2File 24 | from nord.g2.pprint import printpatch 25 | 26 | def printf(fmt, *a): 27 | return sys.stdout.write(fmt % a) 28 | 29 | prog = sys.argv.pop(0) 30 | while len(sys.argv): 31 | filename = sys.argv.pop(0) 32 | printf('"%s"\n', filename) 33 | prf2 = Prf2File(filename) 34 | perf = prf2.performance 35 | printf(' focus: %s\n', 'abcd'[perf.description.focus]) 36 | printf(' range enable: %s\n', ['off','on'][perf.description.rangesel]) 37 | printf(' master clock: %d BPM: %s\n', perf.description.bpm, 38 | ['stop','run'][perf.description.clock]) 39 | printf(' kb split: %s\n', ['off','on'][perf.description.split]) 40 | for sloti, slot in enumerate(perf.slots): 41 | description = slot.description 42 | name = '"%s"' % slot.name 43 | printf(' slot %s: %d:%d %-16s\n', 'abcd'[sloti], 44 | description.bank+1, description.patch+1, name) 45 | printf(' active: %-3s, ', ['off','on'][description.active]) 46 | printf('key: %-3s, ', ['off','on'][description.keyboard]) 47 | printf('hold: %-3s, ', ['off','on'][description.hold]) 48 | printf('range: %d-%d\n', description.keylow, description.keyhigh) 49 | for sloti, slot in enumerate(perf.slots, 1): 50 | printf('Patch %d: "%s"\n', sloti, slot.name) 51 | printpatch(slot.patch) 52 | 53 | -------------------------------------------------------------------------------- /tests/testfilter.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 86 0 3 8 | 2 87 0 6 9 | 3 2 0 0 10 | 4 50 0 9 11 | 5 49 0 14 12 | 6 51 0 20 13 | 7 92 1 3 14 | 8 45 1 10 15 | 9 108 1 16 16 | 10 103 2 3 17 | 12 40 1 25 18 | 13 1 0 27 19 | 11 104 2 10 20 | 14 40 2 25 21 | 15 32 2 15 22 | [/ModuleDump] 23 | [ModuleDump] 24 | 0 25 | [/ModuleDump] 26 | [CurrentNoteDump] 27 | 64 0 0 64 0 0 28 | [/CurrentNoteDump] 29 | [CableDump] 30 | 1 31 | 0 1 0 0 3 0 1 32 | 0 2 0 0 1 0 1 33 | 0 4 0 0 2 0 1 34 | 0 5 1 0 4 0 0 35 | 0 6 2 0 5 1 0 36 | 0 6 1 0 6 2 0 37 | 0 6 3 0 6 1 0 38 | 0 6 0 0 6 3 0 39 | 0 7 2 0 3 1 1 40 | 0 8 0 0 7 0 1 41 | 0 11 0 0 7 0 1 42 | 0 9 0 0 8 0 1 43 | 0 9 1 0 9 0 0 44 | 0 10 0 0 9 0 1 45 | 0 12 0 0 6 0 1 46 | 0 12 1 0 5 2 1 47 | 0 12 2 0 5 1 1 48 | 0 12 3 0 5 0 1 49 | 0 12 4 0 4 0 1 50 | 0 12 5 0 4 1 1 51 | 0 12 6 0 4 2 1 52 | 1 5 0 0 13 0 1 53 | 0 12 7 0 10 0 1 54 | 1 8 2 0 13 2 1 55 | 1 8 1 0 8 2 0 56 | 1 7 1 0 8 1 0 57 | 1 7 0 0 7 1 0 58 | 0 15 0 0 11 0 1 59 | 0 14 0 0 15 0 1 60 | [/CableDump] 61 | [CableDump] 62 | 0 63 | [/CableDump] 64 | [ParameterDump] 65 | 1 66 | 1 86 1 64 67 | 2 87 1 64 68 | 4 50 3 60 0 1 69 | 5 49 4 61 93 0 30 70 | 6 51 10 0 1 52 60 44 0 0 1 64 0 71 | 7 92 7 60 64 0 107 36 2 0 72 | 8 45 9 0 1 2 100 65 0 64 43 64 73 | 9 108 19 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 64 0 0 74 | 10 103 5 60 64 64 0 127 75 | 11 104 5 60 127 0 0 127 76 | 12 40 9 100 100 100 100 100 100 100 100 0 77 | 14 40 9 100 100 100 100 100 100 100 100 0 78 | 15 32 15 127 127 127 127 127 127 127 127 127 127 127 127 127 127 0 79 | [/ParameterDump] 80 | [ParameterDump] 81 | 0 82 | [/ParameterDump] 83 | [CustomDump] 84 | 1 85 | 4 1 0 86 | 5 1 0 87 | 6 1 0 88 | 7 1 0 89 | [/CustomDump] 90 | [CustomDump] 91 | 0 92 | [/CustomDump] 93 | [NameDump] 94 | 1 95 | 1 FilterA1 96 | 2 FilterB1 97 | 3 AudioIn1 98 | 4 FilterC1 99 | 5 FilterD1 100 | 6 FilterE1 101 | 7 FilterF1 102 | 8 VocalFilter1 103 | 9 Vocoder1 104 | 10 EqMid1 105 | 11 EqShelving1 106 | 12 Mixer1 107 | 13 Keyboard1 108 | 14 Mixer2 109 | 15 Filter Bank1 110 | [/NameDump] 111 | [NameDump] 112 | 0 113 | [/NameDump] 114 | -------------------------------------------------------------------------------- /nord/utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # utils.py - misc util functions 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | # toascii remove bad characters 24 | def toascii(s): 25 | # conversion strings for 192-255 26 | s161 = '!cL#Y|S"Ca<^-R-o+23\'uP.10>%%%?' \ 27 | 'AAAAAAACEEEEIIIIDNOOOOOOXOUUUUYpBaaaaaaaceeeeeiiiienooooo/ouuuuypy' 28 | def conv(c): 29 | o = ord(c) 30 | if o < 128: 31 | return c 32 | elif o < 161: 33 | return chr(c-64) 34 | else: 35 | return s161[o-161] 36 | return '' 37 | return ''.join([ conv(c) for c in s ]) 38 | 39 | def setv(g2param, val): 40 | '''setv(g2param, val) - set all variations to val.''' 41 | g2param.variations = [ val ] * 9 42 | 43 | def getv(nmparam, variation=0): 44 | '''getv(nmparam) - get variations[variation].''' 45 | return nmparam.variations[variation] 46 | 47 | def setav(g2param, array): 48 | '''setv(g2param, array) - set variations from array.''' 49 | g2param.variations = array[:9] 50 | 51 | def cpv(g2param, nmparam): 52 | '''cpy(g2param, nmparam) - copy variations.''' 53 | g2param.variations = nmparam.variations[:] 54 | 55 | def isnm1osc(module): 56 | '''isnm1osc(module) - is NM1 module an oscillator''' 57 | shortnms = ['OscMaster', 'OscA', 'OscB', 'OscC', 'OscSlvB', 'OscSlvC', 58 | 'OscSlvD', 'OscSlvE', 'OscSlvA', 'OscSlvFM', 'PercOsc', 59 | 'FormantOsc', 'SpectralOsc', 'MasterOsc', 'OscSineBank'] 60 | return module.type.shortnm in shortnms 61 | 62 | def isnm1lfo(module): 63 | '''isnm1lfo(module) - is NM1 module an lfo.''' 64 | shortnms = ['LFOA', 'LFOB', 'LFOC', 65 | 'LFOSlvB', 'LFOSlvC', 'LFOSlvD', 'LFOSlvE', 'LFOSlvF', 'ClkGen'] 66 | return module.type.shortnm in shortnms 67 | -------------------------------------------------------------------------------- /tests/testmstslv.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 97 0 2 8 | 2 14 0 5 9 | 3 1 0 0 10 | 4 7 0 10 11 | 5 10 0 16 12 | 6 8 0 20 13 | 7 11 0 26 14 | 8 9 1 0 15 | 9 12 1 4 16 | 10 96 1 8 17 | 11 13 1 14 18 | 12 85 1 17 19 | 13 111 1 12 20 | 14 24 2 0 21 | 15 80 2 5 22 | 16 25 2 10 23 | 17 27 2 15 24 | 18 49 3 0 25 | 19 51 3 6 26 | 20 92 3 13 27 | [/ModuleDump] 28 | [ModuleDump] 29 | 0 30 | [/ModuleDump] 31 | [CurrentNoteDump] 32 | 64 0 0 64 0 0 33 | [/CurrentNoteDump] 34 | [CableDump] 35 | 1 36 | 3 2 0 0 1 0 1 37 | 1 1 0 0 3 0 1 38 | 3 5 0 0 4 1 1 39 | 3 7 0 0 6 1 1 40 | 3 9 0 0 8 1 1 41 | 0 11 0 0 13 0 1 42 | 0 12 0 0 11 0 0 43 | 3 13 0 0 10 1 1 44 | 0 4 3 0 2 0 1 45 | 0 4 2 0 4 3 0 46 | 0 6 1 0 4 2 0 47 | 0 6 2 0 6 1 0 48 | 3 15 0 0 14 0 1 49 | 3 17 0 0 16 1 1 50 | 0 14 0 0 8 0 1 51 | [/CableDump] 52 | [CableDump] 53 | 0 54 | [/CableDump] 55 | [ParameterDump] 56 | 1 57 | 1 97 5 64 64 1 127 0 58 | 2 14 5 124 64 0 0 0 59 | 4 7 10 64 64 127 64 0 0 0 0 0 0 60 | 5 10 5 64 64 64 0 0 61 | 6 8 9 64 64 44 0 0 0 0 0 0 62 | 7 11 4 64 64 0 0 63 | 8 9 6 64 64 1 0 0 0 64 | 9 12 4 64 64 0 0 65 | 10 96 7 64 64 1 0 0 0 0 66 | 11 13 4 64 64 0 0 67 | 12 85 5 64 64 0 0 0 68 | 13 111 2 103 1 69 | 14 24 8 64 1 0 0 0 0 64 0 70 | 15 80 5 64 64 0 0 0 71 | 16 25 8 64 1 64 0 0 0 0 64 72 | 17 27 1 64 73 | 18 49 4 60 0 0 0 74 | 19 51 10 0 1 0 60 39 0 0 1 0 0 75 | 20 92 7 60 127 0 0 0 2 0 76 | [/ParameterDump] 77 | [ParameterDump] 78 | 0 79 | [/ParameterDump] 80 | [CustomDump] 81 | 1 82 | 1 1 0 83 | 2 1 0 84 | 4 1 0 85 | 5 1 0 86 | 6 1 0 87 | 7 1 0 88 | 8 1 0 89 | 9 1 0 90 | 10 1 0 91 | 11 1 0 92 | 12 1 0 93 | 15 1 0 94 | 17 1 0 95 | 18 1 0 96 | 19 1 0 97 | 20 1 0 98 | [/CustomDump] 99 | [CustomDump] 100 | 0 101 | [/CustomDump] 102 | [NameDump] 103 | 1 104 | 1 MasterOsc1 105 | 2 OscSlvA1 106 | 3 Keyboard1 107 | 4 OscA1 108 | 5 OscSlvB1 109 | 6 OscB1 110 | 7 OscSlvC1 111 | 8 OscC1 112 | 9 OscSlvD1 113 | 10 FormantOsc1 114 | 11 OscSlvE1 115 | 12 OscSlvFM1 116 | 13 LevMult1 117 | 14 LFOA1 118 | 15 LFOSlvA1 119 | 16 LFOB1 120 | 17 LFOSlvB1 121 | 18 FilterD1 122 | 19 FilterE1 123 | 20 FilterF1 124 | [/NameDump] 125 | [NameDump] 126 | 0 127 | [/NameDump] 128 | -------------------------------------------------------------------------------- /tests/testlfo.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 24 0 3 8 | 2 25 0 9 9 | 3 26 0 15 10 | 4 40 1 13 11 | 5 1 0 0 12 | 6 80 2 0 13 | 7 27 2 5 14 | 8 29 2 8 15 | 9 30 2 11 16 | 10 68 2 14 17 | 11 33 2 18 18 | 12 34 2 21 19 | 13 110 2 24 20 | 14 35 2 27 21 | 15 99 2 30 22 | 16 40 1 18 23 | 17 99 1 26 24 | 18 27 3 15 25 | [/ModuleDump] 26 | [ModuleDump] 27 | 0 28 | [/ModuleDump] 29 | [CurrentNoteDump] 30 | 64 0 0 64 0 0 31 | [/CurrentNoteDump] 32 | [CableDump] 33 | 1 34 | 1 4 2 0 3 0 1 35 | 1 4 1 0 2 0 1 36 | 1 4 0 0 1 1 1 37 | 1 1 0 0 5 0 1 38 | 1 2 0 0 1 0 0 39 | 1 3 0 0 2 0 0 40 | 1 2 2 0 3 0 0 41 | 1 15 2 0 2 2 0 42 | 2 1 1 0 5 1 1 43 | 2 2 1 0 1 1 0 44 | 2 6 1 0 5 1 1 45 | 2 10 0 0 6 1 0 46 | 2 11 0 0 10 0 0 47 | 2 15 0 0 11 0 0 48 | 2 15 1 0 15 0 0 49 | 1 4 3 0 6 0 1 50 | 1 4 4 0 7 0 1 51 | 1 4 5 0 8 0 1 52 | 1 4 6 0 9 0 1 53 | 2 4 7 0 10 0 1 54 | 2 16 0 0 10 1 1 55 | 2 16 1 0 10 3 1 56 | 1 16 2 0 11 0 1 57 | 1 16 3 0 12 0 1 58 | 1 16 4 0 13 0 1 59 | 2 16 5 0 14 0 1 60 | 1 16 6 0 15 0 1 61 | 3 7 0 0 1 0 1 62 | 3 8 0 0 2 1 1 63 | 3 9 0 0 3 1 1 64 | 3 18 0 0 10 2 1 65 | [/CableDump] 66 | [CableDump] 67 | 0 68 | [/CableDump] 69 | [ParameterDump] 70 | 1 71 | 1 24 8 64 2 1 41 1 46 64 0 72 | 2 25 8 70 1 65 23 0 0 0 64 73 | 3 26 6 64 0 4 50 0 0 74 | 4 40 9 100 100 100 100 100 100 100 100 0 75 | 6 80 5 64 64 2 0 0 76 | 7 27 1 97 77 | 8 29 1 22 78 | 9 30 1 106 79 | 10 68 2 64 1 80 | 11 33 2 0 0 81 | 12 34 1 64 82 | 13 110 1 64 83 | 14 35 1 64 84 | 15 99 5 0 0 0 15 0 85 | 16 40 9 100 100 100 100 100 100 100 100 0 86 | 17 99 5 0 0 1 15 0 87 | 18 27 1 64 88 | [/ParameterDump] 89 | [ParameterDump] 90 | 0 91 | [/ParameterDump] 92 | [CustomDump] 93 | 1 94 | 6 1 0 95 | 7 1 0 96 | 8 1 0 97 | 9 1 0 98 | 12 1 0 99 | 13 1 0 100 | 18 1 0 101 | [/CustomDump] 102 | [CustomDump] 103 | 0 104 | [/CustomDump] 105 | [NameDump] 106 | 1 107 | 1 LFOA1 108 | 2 LFOB1 109 | 3 LFOC1 110 | 4 Mixer1 111 | 5 Keyboard1 112 | 6 LFOSlvA1 113 | 7 LFOSlvB1 114 | 8 LFOSlvD1 115 | 9 LFOSlvE1 116 | 10 ClkGen1 117 | 11 ClkRndGen1 118 | 12 RndStepGen1 119 | 13 RandomGen1 120 | 14 RndPulsGen1 121 | 15 PatternGen1 122 | 16 Mixer2 123 | 17 PatternGen2 124 | 18 LFOSlvB2 125 | [/NameDump] 126 | [NameDump] 127 | 0 128 | [/NameDump] 129 | -------------------------------------------------------------------------------- /tests/testaudio.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 600 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 61 0 5 8 | 2 62 0 9 9 | 3 74 0 13 10 | 4 54 0 17 11 | 5 78 0 20 12 | 6 53 0 24 13 | 7 1 0 0 14 | 8 2 0 2 15 | 9 82 1 6 16 | 10 94 1 9 17 | 12 57 1 21 18 | 13 83 1 24 19 | 14 21 2 7 20 | 16 117 2 16 21 | 17 40 2 26 22 | 15 118 2 22 23 | 11 102 1 13 24 | 18 105 3 7 25 | [/ModuleDump] 26 | [ModuleDump] 27 | 0 28 | [/ModuleDump] 29 | [CurrentNoteDump] 30 | 64 0 0 64 0 0 31 | [/CurrentNoteDump] 32 | [CableDump] 33 | 1 34 | 0 1 1 0 8 0 1 35 | 0 2 1 0 1 1 0 36 | 0 3 1 0 2 1 0 37 | 0 5 1 0 3 1 0 38 | 0 1 0 0 8 1 1 39 | 0 9 0 0 8 1 1 40 | 0 16 2 0 9 0 0 41 | 0 11 0 0 9 0 0 42 | 0 2 0 0 1 0 1 43 | 0 3 0 0 2 0 1 44 | 0 4 0 0 3 0 1 45 | 0 5 0 0 4 0 1 46 | 0 6 1 0 5 1 1 47 | 2 6 0 0 7 1 1 48 | 0 17 0 0 6 0 1 49 | 0 10 0 0 9 0 1 50 | 0 14 2 0 9 0 1 51 | 0 18 2 0 14 2 0 52 | 0 14 0 0 10 0 1 53 | 0 18 0 0 14 0 0 54 | 0 14 1 0 10 1 1 55 | 0 18 1 0 14 1 0 56 | 0 13 0 0 12 0 1 57 | 0 16 1 0 12 0 1 58 | 0 16 0 0 13 0 1 59 | 0 15 0 0 16 0 0 60 | 0 17 4 0 16 0 1 61 | 0 17 3 0 14 1 1 62 | 0 17 2 0 14 0 1 63 | 0 17 5 0 15 0 1 64 | 0 12 0 0 5 0 1 65 | 0 17 1 0 11 0 1 66 | 1 11 1 0 7 0 1 67 | 1 11 2 0 7 2 1 68 | 1 15 1 0 11 2 0 69 | 0 17 6 0 18 0 1 70 | 0 17 7 0 18 1 1 71 | [/CableDump] 72 | [CableDump] 73 | 0 74 | [/CableDump] 75 | [ParameterDump] 76 | 1 77 | 1 61 3 0 82 0 78 | 2 62 2 0 48 79 | 3 74 2 0 0 80 | 4 54 1 12 81 | 5 78 2 0 64 82 | 9 82 1 0 83 | 10 94 3 64 64 0 84 | 11 102 11 60 1 0 64 0 64 4 64 0 64 127 85 | 12 57 2 0 0 86 | 13 83 1 2 87 | 14 21 9 0 20 18 20 30 12 1 0 0 88 | 15 118 5 11 67 0 1 0 89 | 16 117 2 0 64 90 | 17 40 9 100 100 100 100 101 100 100 100 0 91 | 18 105 9 0 20 24 20 0 0 0 0 0 92 | [/ParameterDump] 93 | [ParameterDump] 94 | 0 95 | [/ParameterDump] 96 | [CustomDump] 97 | 1 98 | [/CustomDump] 99 | [CustomDump] 100 | 0 101 | [/CustomDump] 102 | [NameDump] 103 | 1 104 | 1 Clip1 105 | 2 Overdrive1 106 | 3 WaveWrap1 107 | 4 Quantizer1 108 | 5 Delay1 109 | 6 Sample&Hold1 110 | 7 Keyboard1 111 | 8 AudioIn1 112 | 9 Diode1 113 | 10 StChorus1 114 | 11 Phaser1 115 | 12 InvLevShift1 116 | 13 Shaper1 117 | 14 Compressor1 118 | 15 Digitizer1 119 | 16 RingMod1 120 | 17 Mixer1 121 | 18 Expander1 122 | [/NameDump] 123 | [NameDump] 124 | 0 125 | [/NameDump] 126 | -------------------------------------------------------------------------------- /nord/g2/misc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | from nord.g2.colors import g2conncolors 22 | 23 | def midicc_reserved(cc): 24 | reservedmidiccs = [ 0, 1, 7, 11, 17, 18, 19, 32, 64, 70, 80, 96, 97 ] + \ 25 | range(120, 128) 26 | return cc in reservedmidiccs 27 | 28 | def handle_uprate(g2area): 29 | # parse the entire netlist of the area and .uprate=1 all 30 | # modules with blue_red and yellow_orange inputs connected to red outputs. 31 | # scan module list until we don't change any modules 32 | done = 0 33 | while not done: 34 | modified = 0 35 | for module in g2area.modules: 36 | #debug('%s:%s' % (module.name, module.type.shortnm)) 37 | for minput in module.inputs: 38 | if not minput.net: 39 | continue 40 | #debug(' %s:%d' % (minput.type.name, minput.rate)) 41 | # try and make all logic run at control rate. 42 | if minput.rate == g2conncolors.yellow_orange: 43 | minput.rate = g2conncolors.yellow 44 | continue 45 | if minput.rate != g2conncolors.blue_red: 46 | continue 47 | if not minput.net.output: 48 | continue 49 | if minput.net.output.rate == g2conncolors.red: 50 | #debug('%s:%s %s' % ( 51 | # module.name, minput.type.name, minput.net.output.type.name)) 52 | modified = 1 53 | module.uprate = 1 54 | minput.rate = g2conncolors.red 55 | # change all outputs to red for next iteration 56 | for output in module.outputs: 57 | if output.rate == g2conncolors.blue_red: 58 | output.rate = g2conncolors.red 59 | if output.rate == g2conncolors.yellow_orange: 60 | output.rate = g2conncolors.orange 61 | break 62 | if not modified: 63 | done = 1 64 | 65 | -------------------------------------------------------------------------------- /nord/types.py: -------------------------------------------------------------------------------- 1 | # 2 | # types.py - type definitions for various nord modular objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord import Struct 23 | from nord.module import Input, Output, Param, Mode, Module 24 | 25 | class ParamDef(Struct): 26 | '''ParamDef Struct subclass for handling module parameter definitions.''' 27 | pass 28 | 29 | class Type(object): 30 | '''Type abstract class maintaining types.''' 31 | def __init__(self, name, type, horiz=0, vert=0): 32 | self.name = name 33 | self.type = type 34 | self.horiz = horiz 35 | self.vert = vert 36 | 37 | class TypeList(list): 38 | def __init__(self, types): 39 | super(TypeList, self).__init__(types) 40 | for type in types: 41 | setattr(self, type.name, type) 42 | 43 | class InputType(Type): 44 | '''InputType Type subclass maintaining module type Inputs.''' 45 | cls = Input 46 | 47 | InputList = TypeList 48 | 49 | class OutputType(Type): 50 | '''OutputType Type subclass maintaining module type Outputs.''' 51 | cls = Output 52 | 53 | OutputList = TypeList 54 | 55 | class ParamType(object): 56 | '''ParamType Type subclass maintaining module type Parameters.''' 57 | cls = Param 58 | def __init__(self, name, type, labels=None): 59 | self.name = name 60 | self.type = type 61 | if labels == None: 62 | labels = [] 63 | self.labels = labels 64 | 65 | ParamList = TypeList 66 | 67 | class ModeType(Type): 68 | '''ModeType Type subclass maintaining module type Parameters.''' 69 | cls = Mode 70 | 71 | ModeList = TypeList 72 | 73 | class PageType(object): 74 | '''PageType class maintaining page where module type resides.''' 75 | def __init__(self, name, index): 76 | self.name = name 77 | self.index = index 78 | 79 | class ModuleType(Struct): 80 | '''ModuleType class maintaining a module type with 81 | inputs/outputs/parameters/modes.''' 82 | cls = Module 83 | 84 | -------------------------------------------------------------------------------- /tests/testinout.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 392 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 1 0 0 8 | 2 63 1 0 9 | 3 65 2 0 10 | 4 2 0 7 11 | 5 5 2 6 12 | 6 4 0 10 13 | 7 3 0 3 14 | 8 67 1 8 15 | 9 3 1 4 16 | 10 3 1 11 17 | 11 3 2 2 18 | 12 5 2 10 19 | 13 5 2 14 20 | 14 5 2 18 21 | 15 5 2 22 22 | 16 5 2 26 23 | 17 100 0 14 24 | 18 3 0 18 25 | 20 4 1 15 26 | [/ModuleDump] 27 | [ModuleDump] 28 | 0 29 | 1 127 0 0 30 | 2 4 0 2 31 | [/ModuleDump] 32 | [CurrentNoteDump] 33 | 64 0 0 64 0 0 34 | [/CurrentNoteDump] 35 | [CableDump] 36 | 1 37 | 1 7 0 0 1 0 1 38 | 1 17 0 0 7 0 0 39 | 2 7 1 0 1 1 1 40 | 2 17 1 0 7 1 0 41 | 1 7 2 0 1 2 1 42 | 1 17 2 0 7 2 0 43 | 1 7 3 0 1 3 1 44 | 0 6 0 0 4 0 1 45 | 0 20 0 0 6 0 0 46 | 0 6 1 0 4 1 1 47 | 0 20 1 0 6 1 0 48 | 1 9 0 0 2 0 1 49 | 2 9 1 0 2 1 1 50 | 1 9 2 0 2 2 1 51 | 1 9 3 0 2 3 1 52 | 2 10 0 0 8 0 1 53 | 1 10 1 0 8 1 1 54 | 1 10 2 0 8 2 1 55 | 2 11 0 0 3 0 1 56 | 2 11 1 0 3 1 1 57 | 2 11 2 0 3 2 1 58 | 2 5 0 0 11 2 0 59 | 2 12 0 0 5 0 0 60 | 2 13 0 0 12 0 0 61 | 2 14 0 0 13 0 0 62 | 2 15 0 0 14 0 0 63 | 2 16 0 0 15 0 0 64 | 1 18 2 0 17 2 1 65 | 2 18 1 0 17 1 1 66 | 1 18 0 0 17 0 1 67 | [/CableDump] 68 | [CableDump] 69 | 0 70 | 0 2 0 0 1 0 1 71 | 0 2 1 0 1 1 1 72 | [/CableDump] 73 | [ParameterDump] 74 | 1 75 | 5 5 3 115 0 0 76 | 6 4 3 115 1 0 77 | 7 3 1 115 78 | 8 67 1 60 79 | 9 3 1 115 80 | 10 3 1 115 81 | 11 3 1 115 82 | 12 5 3 115 1 0 83 | 13 5 3 115 2 0 84 | 14 5 3 115 3 0 85 | 15 5 3 115 4 0 86 | 16 5 3 115 5 0 87 | 17 100 2 89 34 88 | 18 3 1 115 89 | 20 4 3 115 0 0 90 | [/ParameterDump] 91 | [ParameterDump] 92 | 0 93 | 1 127 1 0 94 | 2 4 3 115 0 0 95 | [/ParameterDump] 96 | [KnobMapDump] 97 | 0 1 0 7 98 | 0 2 1 8 99 | 0 2 2 9 100 | 1 5 1 5 101 | 1 5 2 6 102 | 1 6 1 0 103 | 1 6 2 1 104 | 1 8 0 4 105 | 1 17 0 3 106 | 1 17 1 2 107 | [/KnobMapDump] 108 | [CustomDump] 109 | 1 110 | [/CustomDump] 111 | [CustomDump] 112 | 0 113 | [/CustomDump] 114 | [NameDump] 115 | 1 116 | 1 Keyboard1 117 | 2 KbdPatch1 118 | 3 MIDIGlobal1 119 | 4 AudioIn1 120 | 5 1 output1 121 | 6 2 outputs1 122 | 7 4 outputs1 123 | 8 NoteDetect1 124 | 9 4 outputs2 125 | 10 4 outputs3 126 | 11 4 outputs4 127 | 12 1 output2 128 | 13 1 output3 129 | 14 1 output4 130 | 15 1 output5 131 | 16 1 output6 132 | 17 KeybSplit1 133 | 18 4 outputs5 134 | 20 2 outputs2 135 | [/NameDump] 136 | [NameDump] 137 | 0 138 | 1 PolyAreaIn1 139 | 2 2 outputs1 140 | [/NameDump] 141 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | g2ools - Nord Modular G2 Tools 3 | 4 | Description: 5 | 6 | g2ools is a set of python applications and libraries to handle the Nord 7 | Modular G2 synthesizer. It allows a person to write simple tools to process 8 | G2 .pch2 patch files as well as .prf2 performance files. Python was chosen 9 | because of the authors knowledge of the langauge and portability. The main 10 | application written was nm2g2 Nord Modular (nm1) to G2 patch converter. The 11 | first version took 3 weeks from start to finish. After the initial release, 12 | 3phase provided main models of the various modules available within the nm1 13 | as they are quite different or missing from the Nord Modular G2. It works 14 | on many patches, but there are patches that will not work after the converted 15 | patch is loaded into the G2. 3phase and I have made every attempt to do the 16 | best convertion possible. 17 | 18 | This software is released under the GPL licence and comes complete with 19 | source code to the applications and libraries. 20 | 21 | nm2g2.py 22 | 23 | nm2g2.py is a converter from Clavia's original Nord Modular (nm1) patch file 24 | to the Nord Modular G2 (g2) patch file. It can convert whole directories and 25 | currently is used to converter the Nord Modular Patch Collection consisting 26 | of almost 30000 patches. Many patches work and some do not. You're success 27 | will vary depending on the complexity of the original patch and the 28 | differences between the two synthesizers. 29 | 30 | dx2g2.py 31 | 32 | dx2g2.py converts DX7 syx files into G2 patch files containing 8 DX7 patches 33 | each. The operators are converted exactly as the G2 contains 2 modules: 34 | DXRouter and Operator. The is extra circuitry for the LFO, PitchEG and 35 | transpose. The LFO and PitchEG are modeled as closely as possible (and may 36 | get better) but there are differences. The LFO rates are different between 37 | the DX7 and G2 so the closests match is used. The PitchEG rate parameter 38 | is constant reguardless of the levels used. This requires determining a 39 | normalized time for the rate and caculating the actual time to go from one 40 | level to the next. Then the G2's envelope time is set to the closest match. 41 | 42 | Installation: 43 | 44 | Installation is a matter of decompressing the zip file into it's directory 45 | structure stored in the zip file. 46 | 47 | Linux: 48 | 49 | The application requires python version 2.4 or higher to be installed. Most 50 | of the lastest distributions will have it. 51 | 52 | Mac OS-X: 53 | 54 | To run under Mac OS-X, python version 2.4 or higher must be installed. Goto 55 | http://www.python.org 56 | 57 | Windows: 58 | 59 | There is a nm2g2.exe and dx2g2.exe that should run on any Windows XP machine 60 | without the need to install python. 61 | 62 | Running: 63 | 64 | Because the programs require the python modules stored in the /nord 65 | directory and the initial patches stored in the / directory, the 66 | converters must be run within the directory. This may be fixed in a future 67 | release but currently this is how it works. 68 | 69 | -------------------------------------------------------------------------------- /units.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright: Matt Gerassimoff 2007 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | from nord import printf 23 | from Numeric import * 24 | 25 | def ts(x,ty): 26 | return (1-exp(x*ty))/(1-exp(ty)) 27 | 28 | x = array(range(0,127,8)+[127],typecode=Float) 29 | 30 | printf('Nord Modular G2 Units\n\n') 31 | printf('ts(x,ty) = (1-exp(x*ty))/(1-exp(ty))\n') 32 | printf('Lfo Rate Lo: ') 33 | printf('y[0]+y[-1]*ts(x[i]/127.,7.337)\n') 34 | ylo = array([1/62.9,1/39.6,1/25.0,1/15.7,0.10,0.16,0.25,0.40, 35 | 0.64,1.02,1.62,2.56,4.07,6.46,10.3,16.3,24.4],typecode=Float) 36 | y = ylo 37 | for i in range(len(x)): 38 | cy = y[0]+y[-1]*ts(x[i]/127.,7.337) # 7.34 39 | cy = int(cy*100)/100. 40 | if y[i] < 10.0: 41 | printf('%3d %4.2f %4.2f\n', x[i], y[i], cy) 42 | else: 43 | printf('%3d %4.1f %4.1f\n', x[i], y[i], cy) 44 | 45 | printf('\nLfo Rate Hi ') 46 | printf('y[0]+y[-1]*ts(x[i]/127.,7.337)\n') 47 | yhi = array([0.26,0.41,0.64,1.02,1.62,2.58,4.09,6.49,10.3,16.4, 48 | 26.0,41.2,65.4,104,165,262,392],typecode=Float) 49 | y = yhi 50 | for i in range(len(x)): 51 | cy = y[0]+y[-1]*ts(x[i]/127.,7.337) # 7.34 52 | cy = int(cy*100)/100. 53 | if y[i] < 10.0: 54 | printf('%3d %4.2f %4.2f %10.6f\n', x[i], y[i], cy, cy) 55 | elif y[i] < 100.0: 56 | printf('%3d %4.1f %4.1f %10.6f\n', x[i], y[i], cy, cy) 57 | else: 58 | printf('%3d %4.0f %4.0f %10.6f\n', x[i], y[i], cy, cy) 59 | 60 | printf('\nBPM 20 to 240\n\n') 61 | printf('Lfo Rate Sub ') 62 | printf('1/(x[i]*(1/y[-1]-1/y[0])/127.+1/y[0])\n') 63 | ysub = array([699,77.7,41.1,28.0,21.2,17.1,14.3,12.3,10.8, 64 | 9.58, 8.63,7.85,7.21,6.66,6.19,5.78,5.46],typecode=Float) 65 | y = ysub 66 | iy = 1/y 67 | for i in range(len(x)): 68 | cy = x[i]*(iy[-1]-iy[0])/127.+iy[0] 69 | cy = 1/cy 70 | #cy = int(cy*100+0.5)/100. 71 | if y[i] < 10.0: 72 | printf('%3d %4.2f %4.2f %10.6f\n', x[i], y[i], cy, cy) 73 | elif y[i] < 100.0: 74 | printf('%3d %4.1f %4.1f %10.6f\n', x[i], y[i], cy, cy) 75 | else: 76 | printf('%3d %4.0f %4.0f %10.6f\n', x[i], y[i], cy, cy) 77 | 78 | printf('\nEnv ADSR Time\n') 79 | ytim = array([0.0005,0.0021,0.0073,0.0212,0.0543,0.126,0.269,0.540,1.02, 80 | 1.85,3.21,5.37,8.72,13.8,21.2,32.0,45.0],typecode=Float) 81 | y = ytim 82 | for i in range(len(x)): 83 | cy = y[0]+y[-1]*ts(x[i]/127.,7.337) # 7.34 84 | if y[i] < 1.0: 85 | cym = cy*1000. 86 | ym = y[i]*1000. 87 | printf('%3d %4.2fm %4.2fm %10.6fm\n', x[i], ym, cym, cym) 88 | elif y[i] < 10.0: 89 | printf('%3d %4.2fs %4.2fs %10.6fs\n', x[i], y[i], cy, cy) 90 | else: 91 | printf('%3d %4.1fs %4.1fs %10.6fs\n', x[i], y[i], cy, cy) 92 | 93 | -------------------------------------------------------------------------------- /nm2g2g.ui: -------------------------------------------------------------------------------- 1 | 2 | NM2G2G 3 | 4 | 5 | 6 | 0 7 | 0 8 | 658 9 | 589 10 | 11 | 12 | 13 | NM2G2G NM1 To G2 Converter 14 | 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | 36 | 0 37 | 0 38 | 39 | 40 | 41 | Qt::Vertical 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 0 53 | 0 54 | 658 55 | 35 56 | 57 | 58 | 59 | 60 | &File 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | toolBar 73 | 74 | 75 | Qt::NoToolBarArea|Qt::RightToolBarArea|Qt::TopToolBarArea 76 | 77 | 78 | TopToolBarArea 79 | 80 | 81 | false 82 | 83 | 84 | 85 | 86 | 87 | 88 | &Quit 89 | 90 | 91 | Ctrl+Q 92 | 93 | 94 | 95 | 96 | &Run 97 | 98 | 99 | Ctrl+R 100 | 101 | 102 | 103 | 104 | &Stop 105 | 106 | 107 | 108 | 109 | 110 | 111 | action_Quit 112 | activated() 113 | NM2G2G 114 | close() 115 | 116 | 117 | -1 118 | -1 119 | 120 | 121 | 328 122 | 294 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /pch2cmp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import os, sys, traceback 4 | from nord import printf 5 | from nord.g2.file import Pch2File 6 | 7 | def compare_shortnm(a, b): 8 | x = cmp(a.module.type.shortnm, b.module.type.shortnm) 9 | if x: return x 10 | return cmp(a.type.name, b.type.name) 11 | 12 | def compare_ports(aport, bport): 13 | if not aport and bport: return 1 14 | if aport and not bport: return -1 15 | return 0 16 | 17 | def get_nets(pch2): 18 | # sort each net's inputs by mod-name/port-name 19 | nets = [ n for n in pch2.patch.voice.netlist.nets if n.output ] 20 | for net in nets: 21 | #ins = net.inputs[:] 22 | net.inputs.sort(compare_shortnm) 23 | 24 | def ordernets(a, b): 25 | x = compare_shortnm(a.output, b.output) 26 | if x: return x 27 | x = cmp(len(a.inputs), len(b.inputs)) 28 | if x: return x 29 | for i in range(len(a.inputs)): 30 | x = compare_shortnm(a.inputs[i], b.inputs[i]) 31 | if x: return x 32 | return 0 33 | 34 | nets.sort(ordernets) 35 | 36 | def check_ports(modmap, aport, bport): 37 | x = compare_ports(aport, bport) 38 | if x: return x 39 | x = compare_shortnm(aport, bport) 40 | if x: return x 41 | # if index of aport.module not seen, create a new mapping to bport.module 42 | aidx, bidx = aport.module.index, bport.module.index 43 | if modmap.has_key(aidx): 44 | return cmp(modmap[aidx], bidx) 45 | modmap[aidx] = bidx 46 | return 0 # only have one to check against, have to assume it's correct. 47 | 48 | def check_net(modmap, anet, bnet): 49 | # output module/port must match 50 | if anet.output == None: 51 | return -1 52 | if bnet.output == None: 53 | return 1 54 | x = check_ports(modmap, anet.output, bnet.output) 55 | if x: return x 56 | # length of netlist must match 57 | x = cmp(len(anet.inputs),len(bnet.inputs)) 58 | if x: return x 59 | # all inputs must match 60 | for ain, bin in zip(anet.inputs, bnet.inputs): 61 | x = check_ports(modmap, ain, bin) 62 | if x: return x 63 | return 0 64 | 65 | def compare_netlist(a, b): 66 | x = cmp(len(a.nets), len(b.nets)) 67 | if x: return x 68 | modmap = {} 69 | for anet, bnet in zip(a.nets, b.nets): 70 | x = check_net(modmap, anet, bnet) 71 | if x: return x 72 | return 0 73 | 74 | def matchingnets(a, b): 75 | modmap = {} 76 | matches = 0 77 | for anet in a.nets: 78 | for bnet in b.nets: 79 | if check_net(modmap, anet, bnet) == 0: 80 | match += 1 81 | return matches 82 | 83 | filenames = [ f for f in sys.argv[1:] if f[-4:] == 'pch2' ] 84 | filenames.sort() 85 | pch2s = [] 86 | for filename in filenames: 87 | printf('%s\n', os.path.basename(filename)) 88 | p = Pch2File(filename) 89 | get_nets(p) 90 | pch2s.append(p) 91 | 92 | def bynetsize(a, b): 93 | return cmp(len(a.patch.voice.netlist.nets), len(b.patch.voice.netlist.nets)) 94 | pch2s.sort(bynetsize) 95 | 96 | p = {} 97 | for pch2 in pch2s: 98 | k = len(pch2.patch.voice.netlist.nets) 99 | d = p.get(k, None) 100 | if not d: 101 | d = p[k] = [] 102 | d.append(pch2) 103 | 104 | for k in p.keys(): 105 | a = p[k] 106 | printf('net size %s:\n', k) 107 | while len(a): 108 | b = a.pop(0) 109 | matches = [b] 110 | j = 0 111 | while j < len(a): 112 | try: 113 | if compare_netlist(b.patch.voice.netlist,a[j].patch.voice.netlist) == 0: 114 | matches.append(a.pop(j)) 115 | else: 116 | j += 1 117 | except: 118 | raise Exception('%s\n patches: %s %s' % ( 119 | traceback.format_exc(), 120 | os.path.basename(b.filename), os.path.basename(a[j].filename))) 121 | 122 | if len(matches) == 1: 123 | continue 124 | printf(' matches:\n') 125 | for match in matches: 126 | filename = os.path.basename(match.filename) 127 | printf(' %s\n', filename) 128 | 129 | -------------------------------------------------------------------------------- /nord/g2/crc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | def crc16(val, icrc): 23 | '''crc16(val, ircr) - calculate crc of 1 char.''' 24 | k = (((icrc>>8)^val)&0xff)<<8 25 | crc_ = 0 26 | for bits in xrange(8): 27 | if (crc_^k)&0x8000 != 0: 28 | crc_ = (crc_<<1)^0x1021 29 | else: 30 | crc_ <<= 1 31 | k <<= 1 32 | return (icrc<<8)^crc_ 33 | 34 | def crc(s): 35 | '''crc(s) - calculate crc of whole string.''' 36 | return reduce(lambda a, b: crc16(ord(b), a), s, 0) & 0xffff 37 | 38 | # calculated via: 39 | # ./pycrc.py --model zmodem --algorithm table-driven --table-idx-width 8 \ 40 | # --generate c -o crc.c 41 | crctab = [ 42 | 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 43 | 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 44 | 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 45 | 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 46 | 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 47 | 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 48 | 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 49 | 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 50 | 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 51 | 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 52 | 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 53 | 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 54 | 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 55 | 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 56 | 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 57 | 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 58 | 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 59 | 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 60 | 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 61 | 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 62 | 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 63 | 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 64 | 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 65 | 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 66 | 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 67 | 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 68 | 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 69 | 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 70 | 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 71 | 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 72 | 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 73 | 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 74 | ] 75 | 76 | def crc_(s): 77 | '''crc(s) - calculate crc of whole string fast.''' 78 | return reduce(lambda crc, c: 79 | (crctab[((crc>>8)^ord(c))&0xff]^(crc << 8)), s, 0)&0xffff 80 | 81 | try: 82 | from nord.g2._bits import crc 83 | except: 84 | crc = crc_ 85 | 86 | -------------------------------------------------------------------------------- /tests/testosc.pch: -------------------------------------------------------------------------------- 1 | [Header] 2 | Version=Nord Modular patch 3.0 3 | 0 127 0 127 2 0 0 1 606 2 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | [/Header] 5 | [ModuleDump] 6 | 1 7 | 1 43 1 0 8 | 4 2 0 0 9 | 3 7 0 3 10 | 2 7 0 10 11 | 5 7 0 17 12 | 7 8 1 3 13 | 8 8 1 10 14 | 9 8 1 17 15 | 11 9 2 0 16 | 13 14 2 5 17 | 14 10 2 10 18 | 15 40 3 23 19 | 6 40 1 29 20 | 10 11 2 14 21 | 12 12 2 18 22 | 16 85 2 26 23 | 17 31 2 30 24 | 18 95 3 0 25 | 19 58 3 5 26 | 20 13 2 22 27 | 21 96 1 24 28 | 22 7 0 24 29 | [/ModuleDump] 30 | [ModuleDump] 31 | 0 32 | [/ModuleDump] 33 | [CurrentNoteDump] 34 | 64 0 0 64 0 0 35 | [/CurrentNoteDump] 36 | [CableDump] 37 | 1 38 | 0 3 2 0 4 0 1 39 | 0 2 3 0 3 2 0 40 | 0 5 2 0 2 3 0 41 | 0 22 2 0 5 2 0 42 | 0 7 1 0 4 0 1 43 | 0 8 2 0 7 1 0 44 | 0 9 1 0 8 2 0 45 | 0 21 1 0 9 1 0 46 | 0 3 3 0 4 1 1 47 | 0 2 1 0 3 3 0 48 | 0 5 1 0 2 1 0 49 | 0 22 1 0 5 1 0 50 | 0 22 0 0 22 1 0 51 | 0 5 0 0 22 0 0 52 | 0 3 4 0 5 0 0 53 | 0 3 0 0 3 4 0 54 | 0 7 2 0 4 1 1 55 | 0 8 1 0 7 2 0 56 | 0 9 2 0 8 1 0 57 | 0 21 0 0 9 2 0 58 | 0 11 1 0 7 2 0 59 | 0 13 3 0 11 1 0 60 | 0 13 1 0 13 3 0 61 | 0 14 1 0 13 1 0 62 | 0 12 1 0 14 1 0 63 | 0 20 2 0 12 1 0 64 | 0 16 1 0 20 2 0 65 | 1 3 1 0 1 0 1 66 | 1 2 0 0 3 1 0 67 | 1 5 4 0 2 0 0 68 | 1 22 4 0 5 4 0 69 | 1 7 3 0 1 0 1 70 | 1 7 0 0 7 3 0 71 | 1 8 3 0 7 0 0 72 | 1 8 0 0 8 3 0 73 | 1 9 3 0 8 0 0 74 | 1 9 0 0 9 3 0 75 | 1 11 0 0 7 3 0 76 | 1 10 1 0 11 0 0 77 | 1 20 1 0 10 1 0 78 | 1 16 2 0 20 1 0 79 | 1 11 2 0 11 0 0 80 | 1 13 2 0 11 2 0 81 | 1 18 1 0 13 2 0 82 | 1 19 0 0 1 0 1 83 | 1 19 1 0 19 0 0 84 | 1 19 2 0 19 1 0 85 | 0 6 0 0 3 0 1 86 | 0 6 1 0 2 0 1 87 | 0 6 2 0 5 0 1 88 | 0 6 3 0 7 0 1 89 | 0 6 4 0 8 0 1 90 | 0 6 5 0 9 0 1 91 | 0 18 0 0 11 0 1 92 | 0 6 7 0 13 0 1 93 | 0 15 0 0 14 0 1 94 | 0 15 1 0 10 0 1 95 | 0 15 2 0 12 0 1 96 | 0 15 3 0 16 0 1 97 | 0 15 7 0 19 0 1 98 | 0 15 6 0 18 0 1 99 | 0 15 5 0 17 0 1 100 | 0 15 4 0 20 0 1 101 | 0 6 6 0 21 0 1 102 | 3 13 0 0 11 1 1 103 | 3 14 0 0 13 0 0 104 | 3 10 0 0 14 0 0 105 | 3 12 0 0 10 0 0 106 | 3 20 0 0 12 0 0 107 | 3 16 0 0 20 0 0 108 | [/CableDump] 109 | [CableDump] 110 | 0 111 | [/CableDump] 112 | [ParameterDump] 113 | 1 114 | 1 43 2 64 0 115 | 2 7 10 64 64 0 89 3 0 0 0 0 0 116 | 3 7 10 66 64 64 35 3 0 0 68 53 0 117 | 5 7 10 64 64 64 64 3 0 0 0 44 0 118 | 6 40 9 100 100 100 100 100 100 100 100 0 119 | 7 8 9 64 64 64 3 0 0 0 66 0 120 | 8 8 9 64 64 64 2 0 0 0 54 0 121 | 9 8 9 64 64 64 1 0 0 0 0 0 122 | 10 11 4 64 64 0 0 123 | 11 9 6 64 64 1 0 0 0 124 | 12 12 4 64 64 0 0 125 | 13 14 5 127 64 2 0 0 126 | 14 10 5 64 64 91 55 0 127 | 15 40 9 100 100 100 100 100 100 100 100 0 128 | 16 85 5 0 64 1 0 0 129 | 17 31 1 0 130 | 18 95 7 64 64 64 0 0 64 0 131 | 19 58 16 42 15 67 71 120 102 57 32 39 70 1 68 82 79 115 0 132 | 20 13 4 64 64 0 0 133 | 21 96 7 64 64 1 0 0 65 67 134 | 22 7 10 64 64 92 64 0 0 0 0 0 0 135 | [/ParameterDump] 136 | [ParameterDump] 137 | 0 138 | [/ParameterDump] 139 | [KnobMapDump] 140 | 1 3 0 0 141 | 1 3 1 1 142 | [/KnobMapDump] 143 | [CustomDump] 144 | 1 145 | 2 1 1 146 | 3 1 0 147 | 5 1 0 148 | 7 1 0 149 | 8 1 0 150 | 9 1 0 151 | 10 1 2 152 | 11 1 0 153 | 12 1 0 154 | 13 1 0 155 | 14 1 1 156 | 16 1 2 157 | 18 1 0 158 | 20 1 0 159 | 21 1 0 160 | 22 1 0 161 | [/CustomDump] 162 | [CustomDump] 163 | 0 164 | [/CustomDump] 165 | [NameDump] 166 | 1 167 | 1 Constant1 168 | 2 OscA2 169 | 3 OscA1 170 | 4 AudioIn1 171 | 5 OscA3 172 | 6 Mixer1 173 | 7 OscB1 174 | 8 OscB2 175 | 9 OscB3 176 | 10 OscSlvC1 177 | 11 OscC1 178 | 12 OscSlvD1 179 | 13 OscSlvA1 180 | 14 OscSlvB1 181 | 15 Mixer4 182 | 16 OscSlvFM1 183 | 17 Noise1 184 | 18 PercOsc1 185 | 19 DrumSynth1 186 | 20 OscSlvE1 187 | 21 FormantOsc1 188 | 22 OscA4 189 | [/NameDump] 190 | [NameDump] 191 | 0 192 | [/NameDump] 193 | -------------------------------------------------------------------------------- /nmcat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import sys 23 | sys.path.append('.') 24 | from nord import printf 25 | from nord.nm1.file import PchFile, NM1Error 26 | 27 | def printpatch(patch): 28 | for areanm in ['voice','fx']: 29 | area = getattr(patch, areanm) 30 | printf('%s:\n', areanm) 31 | 32 | printf(' modules:\n') 33 | for module in area.modules: 34 | mtype = module.type 35 | printf(' %s: %d "%s" (%d,%d)\n', mtype.shortnm, 36 | module.index, module.name, module.horiz, module.vert) 37 | 38 | for param in range(len(mtype.params)): 39 | printf(' %s(%d): %d\n', mtype.params[param].name, 40 | param, module.params[param].variations[0]) 41 | 42 | for mode in range(len(mtype.modes)): 43 | printf(' >%s(%d): %d\n', mtype.modes[mode].name, 44 | mode, module.modes[mode].value) 45 | 46 | printf(' cables:\n') 47 | for cable in area.cables: 48 | source,dest = cable.source,cable.dest 49 | smod,dmod = source.module,dest.module 50 | stype,dtype = smod.type, dmod.type 51 | #c = cable 52 | #printf('%d %d %d %d %d %d %d\n', c.color,c.dest.index,c.dest.conn,c.dest.type, 53 | # c.source.index,c.source.conn,c.source.type) 54 | printf(' %s.%s - %s.%s: c=%d\n', smod.name, source.type.name, 55 | dmod.name, dest.type.name, cable.color) 56 | 57 | printf(' nets:\n') 58 | for net in area.netlist.nets: 59 | source = net.output 60 | if source: 61 | smod = area.find_module(source.module.index) 62 | s = '%s.%s' % (smod.name, source.type.name) 63 | else: 64 | s = 'nosrc' 65 | t = [] 66 | for dest in net.inputs: 67 | dmod = area.find_module(dest.module.index) 68 | dtype = dmod.type 69 | t.append('%s.%s' % (dmod.name, dest.type.name)) 70 | printf(' %s -> %s\n', s, ','.join(t)) 71 | 72 | printf('knobs:\n') 73 | for knob in patch.knobs: 74 | if hasattr(knob.param,'module'): 75 | printf(' %02d: %s:%s\n', knob.knob,knob.param.module.name,knob.param.type.name) 76 | else: 77 | printf(' %02d: morph %d\n', knob.knob,knob.param.index) 78 | 79 | printf('ctrls:\n') 80 | for ctrl in patch.ctrls: 81 | if hasattr(ctrl.param,'module'): 82 | printf(' %02d: %s:%s\n', ctrl.midicc,ctrl.param.module.name,ctrl.param.type.name) 83 | else: 84 | printf(' %02d: morph %d\n', ctrl.midicc,ctrl.param.index) 85 | 86 | printf('morphs:\n') 87 | for morph in patch.morphs: 88 | if morph.knob: 89 | knob = morph.knob.knob 90 | else: 91 | knob = 0 92 | printf(' %d: %d %s\n', morph.index, knob, 93 | ['none','vel','note'][morph.keyassign]) 94 | for map in morph.maps: 95 | printf(' %s:%s range %d\n', map.param.module.name,map.param.type.name, 96 | map.range) 97 | 98 | prog = sys.argv.pop(0) 99 | while len(sys.argv): 100 | filename = sys.argv.pop(0) 101 | printf('"%s"\n', filename) 102 | try: 103 | pch = PchFile(filename) 104 | printpatch(pch.patch) 105 | except NM1Error, s: 106 | printf('%s: NM1Error %s\n', filename, s) 107 | sys.exit(1) 108 | 109 | -------------------------------------------------------------------------------- /nord/convert/logic.py: -------------------------------------------------------------------------------- 1 | # 2 | # logic.py - Logic tab conversion objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord.utils import setv, getv 23 | from nord.convert import Convert 24 | from nord.convert.table import logicdel 25 | from nord.g2.colors import g2conncolors 26 | 27 | class ConvPosEdgeDly(Convert): 28 | maing2module = 'Delay' 29 | parammap = ['Time'] 30 | inputmap = ['In'] 31 | outputmap = ['Out'] 32 | mode = 0 33 | 34 | def domodule(self): 35 | nmm, g2m = self.nmmodule, self.g2module 36 | nmmp, g2mp = nmm.params, g2m.params 37 | setv(g2mp.Range, 1) # Lo 38 | setv(g2mp.Time, logicdel[getv(nmmp.Time)]) 39 | g2m.modes.Mode.value = self.mode 40 | 41 | class ConvNegEdgeDly(ConvPosEdgeDly): 42 | mode = 1 43 | 44 | class ConvPulse(ConvPosEdgeDly): 45 | maing2module = 'Pulse' 46 | inputmap = ['In'] 47 | outputmap = ['Out'] 48 | mode = 0 49 | 50 | class ConvLogicDelay(ConvPosEdgeDly): 51 | mode = 2 52 | 53 | class ConvLogicInv(Convert): 54 | maing2module = 'Invert' 55 | inputmap = ['In2'] 56 | outputmap = ['Out2'] 57 | 58 | class ConvLogicProc(Convert): 59 | maing2module = 'Gate' 60 | parammap = [None] 61 | inputmap = ['In2_1', 'In2_2'] 62 | outputmap = ['Out2'] 63 | 64 | def domodule(self): 65 | nmm, g2m = self.nmmodule, self.g2module 66 | nmmp, g2mp = nmm.params, g2m.params 67 | 68 | g2m.modes.GateMode2.value = [0, 2, 4][getv(nmmp.Mode)] 69 | 70 | class ConvCompareLev(Convert): 71 | maing2module = 'CompLev' 72 | parammap = [['C', 'Level']] 73 | inputmap = ['In'] 74 | outputmap = ['Out'] 75 | 76 | def domodule(self): 77 | self.g2module.inputs.In.rate = g2conncolors.blue 78 | 79 | class ConvCompareAB(Convert): 80 | maing2module = 'CompSig' 81 | inputmap = ['A', 'B'] 82 | outputmap = ['Out'] 83 | 84 | def domodule(self): 85 | self.g2module.inputs.A.rate = g2conncolors.blue 86 | self.g2module.inputs.B.rate = g2conncolors.blue 87 | 88 | class ConvClkDiv(Convert): 89 | maing2module = 'ClkDiv' 90 | parammap = ['Divider'] 91 | inputmap = ['Clk', 'Rst'] 92 | outputmap = ['Out', '', ''] 93 | 94 | def domodule(self): 95 | nmm, g2m = self.nmmodule, self.g2module 96 | nmmp, g2mp = nmm.params, g2m.params 97 | 98 | g2m.modes.DivMode.value = 1 99 | 100 | class ConvClkDivFix(Convert): 101 | maing2module = 'ClkDiv' 102 | inputmap = ['Clk', 'Rst'] 103 | outputmap = ['', '', ''] # 16, T8, 8 104 | 105 | def domodule(self): 106 | nmm, g2m = self.nmmodule, self.g2module 107 | nmmp, g2mp = nmm.params, g2m.params 108 | 109 | oclks = [[5, '16', 0], [7, 'T8', 1], [11, '8', 2]] 110 | clks = oclks[:] 111 | while len(clks): 112 | clk = clks.pop(0) 113 | if len(getattr(nmm.outputs, clk[1]).cables) != 0: 114 | break 115 | if len(clks) == 0: 116 | clk = oclks[0] 117 | 118 | g2m.modes.DivMode.value = 1 119 | setv(g2mp.Divider, clk[0]) 120 | g2m.name = clk[1] 121 | self.outputs[clk[2]] = g2m.outputs.Out 122 | 123 | rst, midiclk = g2m.inputs.Rst, g2m.inputs.Clk 124 | for div, nm, out in clks: 125 | if len(getattr(nmm.outputs, nm).cables) == 0: 126 | continue 127 | clk = self.add_module('ClkDiv', name=nm) 128 | clk.modes.DivMode.value = 1 129 | setv(clk.params.Divider, div) 130 | self.connect(rst, clk.inputs.Rst) 131 | self.connect(midiclk, clk.inputs.Clk) 132 | rst, midiclk = clk.inputs.Rst, clk.inputs.Clk 133 | self.outputs[out] = clk.outputs.Out 134 | 135 | -------------------------------------------------------------------------------- /nord/g2/bits.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import struct 23 | from array import array 24 | 25 | # number format for getbits() and setbits() 26 | # b b b b 27 | # 0 1 2 3 28 | # 01234567012345670123456701234567 29 | # m lm lm lm l 30 | # b: byte 31 | # m: msb 32 | # l: lsb 33 | 34 | def getbits(bit, nbits, data, signed=0): 35 | '''getbits(bit, nbits, data, signed=0) - return int as subset of string data. 36 | the values are formatted in big-endiann: 37 | 0 is msb, 31 is lsb for a 32-bit word. 38 | ''' 39 | 40 | def getbits_(x, p, n): 41 | return (x >> p) & ~(~0<> 3 44 | # align size to a 32-bit word 45 | long_ = struct.unpack('>L', (str(data[byte:byte+4])+'\x00'*4)[:4])[0] 46 | val = getbits_(long_, 32-(bit&7)-nbits, nbits) 47 | if signed and (val>>(nbits-1)): 48 | val |= ~0 << nbits 49 | return bit+nbits, int(val) 50 | 51 | def setbits(bit, nbits, data, value): 52 | '''setbits(bit, nbits, data, value) - set bits in subset 53 | of string data from int. 54 | ''' 55 | def setbits_(x, p, n, y): 56 | m = ~(~0<> 3 60 | last = (bit+nbits+7)>>3 61 | s = data[byte:byte+4].tostring() 62 | # align size to a 32-bit word 63 | long_ = setbits_(struct.unpack('>L', s)[0], 32-(bit&7)-nbits, nbits, value) 64 | # readjust array to fit (bits+nbits)/8 bytes 65 | a = array('B', struct.pack('>L', long_)[:last-byte]) 66 | #printf('bit=%d nbits=%d byte=%d last=%d last-byte+1=%d len=%d len(a)=%d\n', 67 | # bit, nbits, byte, last, last-byte, len(data), len(a)) 68 | data[byte:last] = a 69 | #printf('%s\n', data) 70 | return bit+nbits 71 | 72 | class BitStream(object): 73 | def __init__(self, data, bit=0): 74 | self.data = data 75 | self.bit = bit 76 | 77 | def setup(self, bit=0, data=None): 78 | self.bit = bit 79 | if data: 80 | self.data = data 81 | 82 | def read_bits(self, nbits): 83 | self.bit, value = getbits(self.bit, nbits, self.data) 84 | return value 85 | 86 | def read_bitsa(self, nbitsa): 87 | return [ self.read_bits(nbits) for nbits in nbitsa ] 88 | 89 | def read_bytes(self, nbytes): 90 | return [ self.read_bits(8) for byte in xrange(nbytes) ] 91 | 92 | def read_str(self, nbytes): 93 | s = bytearray(nbytes) 94 | for byte in xrange(nbytes): 95 | s[byte] = self.read_bits(8) 96 | return str(s) 97 | 98 | def seek_bit(self, bit, where=0): 99 | if where == 0: 100 | self.bit = bit 101 | elif where == 1: 102 | self.bit += bit 103 | elif where == 2: 104 | self.bit = len(self.data) * 8 - bit 105 | 106 | def tell_bit(self): 107 | return self.bit 108 | 109 | def write_bits(self, nbits, value): 110 | self.bit = setbits(self.bit, nbits, self.data, value) 111 | 112 | def write_bitsa(self, nbitsa, values): 113 | for nbits, value in zip(nbitsa, values): 114 | self.write_bits(nbits, value) 115 | 116 | def write_bytes(self, bytes): 117 | for byte in bytes: 118 | self.write_bits(8, byte) 119 | 120 | def write_str(self, str): 121 | for c in str: 122 | self.write_bits(8, ord(c)) 123 | 124 | def string(self): 125 | return str(self.data[:(self.bit+7)>>3]) 126 | 127 | try: 128 | from nord.g2._bits import setbits, getbits, BitStream 129 | except: 130 | pass 131 | 132 | -------------------------------------------------------------------------------- /nm2g2g_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'nm2g2g.ui' 4 | # 5 | # Created: Tue Jan 1 18:39:57 2008 6 | # by: PyQt4 UI code generator 4.3.1 7 | # 8 | # WARNING! All changes made in this file will be lost! 9 | 10 | from PyQt4 import QtCore, QtGui 11 | 12 | class Ui_NM2G2G(object): 13 | def setupUi(self, NM2G2G): 14 | NM2G2G.setObjectName("NM2G2G") 15 | NM2G2G.resize(QtCore.QSize(QtCore.QRect(0,0,658,589).size()).expandedTo(NM2G2G.minimumSizeHint())) 16 | 17 | self.centralwidget = QtGui.QWidget(NM2G2G) 18 | self.centralwidget.setObjectName("centralwidget") 19 | 20 | self.vboxlayout = QtGui.QVBoxLayout(self.centralwidget) 21 | self.vboxlayout.setSpacing(0) 22 | self.vboxlayout.setMargin(0) 23 | self.vboxlayout.setObjectName("vboxlayout") 24 | 25 | self.splitter = QtGui.QSplitter(self.centralwidget) 26 | 27 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred,QtGui.QSizePolicy.Expanding) 28 | sizePolicy.setHorizontalStretch(0) 29 | sizePolicy.setVerticalStretch(0) 30 | sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) 31 | self.splitter.setSizePolicy(sizePolicy) 32 | self.splitter.setOrientation(QtCore.Qt.Vertical) 33 | self.splitter.setObjectName("splitter") 34 | 35 | self.treeView = QtGui.QTreeView(self.splitter) 36 | self.treeView.setObjectName("treeView") 37 | 38 | self.textEdit = QtGui.QTextEdit(self.splitter) 39 | self.textEdit.setObjectName("textEdit") 40 | self.vboxlayout.addWidget(self.splitter) 41 | NM2G2G.setCentralWidget(self.centralwidget) 42 | 43 | self.menubar = QtGui.QMenuBar(NM2G2G) 44 | self.menubar.setGeometry(QtCore.QRect(0,0,658,35)) 45 | self.menubar.setObjectName("menubar") 46 | 47 | self.menu_File = QtGui.QMenu(self.menubar) 48 | self.menu_File.setObjectName("menu_File") 49 | NM2G2G.setMenuBar(self.menubar) 50 | 51 | self.statusbar = QtGui.QStatusBar(NM2G2G) 52 | self.statusbar.setObjectName("statusbar") 53 | NM2G2G.setStatusBar(self.statusbar) 54 | 55 | self.toolBar = QtGui.QToolBar(NM2G2G) 56 | self.toolBar.setAllowedAreas(QtCore.Qt.NoToolBarArea|QtCore.Qt.RightToolBarArea|QtCore.Qt.TopToolBarArea) 57 | self.toolBar.setObjectName("toolBar") 58 | NM2G2G.addToolBar(QtCore.Qt.TopToolBarArea,self.toolBar) 59 | 60 | self.action_Quit = QtGui.QAction(NM2G2G) 61 | self.action_Quit.setObjectName("action_Quit") 62 | 63 | self.action_Run = QtGui.QAction(NM2G2G) 64 | self.action_Run.setObjectName("action_Run") 65 | 66 | self.action_Stop = QtGui.QAction(NM2G2G) 67 | self.action_Stop.setObjectName("action_Stop") 68 | self.menu_File.addAction(self.action_Run) 69 | self.menu_File.addAction(self.action_Stop) 70 | self.menu_File.addSeparator() 71 | self.menu_File.addAction(self.action_Quit) 72 | self.menubar.addAction(self.menu_File.menuAction()) 73 | self.toolBar.addAction(self.action_Run) 74 | self.toolBar.addAction(self.action_Stop) 75 | 76 | self.retranslateUi(NM2G2G) 77 | QtCore.QObject.connect(self.action_Quit,QtCore.SIGNAL("activated()"),NM2G2G.close) 78 | QtCore.QMetaObject.connectSlotsByName(NM2G2G) 79 | 80 | def retranslateUi(self, NM2G2G): 81 | NM2G2G.setWindowTitle(QtGui.QApplication.translate("NM2G2G", "NM2G2G NM1 To G2 Converter", None, QtGui.QApplication.UnicodeUTF8)) 82 | self.menu_File.setTitle(QtGui.QApplication.translate("NM2G2G", "&File", None, QtGui.QApplication.UnicodeUTF8)) 83 | self.toolBar.setWindowTitle(QtGui.QApplication.translate("NM2G2G", "toolBar", None, QtGui.QApplication.UnicodeUTF8)) 84 | self.action_Quit.setText(QtGui.QApplication.translate("NM2G2G", "&Quit", None, QtGui.QApplication.UnicodeUTF8)) 85 | self.action_Quit.setShortcut(QtGui.QApplication.translate("NM2G2G", "Ctrl+Q", None, QtGui.QApplication.UnicodeUTF8)) 86 | self.action_Run.setText(QtGui.QApplication.translate("NM2G2G", "&Run", None, QtGui.QApplication.UnicodeUTF8)) 87 | self.action_Run.setShortcut(QtGui.QApplication.translate("NM2G2G", "Ctrl+R", None, QtGui.QApplication.UnicodeUTF8)) 88 | self.action_Stop.setText(QtGui.QApplication.translate("NM2G2G", "&Stop", None, QtGui.QApplication.UnicodeUTF8)) 89 | 90 | -------------------------------------------------------------------------------- /nord/module.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # module.py - create a module from it's type 4 | # 5 | # Copyright (c) 2006,2007 Matt Gerassimoff 6 | # 7 | # This file is part of g2ools. 8 | # 9 | # g2ools is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # g2ools is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Foobar; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | # 23 | from nord import printf 24 | 25 | class Input(object): 26 | '''Input IOMember subclass''' 27 | __slots__ = ( 'module', 'type', 'index', 'rate', 'cables', 'net', 'conv' ) 28 | direction = 0 29 | def __init__(self, module, type, index): 30 | '''Input(module, type, index) -> Input object''' 31 | self.module = module 32 | self.type = type 33 | self.index = index 34 | self.rate = type.type 35 | self.cables = [] 36 | self.net = None 37 | 38 | class Output(object): 39 | '''Output IOMember subclass''' 40 | __slots__ = ( 'module', 'type', 'index', 'rate', 'cables', 'net', 'conv' ) 41 | direction = 1 42 | def __init__(self, module, type, index): 43 | '''Output(module, type, index) -> Output object''' 44 | self.module = module 45 | self.type = type 46 | self.index = index 47 | self.rate = type.type 48 | self.cables = [] 49 | self.net = None 50 | 51 | class Param(object): 52 | __slots__ = ( 53 | 'module', 'type', 'index', 'variations', 'knob', 'ctrl', 'morph', 'labels' 54 | ) 55 | '''Param class representing dynamic parameters for a nord modular Module.''' 56 | def __init__(self, module, type, index): 57 | '''Param(module, type, index) -> Param object 58 | 59 | \tmembers: 60 | \tvariations\t9 variations for parameter (nm1 patch just uses 1st variation. 61 | \tknob\tKnob object if a controller knob is assigned. 62 | \tctrl\tCtrl object if a midi controller is assigned. 63 | \tmorph\tMorph object if a morph is assigned. 64 | \tlabels\tif module type parameter has labels, this is an array of those. 65 | ''' 66 | self.module = module 67 | self.type = type 68 | self.index = index 69 | self.variations = [ type.type.default ] * 9 70 | self.knob = None 71 | self.ctrl = None 72 | self.morph = None 73 | if len(type.labels): 74 | self.labels = type.labels[:] # make a copy so they can be changed. 75 | 76 | class Mode(object): 77 | __slots__ = ( 'module', 'type', 'index', 'value' ) 78 | '''Mode class representing static parameters for a nord modular Module.''' 79 | def __init__(self, module, type, index): 80 | '''Mode(module, type, index) -> Mode object''' 81 | self.module = module 82 | self.type = type 83 | self.index = index 84 | self.value = type.type.default 85 | 86 | class Array(list): 87 | '''Array class for managing arrays within a Module object (internal).''' 88 | def __init__(self, parent, items, item_class): 89 | self[:] = [ item_class(parent, e, i) for i, e in enumerate(items) ] 90 | for o in self: 91 | self.__dict__[o.type.name] = o 92 | 93 | #def __setattr__(self, nm, val): 94 | # self.__dict__[nm] = val 95 | 96 | #def __getattr__(self, nm): 97 | # return self.__dict__[nm] 98 | 99 | class Module(object): 100 | '''Module class representing a nord modular module within a patch.''' 101 | def __init__(self, type, area, **kw): 102 | '''Module(type, area, **kw) -> Module object''' 103 | #self.__dict__ = kw 104 | self.name = '' 105 | self.type = type 106 | self.area = area 107 | self.__dict__.update(kw) 108 | 109 | self.inputs = Array(self, type.inputs, Input) 110 | self.outputs = Array(self, type.outputs, Output) 111 | self.params = Array(self, type.params, Param) 112 | self.modes = Array(self, type.modes, Mode) 113 | 114 | if type.id == 121: # SeqNote mag/octave additions 115 | # [0, 1, mag, 0, 1, octave] 116 | # mag: 0=3-octaves, 1=2-octaves, 2=1-octave 117 | # octave: 0-9 (c0-c9) 118 | self.editmodes = [ 0, 1, 1, 0, 1, 5] 119 | 120 | -------------------------------------------------------------------------------- /nm2g2g.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import os, sys 23 | from PyQt4.Qt import * 24 | from PyQt4 import uic 25 | 26 | sys.setcheckinterval(10) 27 | 28 | class ConvertThread(QThread): 29 | def __init__(self, main): 30 | QThread.__init__(self) 31 | self.main = main 32 | self.connect(self, SIGNAL('write'), self.main.write) 33 | 34 | def run(self): 35 | self.str = '' 36 | g2oolsdir = os.path.dirname(sys.argv[0]) 37 | prog = os.path.join(g2oolsdir, 'nm2g2.py') 38 | sys.path.append(g2oolsdir) 39 | script=open(prog).read() 40 | globs = globals() 41 | exec 'from nm2g2 import *' in globs 42 | nm2g2log = main([prog ,'-r']+self.files, self) 43 | nm2g2log.error('Convertion Finished.') 44 | self.exit(0) 45 | 46 | def write(self, s): 47 | self.str += s 48 | 49 | def flush(self): 50 | self.emit(SIGNAL('write'), self.str) 51 | self.str = '' 52 | 53 | class CheckableDirModel(QDirModel): 54 | def __init__(self, *args): 55 | self.checkmap = {} 56 | QDirModel.__init__(self, *args) 57 | self.setResolveSymlinks(False) 58 | 59 | def hasSiblings(self, index): 60 | if index.row() == 0: 61 | return QDirModel.index(self, index.row()+1, index.column(), index.parent()).isValid() 62 | else: 63 | return True 64 | 65 | def flags(self, index): 66 | return QDirModel.flags(self, index)|\ 67 | Qt.ItemIsUserCheckable|Qt.ItemIsTristate 68 | 69 | def setData(self, index, value, role=Qt.DisplayRole): 70 | if index.isValid(): 71 | id = self.filePath(index) 72 | checked = self.checkmap[id] = value.toInt()[0] 73 | self.emit(SIGNAL('dataChanged(const QModelIndex&, const QModelIndex&)'), index, index) 74 | self.emit(SIGNAL('selectionChanged()')) 75 | return True 76 | return False 77 | 78 | def data(self, index, role=Qt.DisplayRole): 79 | if role == Qt.CheckStateRole and \ 80 | index.isValid() and \ 81 | index.column() == 0: 82 | id = self.filePath(index) 83 | if self.checkmap.has_key(id): 84 | return QVariant(self.checkmap[id]) 85 | return QVariant(Qt.Unchecked) 86 | return QDirModel.data(self, index, role) 87 | 88 | form_class, base_class = uic.loadUiType("nm2g2g.ui") 89 | 90 | class NM2G2G(QMainWindow, form_class): 91 | def __init__(self, parent=None): 92 | QMainWindow.__init__(self, parent) 93 | 94 | self.setupUi(self) 95 | 96 | self.dirmodel = CheckableDirModel() 97 | self.dirmodel.setSorting(QDir.Name|QDir.DirsFirst) 98 | tree = self.treeView 99 | tree.setModel(self.dirmodel) 100 | tree.setRootIndex(self.dirmodel.index(QDir.currentPath())) 101 | tree.resizeColumnToContents(0) 102 | 103 | self.guimutex = QMutex() 104 | self.convert = ConvertThread(self) 105 | 106 | @pyqtSignature('bool') 107 | def on_action_Quit_triggered(self, checked): 108 | self.close() 109 | 110 | @pyqtSignature('bool') 111 | def on_action_Run_triggered(self, checked): 112 | cm = self.dirmodel.checkmap 113 | files = [ str(k) for k in self.dirmodel.checkmap.keys() if cm[k] ] 114 | files.sort() 115 | self.textEdit.document().clear() 116 | self.convert.files = files 117 | self.convert.start() 118 | 119 | @pyqtSignature('bool') 120 | def on_action_Stop_triggered(self, checked): 121 | global maindone 122 | maindone = True 123 | 124 | def write(self, s): 125 | #self.ui.textEdit.insertHtml(s) 126 | self.textEdit.insertPlainText(s) 127 | self.textEdit.ensureCursorVisible() 128 | 129 | if __name__ == "__main__": 130 | app = QApplication(sys.argv) 131 | nm2g2g = NM2G2G() 132 | nm2g2g.show() 133 | sys.exit(app.exec_()) 134 | 135 | -------------------------------------------------------------------------------- /nord/convert/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # __init__.py - package init for convert 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | from nord.convert.convert import Convert 24 | from nord.convert import inout 25 | from nord.convert import osc 26 | from nord.convert import lfo 27 | from nord.convert import env 28 | from nord.convert import filter 29 | from nord.convert import mixer 30 | from nord.convert import audio 31 | from nord.convert import ctrl 32 | from nord.convert import logic 33 | from nord.convert import seq 34 | 35 | id_table = { 36 | 1: inout.ConvKeyboard, 37 | 63: inout.ConvKeyboardPatch, 38 | 65: inout.ConvMIDIGlobal, 39 | 2: inout.ConvAudioIn, 40 | 127: inout.ConvPolyAreaIn, 41 | 5: inout.Conv1Output, 42 | 4: inout.Conv2Output, 43 | 3: inout.Conv4Output, 44 | 67: inout.ConvNoteDetect, 45 | 100: inout.ConvKeyboardSplit, 46 | 47 | 97: osc.ConvMasterOsc, 48 | 7: osc.ConvOscA, 49 | 8: osc.ConvOscB, 50 | 9: osc.ConvOscC, 51 | 107: osc.ConvSpectralOsc, 52 | 96: osc.ConvFormantOsc, 53 | 14: osc.ConvOscSlvA, 54 | 10: osc.ConvOscSlvB, 55 | 11: osc.ConvOscSlvC, 56 | 12: osc.ConvOscSlvD, 57 | 13: osc.ConvOscSlvE, 58 | 106: osc.ConvOscSineBank, 59 | 85: osc.ConvOscSlvFM, 60 | 31: osc.ConvNoise, 61 | 95: osc.ConvPercOsc, 62 | 58: osc.ConvDrumSynth, 63 | 64 | 24: lfo.ConvLFOA, 65 | 25: lfo.ConvLFOB, 66 | 26: lfo.ConvLFOC, 67 | 80: lfo.ConvLFOSlvA, 68 | 27: lfo.ConvLFOSlvB, 69 | 28: lfo.ConvLFOSlvC, 70 | 29: lfo.ConvLFOSlvD, 71 | 30: lfo.ConvLFOSlvE, 72 | 68: lfo.ConvClkGen, 73 | 33: lfo.ConvClkRndGen, 74 | 34: lfo.ConvRndStepGen, 75 | 110: lfo.ConvRandomGen, 76 | 35: lfo.ConvRndPulseGen, 77 | 99: lfo.ConvPatternGen, 78 | 79 | 20: env.ConvADSR_Env, 80 | 84: env.ConvAD_Env, 81 | 23: env.ConvMod_Env, 82 | 46: env.ConvAHD_Env, 83 | 52: env.ConvMulti_Env, 84 | 71: env.ConvEnvFollower, 85 | 86 | 86: filter.ConvFilterA, 87 | 87: filter.ConvFilterB, 88 | 50: filter.ConvFilterC, 89 | 49: filter.ConvFilterD, 90 | 51: filter.ConvFilterE, 91 | 92: filter.ConvFilterF, 92 | 45: filter.ConvVocalFilter, 93 | 108: filter.ConvVocoder, 94 | 32: filter.ConvFilterBank, 95 | 103: filter.ConvEqMid, 96 | 104: filter.ConvEqShelving, 97 | 98 | 19: mixer.Conv3Mixer, 99 | 40: mixer.Conv8Mixer, 100 | 44: mixer.ConvGainControl, 101 | 18: mixer.ConvX_Fade, 102 | 47: mixer.ConvPan, 103 | 113: mixer.Conv1to2Fade, 104 | 114: mixer.Conv2to1Fade, 105 | 111: mixer.ConvLevMult, 106 | 112: mixer.ConvLevAdd, 107 | 76: mixer.ConvOnOff, 108 | 79: mixer.Conv4_1Switch, 109 | 88: mixer.Conv1_4Switch, 110 | 81: mixer.ConvAmplifier, 111 | 112 | 61: audio.ConvClip, 113 | 62: audio.ConvOverdrive, 114 | 74: audio.ConvWaveWrap, 115 | 54: audio.ConvQuantizer, 116 | 78: audio.ConvDelay, 117 | 53: audio.ConvSampleNHold, 118 | 82: audio.ConvDiode, 119 | 94: audio.ConvStereoChorus, 120 | 102: audio.ConvPhaser, 121 | 57: audio.ConvInvLevShift, 122 | 83: audio.ConvShaper, 123 | 21: audio.ConvCompressor, 124 | 105: audio.ConvExpander, 125 | 118: audio.ConvDigitizer, 126 | 117: audio.ConvRingMod, 127 | 128 | 43: ctrl.ConvConstant, 129 | 39: ctrl.ConvSmooth, 130 | 48: ctrl.ConvPortamentoA, 131 | 16: ctrl.ConvPortamentoB, 132 | 72: ctrl.ConvNoteScaler, 133 | 75: ctrl.ConvNoteQuant, 134 | 98: ctrl.ConvKeyQuant, 135 | 22: ctrl.ConvPartialGen, 136 | 66: ctrl.ConvControlMixer, 137 | 115: ctrl.ConvNoteVelScal, 138 | 139 | 36: logic.ConvPosEdgeDly, 140 | 64: logic.ConvNegEdgeDly, 141 | 38: logic.ConvPulse, 142 | 37: logic.ConvLogicDelay, 143 | 70: logic.ConvLogicInv, 144 | 73: logic.ConvLogicProc, 145 | 59: logic.ConvCompareLev, 146 | 89: logic.ConvCompareAB, 147 | 69: logic.ConvClkDiv, 148 | 77: logic.ConvClkDivFix, 149 | 150 | 17: seq.ConvEventSeq, 151 | 91: seq.ConvCtrlSeq, 152 | 15: seq.ConvNoteSeqA, 153 | 90: seq.ConvNoteSeqB, 154 | } 155 | 156 | -------------------------------------------------------------------------------- /nord/convert/seq.py: -------------------------------------------------------------------------------- 1 | # 2 | # seq.py - Seq tab conversion objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord.utils import setv, getv 23 | from nord.convert import Convert 24 | 25 | def handlelength(conv): 26 | nmm, g2m = conv.nmmodule, conv.g2module 27 | nmmp, g2mp = nmm.params, g2m.params 28 | length = getv(nmmp.Length) 29 | if getv(nmmp.Loop) == 0 and length > 15: 30 | link = g2m.outputs.Link 31 | setv(g2mp.Length, 16) 32 | for l in xrange(16, length, 16): 33 | seq = conv.add_module(g2m.type.shortnm) 34 | if l + 16 > length: 35 | setv(seq.params.Length, length - l) 36 | else: 37 | setv(seq.params.Length, 16) 38 | setv(seq.params.Loop, 0) # Once 39 | conv.connect(g2m.inputs.Rst, seq.inputs.Park) 40 | conv.connect(link, seq.inputs.Rst) 41 | conv.connect(g2m.inputs.Clk, seq.inputs.Clk) 42 | link = seq.outputs.Link 43 | return link 44 | if length > 16: 45 | clkdiv = conv.add_module('ClkDiv') 46 | clkdiv.modes.DivMode.value = 0 47 | setv(clkdiv.params.Divider, length) 48 | conv.connect(clkdiv.outputs.Out, g2m.inputs.Rst) 49 | conv.connect(clkdiv.inputs.Clk, g2m.inputs.Clk) 50 | conv.inputs[1] = clkdiv.inputs.Rst 51 | setv(g2mp.Loop, 0) # Once 52 | return g2m.outputs.Link 53 | 54 | class ConvEventSeq(Convert): 55 | maing2module = 'SeqEvent' 56 | parammap = ['Length', 'Loop', ['TG1', 'Gate1'], ['TG2', 'Gate2']]+[None]*32 57 | inputmap = ['Clk', 'Rst'] 58 | outputmap = ['Trig1', 'Trig2', 'Link', 'Link'] 59 | 60 | def domodule(self): 61 | nmm, g2m = self.nmmodule, self.g2module 62 | nmmp, g2mp = nmm.params, g2m.params 63 | 64 | for j in xrange(2): 65 | for i in xrange(16): 66 | s = 'Seq%dStep%d' % (j+1, i+1) 67 | step = getattr(g2mp, s) 68 | setv(step, getv(getattr(nmmp, s))) 69 | self.params[4+j*16+i] = step 70 | 71 | self.outputs[3] = handlelength(self) 72 | 73 | class ConvCtrlSeq(Convert): 74 | maing2module = 'SeqLev' 75 | parammap = [None]*16 + ['Length', ['BipUni', 'Uni'], 'Loop'] 76 | inputmap = ['Clk', 'Rst'] 77 | outputmap = ['Val', 'Link', 'Link'] 78 | 79 | def domodule(self): 80 | nmm, g2m = self.nmmodule, self.g2module 81 | nmmp, g2mp = nmm.params, g2m.params 82 | 83 | for i in xrange(16): 84 | s = 'Seq1Step%d' % (i+1) 85 | step = getattr(g2mp, s) 86 | t = 'Ctrl%d' % (i+1) 87 | setv(step, getv(getattr(nmmp, t))) 88 | self.params[i] = step 89 | 90 | self.outputs[2] = handlelength(self) 91 | 92 | class ConvNoteSeqA(Convert): 93 | maing2module = 'SeqNote' 94 | parammap = [None]*16 + ['Length', None, None, None, 'Loop'] 95 | inputmap = ['Clk', 'Rst'] 96 | outputmap = ['Note', 'Link', 'Link', 'Trig'] 97 | 98 | def domodule(self): 99 | nmm, g2m = self.nmmodule, self.g2module 100 | nmmp, g2mp = nmm.params, g2m.params 101 | 102 | for i in xrange(16): 103 | s = 'Seq1Step%d' % (i+1) 104 | t = 'Note%d' % (i+1) 105 | step = getattr(g2mp, s) 106 | setv(step, getv(getattr(nmmp, t))) 107 | self.params[i] = step 108 | # setup trigger as GClk 109 | s = 'Seq2Step%d' % (i+1) 110 | setv(getattr(g2mp, s), 1) 111 | setv(g2mp.TG, 0) # simulate GClk (maybe?) 112 | self.outputs[2] = handlelength(self) 113 | 114 | class ConvNoteSeqB(Convert): 115 | maing2module = 'SeqNote' 116 | parammap = [None]*16 + ['Length', None, None, None, 'Loop'] 117 | inputmap = ['Clk', 'Rst'] 118 | outputmap = ['Note', 'Link', 'Link', 'Trig'] 119 | 120 | def domodule(self): 121 | nmm, g2m = self.nmmodule, self.g2module 122 | nmmp, g2mp = nmm.params, g2m.params 123 | 124 | for i in xrange(16): 125 | s = 'Seq1Step%d' % (i+1) 126 | t = 'Note%d' % (i+1) 127 | step = getattr(g2mp, s) 128 | setv(step, getv(getattr(nmmp, t))) 129 | self.params[i] = step 130 | # setup trigger as GClk 131 | s = 'Seq2Step%d' % (i+1) 132 | setv(getattr(g2mp, s), 1) 133 | setv(g2mp.TG, 0) # simulate GClk (maybe?) 134 | self.outputs[2] = handlelength(self) 135 | 136 | -------------------------------------------------------------------------------- /nord/net.py: -------------------------------------------------------------------------------- 1 | # 2 | # net.py - maintain netlist from cable connections 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | 23 | from nord import printf 24 | 25 | '''These classes should not be used by user applications. It's all 26 | internal representations of cable netlists of patches.''' 27 | 28 | class NetError(Exception): 29 | def __init__(self, value): 30 | self.value = value 31 | def __str__(self): 32 | return repr(self.value) 33 | 34 | class Net: 35 | __slots__ = ( 'output', 'inputs' ) 36 | def __init__(self, output, inputs): 37 | self.output = output 38 | self.inputs = inputs 39 | 40 | class NetList: 41 | def __init__(self): 42 | self.nets = [] 43 | 44 | def copy(self): 45 | new = NetList() 46 | new.nets = self.nets[:] 47 | return new 48 | 49 | def combine(self, source, dest): 50 | sout, dout = source.net.output, dest.net.output 51 | if sout and dout and (sout != dout): # shouldn't happen 52 | printf('source %s\n', self.nettos(source.net)) 53 | printf('dest %s\n', self.nettos(dest.net)) 54 | raise NetError( 55 | 'source and dest both have outputs: source=%s:%s dest=%s:%s' % ( 56 | sout.module.type.shortnm, sout.type.name, 57 | dout.module.type.shortnm, dout.type.name)) 58 | 59 | self.nets.remove(dest.net) 60 | 61 | if dout: 62 | source.net.output = dout 63 | source.net.output.net = source.net 64 | 65 | source.net.inputs += dest.net.inputs 66 | for input in dest.net.inputs: 67 | input.net = source.net 68 | 69 | def add(self, source, dest): 70 | snet, dnet = source.net, dest.net 71 | if snet and dnet and snet == dnet: 72 | printf('net already created\n') 73 | printf('%r %r\n', snet, dnet) 74 | printf(' %d:%s -> %d:%s\n', 75 | source.module.index, source.type.name, 76 | dest.module.index, dest.type.name) 77 | printf('source net: %s\n', self.nettos(snet)) 78 | printf('dest net: %s\n', self.nettos(dnet)) 79 | return 80 | 81 | if snet and dnet: # two separate nets need to be combined 82 | self.combine(source, dest) 83 | return 84 | 85 | if snet: 86 | net = snet 87 | net.inputs.append(dest) 88 | elif dnet: 89 | net = dnet 90 | if source.direction: 91 | if net.output and source != net.output: 92 | raise NetError( 93 | 'both nets have outputs: source=%s:%s net.source=%s:%s' % ( 94 | source.module.type.shortnm, source.type.name, 95 | net.output.module.type.shortnm, net.output.type.name)) 96 | net.output = source 97 | else: 98 | net.inputs.append(source) 99 | else: 100 | net = None 101 | 102 | # add new net if one not found 103 | if not net: 104 | if source.direction: 105 | net = Net(source, [dest]) 106 | else: 107 | net = Net(None, [dest, source]) 108 | self.nets.append(net) 109 | 110 | # update source and dest nets list 111 | if not source.net: 112 | source.net = net 113 | if not dest.net: 114 | dest.net = net 115 | 116 | def delete(self, source, dest): 117 | if source.net != dest.net: 118 | raise NetError('source=%s:%s dest=%s:%s not connected' % ( 119 | source.module.name, source.type.name, 120 | dest.module.name, dest.type.name)) 121 | if 0 and not source.net in self.nets: 122 | raise NetError('source=%s:%s dest=%s:%s not in netlist' % ( 123 | source.module.name, source.type.name, 124 | dest.module.name, dest.type.name)) 125 | 126 | # remove net from netlist and rebuild two nets 127 | net = source.net 128 | if net.output: 129 | net.output.net = None 130 | for input in net.inputs: 131 | input.net = None 132 | self.nets.remove(net) 133 | 134 | def nettos(self, net): 135 | if not net: 136 | return '' 137 | if net.output: 138 | nout = net.output 139 | out = '%s(%s)%d:%s' % (nout.module.name, nout.module.type.shortnm, 140 | nout.module.index, nout.type.name) 141 | else: 142 | out = '' 143 | inp = ','.join([ 144 | '%s(%s)%d:%s' % (inp.module.name, inp.module.type.shortnm, 145 | inp.module.index, inp.type.name) 146 | for inp in net.inputs]) 147 | return '%s -> %s' % (out, inp) 148 | 149 | -------------------------------------------------------------------------------- /nm2g2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | import logging 23 | import os, sys, time, traceback 24 | from optparse import OptionParser, make_option 25 | from glob import glob 26 | sys.path.append('.') 27 | from nord.nm2g2 import NM2G2Converter, NM1Error 28 | 29 | #__builtins__.printf = printf 30 | 31 | nm2g2_options = [ 32 | make_option('-a', '--all-files', action='store_true', 33 | dest='allfiles', default=False, 34 | help='Process all files (not just *.pch)'), 35 | make_option('-A', '--adsr-for-ad', action='store_true', 36 | dest='adsrforad', default=False, 37 | help='Replace AD modules with ADSR modules'), 38 | make_option('-c', '--compress-columns', action='store_true', 39 | dest='compresscolumns', default=False, 40 | help='Remove columns not containing modules'), 41 | make_option('-d', '--debug', action='store_true', 42 | dest='debug', default=False, 43 | help='Allow exceptions to terminate application'), 44 | make_option('-k', '--keep-old', action='store_true', 45 | dest='keepold', default=False, 46 | help='If .pch2 file exists, do not replace it'), 47 | make_option('-l', '--no-logic-combine', action='store_false', 48 | dest='logiccombine', default=True, 49 | help='Do not combine logic and inverter modules'), 50 | make_option('-n', '--no-log', action='store_true', 51 | dest='nolog', default=False, 52 | help='Do not generated failed patches log'), 53 | make_option('-o', '--g2-overdrive', action='store_true', 54 | dest='g2overdrive', default=False, 55 | help='Use g2 overdrive model'), 56 | make_option('-p', '--pad-mixer', action='store_true', 57 | dest='padmixer', default=False, 58 | help='Use mixers with Pad when possible'), 59 | make_option('-r', '--recursive', action='store_true', 60 | dest='recursive', default=False, 61 | help='On dir arguments, convert all .pch files'), 62 | make_option('-s', '--no-shorten', action='store_false', 63 | dest='shorten', default=True, 64 | help='Turn off shorten cable connections'), 65 | make_option('-v', '--verbose', action='store', 66 | dest='verbosity', default='2', choices=map(str, range(5)), 67 | help='Set converter verbosity level 0-4'), 68 | ] 69 | 70 | def doconvert(filename, options): 71 | # general algorithm for converter: 72 | try: 73 | nm2g2 = NM2G2Converter(filename, options, options.log) 74 | nm2g2.convert() 75 | except KeyboardInterrupt: 76 | sys.exit(1) 77 | except NM1Error, s: 78 | return '%s\n%s' % (filename, s) 79 | except Exception, e: 80 | if options.debug: 81 | return '%s\n%s' % (filename, traceback.format_exc()) 82 | else: 83 | return '%s\n%s' % (filename, e) 84 | return '' 85 | 86 | def process_file(filename, options): 87 | if filename[-5:].lower() == '.pch2': 88 | return 89 | if filename[-4:].lower() == '.pch' or options.allfiles: 90 | testname = filename 91 | if filename[-4:].lower() != '.pch': 92 | testname = filename+'.pch' 93 | if options.keepold and os.path.exists(testname + '2'): 94 | return 95 | options.log.error('"%s"' % filename) 96 | failed = doconvert(filename, options) 97 | if failed: 98 | options.failedpatches.append(failed) 99 | options.log.info('-' * 20) 100 | 101 | def main(argv, stream): 102 | global nm2g2_options 103 | 104 | parser = OptionParser("usage: %prog [options] ", 105 | option_list=nm2g2_options) 106 | (options, args) = parser.parse_args(argv[:]) 107 | options.programpath = args.pop(0) 108 | verbosity = [ 109 | logging.CRITICAL, 110 | logging.ERROR, 111 | logging.WARNING, 112 | logging.INFO, 113 | logging.DEBUG, 114 | ][int(options.verbosity)] 115 | 116 | options.log = logging.getLogger('nm2g2') 117 | options.failedpatches = [] 118 | 119 | fmt = logging.Formatter('%(message)s', None) 120 | hdlr = logging.StreamHandler(stream) 121 | hdlr.setFormatter(fmt) 122 | options.log.addHandler(hdlr) 123 | options.log.setLevel(verbosity) 124 | options.log.propagate = False 125 | 126 | while len(args): 127 | arg = args.pop(0) 128 | pathlist = glob(arg) 129 | if len(pathlist) == 0: 130 | options.failedpatches.append(arg) 131 | continue 132 | for path in pathlist: 133 | if os.path.isdir(path) and options.recursive: 134 | for root, dirnamess, filenames in os.walk(path): 135 | for name in filenames: 136 | filename = os.path.join(root, name) 137 | process_file(filename, options) 138 | else: 139 | process_file(path, options) 140 | 141 | if len(options.failedpatches): 142 | s = 'Failed patches: \n %s\n' % '\n '.join(options.failedpatches) 143 | if not options.nolog: 144 | date = time.strftime('%m-%d-%y-%H:%M:%S', time.localtime()) 145 | open('failedpatches-%s.txt' % (date), 'w').write(s) 146 | options.log.warning(s) 147 | 148 | class StdoutStream: 149 | def __init__(self, file=sys.stdout): 150 | self.file = file 151 | self.str = '' 152 | 153 | def write(self, s): 154 | self.str += s 155 | 156 | def flush(self): 157 | self.file.write(self.str) 158 | self.str = '' 159 | 160 | if __name__ == '__main__': 161 | main(sys.argv, StdoutStream()) 162 | -------------------------------------------------------------------------------- /nord/convert/ctrl.py: -------------------------------------------------------------------------------- 1 | # 2 | # ctrl.py - Ctrl tab conversion objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord.utils import setv, getv 23 | from nord.units import nm2g2val, g2adsrtime, nm1adsrtime 24 | from nord.convert import Convert 25 | from nord.convert.table import glide, notescale, modtable 26 | 27 | class ConvConstant(Convert): 28 | maing2module = 'Constant' 29 | parammap = [['Level', 'Value'], ['BipUni', 'Unipolar']] 30 | outputmap = ['Out'] 31 | 32 | class ConvSmooth(Convert): 33 | maing2module = 'Glide' 34 | parammap = ['Time'] 35 | inputmap = ['In'] 36 | outputmap = ['Out'] 37 | 38 | def domodule(self): 39 | nmm, g2m = self.nmmodule, self.g2module 40 | nmmp, g2mp = nmm.params, g2m.params 41 | 42 | setv(g2mp.Glide, 1) 43 | setv(g2mp.Time, glide[getv(nmmp.Time)]) 44 | 45 | class ConvPortamentoA(Convert): 46 | maing2module = 'Glide' 47 | parammap = ['Time'] 48 | inputmap = ['In', 'On'] 49 | outputmap = ['Out'] 50 | 51 | def domodule(self): 52 | nmm, g2m = self.nmmodule, self.g2module 53 | nmmp, g2mp = nmm.params, g2m.params 54 | 55 | porttime = [ .5*val for val in g2adsrtime] 56 | nm1midival = getv(nmmp.Time) 57 | g2midival = nm2g2val(nm1midival, nm1adsrtime, porttime) 58 | setv(g2mp.Time, g2midival) 59 | setv(g2mp.Glide, 0) 60 | 61 | class ConvPortamentoB(ConvPortamentoA): 62 | def domodule(self): 63 | ConvPortamentoA.domodule(self) 64 | nmm, g2m = self.nmmodule, self.g2module 65 | nmmp, g2mp = nmm.params, g2m.params 66 | invert = self.add_module('Invert') 67 | self.connect(invert.outputs.Out1, g2m.inputs.On) 68 | self.inputs[1] = invert.inputs.In1 69 | 70 | class ConvNoteScaler(Convert): 71 | maing2module = 'NoteScaler' 72 | parammap = [['Range', 'Transpose']] 73 | inputmap = ['In'] 74 | outputmap = ['Out'] 75 | 76 | class ConvNoteQuant(Convert): 77 | maing2module = 'NoteQuant' 78 | parammap = ['Range', 'Notes'] 79 | inputmap = ['In'] 80 | outputmap = ['Out'] 81 | 82 | class ConvKeyQuant(Convert): 83 | maing2module = 'KeyQuant' 84 | parammap = ['Range', ['Capture', 'Cont'], 85 | 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'C', 'C#', 'D', 'D#'] 86 | inputmap = ['In'] 87 | outputmap = ['Out'] 88 | 89 | class ConvPartialGen(Convert): 90 | maing2module = 'PartQuant' 91 | parammap = ['Range'] 92 | inputmap = ['In'] 93 | outputmap = ['Out'] 94 | 95 | class ConvControlMixer(Convert): 96 | maing2module = 'Mix2-1B' 97 | parammap = ['Inv1', ['Lev1', 'Level1'], 'Inv2', ['Lev2', 'Level2'], 98 | ['ExpLin', 'Mode']] 99 | inputmap = ['In1', 'In2'] 100 | outputmap = ['Out'] 101 | 102 | def domodule(self): 103 | nmm, g2m = self.nmmodule, self.g2module 104 | nmmp, g2mp = nmm.params, g2m.params 105 | 106 | setv(g2mp.Lev1, modtable[getv(g2mp.Lev1)][0]) 107 | setv(g2mp.Lev2, modtable[getv(g2mp.Lev2)][0]) 108 | 109 | def finalize(self): 110 | self.g2module.uprate = 0 111 | 112 | class ConvNoteVelScal(Convert): 113 | maing2module = 'LevScaler' 114 | parammap = [None, ['L', 'LeftGain'], ['BP', 'Breakpoint'], ['R', 'RightGain']] 115 | inputmap = ['', 'Note'] # no Vel 116 | outputmap = ['Level'] 117 | 118 | def domodule(self): 119 | nmm, g2m = self.nmmodule, self.g2module 120 | nmmp, g2mp = nmm.params, g2m.params 121 | 122 | setv(g2mp.Kbt, 0) 123 | l = getv(nmmp.LeftGain) 124 | r = getv(nmmp.RightGain) 125 | velsens = getv(nmmp.VelocitySensitivity) 126 | external = 0 127 | for paramnm in ['VelocitySensitivity', 'LeftGain', 'RightGain']: 128 | param = getattr(nmmp, paramnm) 129 | for checknm in ['knob', 'ctrl', 'morph']: 130 | if getattr(param, checknm) != None: 131 | external = 1 132 | less8db = (abs(l-24) <= 8 and abs(r-24) <= 8) 133 | velinp = len(nmm.inputs.Velocity.cables) != 0 134 | setv(g2mp.L, notescale[l][1]) 135 | setv(g2mp.R, notescale[r][1]) 136 | if not external and less8db and not velinp and velsens == 0 : 137 | return 138 | 139 | if not less8db: 140 | setv(g2mp.Kbt, 0) 141 | setv(g2mp.L, notescale[l][0]) 142 | setv(g2mp.R, notescale[r][0]) 143 | levmult1 = self.add_module('LevMult', name='24db') 144 | self.connect(g2m.outputs.Level, g2m.inputs.In) 145 | self.connect(g2m.outputs.Level, levmult1.inputs.Mod) 146 | self.connect(g2m.outputs.Out, levmult1.inputs.In) 147 | out = levmult1.outputs.Out 148 | if not velinp and velsens == 0: 149 | self.outputs[0] = levmult1.outputs.Out 150 | return 151 | else: 152 | out = g2m.outputs.Level 153 | 154 | mix21b = self.add_module('Mix2-1B', name='Vel') 155 | setv(mix21b.params.Inv2, 1) 156 | setv(mix21b.params.Lev1, 88) 157 | setv(mix21b.params.Lev2, 16) 158 | self.connect(mix21b.inputs.Chain, mix21b.inputs.In1) 159 | self.connect(mix21b.inputs.In1, mix21b.inputs.In2) 160 | levmult2 = self.add_module('LevMult', name='') 161 | xfade = self.add_module('X-Fade', name='VelSens') 162 | setv(xfade.params.LogLin, 1) # Lin 163 | self.connect(mix21b.outputs.Out, levmult2.inputs.Mod) 164 | self.connect(out, levmult2.inputs.In) 165 | self.connect(levmult2.inputs.In, xfade.inputs.In1) 166 | self.connect(levmult2.outputs.Out, xfade.inputs.In2) 167 | setv(xfade.params.Mix, velsens) 168 | self.params[0] = xfade.params.Mix 169 | self.inputs[0] = mix21b.inputs.Chain 170 | self.outputs[0] = xfade.outputs.Out 171 | 172 | -------------------------------------------------------------------------------- /nord/g2/pprint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright (c) 2006,2007 Matt Gerassimoff 4 | # 5 | # This file is part of g2ools. 6 | # 7 | # g2ools is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # g2ools is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Foobar; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | 22 | from nord.g2.categories import g2categories 23 | from nord import printf 24 | 25 | def printdescription(patch): 26 | printf('patchdescription:\n') 27 | desc = patch.description 28 | printf(' category: %s\n', g2categories[desc.category]) 29 | printf(' voices: %d\n', desc.voices) 30 | printf(' height: %d\n', desc.height) 31 | printf(' monopoly: %d\n', desc.monopoly) 32 | printf(' variation: %d\n', desc.variation) 33 | x = [ desc.red, desc.blue, desc.yellow, desc.orange, desc.green, 34 | desc.purple, desc.white ] 35 | colors = ''.join(['RBYOGPW'[i] for i in xrange(len(x)) if x[i]]) 36 | printf(' colors: %s\n', colors) 37 | #printf(' unk2=0x%02x\n', desc.unk2) 38 | 39 | def printvariations(patch): 40 | settings = patch.settings 41 | printf('variations:\n') 42 | for attr in [ 'activemuted', 'patchvol', 'glide', 'glidetime', 'bend', 'semi', 43 | 'vibrato', 'cents', 'rate', 44 | 'arpeggiator', 'arptime', 'arptype', 'octaves', 45 | 'octaveshift', 'sustain' ]: 46 | printf(' %-16s %s\n', (attr+':'), getattr(settings, attr).variations) 47 | 48 | def printmodules(patch): 49 | printf('modules:\n') 50 | for module in patch.voice.modules: 51 | printf(' %-18s %-16s %2d:(%d,%2d)%3d type=%3d uprate=%d leds=%d\n', 52 | '"%s"' % module.name, module.type.shortnm, 53 | module.index, module.horiz, module.vert, module.color, 54 | module.type.id, module.uprate, module.leds) 55 | if hasattr(module, 'modes') and len(module.modes): 56 | printf(' modes:\n') 57 | for m, mode in enumerate(module.modes): 58 | mtype = module.type.modes[m] 59 | printf(' %-16s %r\n', mtype.name+':', mode) 60 | if hasattr(module, 'params') and len(module.params): 61 | printf(' params:\n') 62 | for p, param in enumerate(module.params): 63 | ptype = module.type.params[p] 64 | printf(' %-16s %r\n', ptype.name+':', param.variations) 65 | if hasattr(param, 'labels'): 66 | printf(' %r\n', param.labels) 67 | 68 | def printcables(patch): 69 | printf('cables:\n') 70 | for cable in patch.voice.cables: 71 | source, dest = cable.source, cable.dest 72 | smod, dmod = source.module, dest.module 73 | stype, dtype = smod.type, dmod.type 74 | snm = source.type.name 75 | dnm = dest.type.name 76 | printf(' %s.%s -%s %s.%s: c=%d\n', stype.shortnm, snm, 77 | '->'[source.direction], dtype.shortnm, dnm, cable.color) 78 | 79 | def printknobs(patch): 80 | printf('knobs:\n') 81 | for i, knob in enumerate(patch.knobs): 82 | if knob.assigned: 83 | printf(' %s%d:%d ', 'ABCDE'[i/24], (i/8)%3, i&7) 84 | if hasattr(knob.param, 'module'): 85 | printf('%s:"%s":%s isled=0x%02x\n', 86 | ['fx', 'voice'][knob.param.module.area.index], 87 | knob.param.module.name, knob.param.type.name, 88 | knob.isled) 89 | else: 90 | printf('morph:%d:"%s"\n', knob.param.index, knob.param.label) 91 | 92 | midicctable = { 93 | 0: 'Bank Select MSB', 94 | 1: 'Modwheel', 95 | 2: 'Breath', 96 | 4: 'Foot ctrl', 97 | 5: 'Port time', 98 | 6: 'Data MSB', 99 | 8: 'Balance', 100 | 10: 'Pan', 101 | 38: 'Data LSB', 102 | 65: 'Portamento On/Off', 103 | 66: 'Sustenuto On/Off', 104 | 67: 'Soft Pedal On/Off', 105 | 68: 'Legato Pedal On/Off', 106 | 69: 'Hold 2', 107 | 84: 'Port control', 108 | 91: 'Effect 1 Depth', 109 | 92: 'Effect 2 Depth', 110 | 93: 'Effect 3 Depth', 111 | 94: 'Effect 4 Depth', 112 | 95: 'Effect 5 Depth', 113 | 96: 'G2 Global Modwheel 1', 114 | 97: 'G2 Global Modwheel 2', 115 | 98: 'NRPN LSB', 116 | 99: 'NPRN MSB', 117 | 100: 'RPN LSB', 118 | 101: 'RPN MSB', 119 | 121: 'Reset all controllers', 120 | 123: 'All notes off', 121 | } 122 | 123 | def printmidicc(patch): 124 | printf('midicc:\n') 125 | for ctrl in patch.ctrls: 126 | param = ctrl.param 127 | if param.module.area.index == 2: 128 | name = param.name 129 | else: 130 | name = param.module.name + ':' + param.type.name 131 | if midicctable.has_key(ctrl.midicc): 132 | s = '"' + midicctable[ctrl.midicc] + '"' 133 | else: 134 | s = '' 135 | area = param.module.area.index 136 | printf(' %-8s midicc=%2d %s(%d, %d) %s\n', 137 | {0:'fx', 1:'voice', 2:'settings'}[area], ctrl.midicc, 138 | name, param.module.index, param.index, s) 139 | 140 | def printmorphs(patch): 141 | settings = patch.settings 142 | printf('morphs:\n') 143 | printf(' dial settings:\n') 144 | for i in range(len(settings.morphs)): 145 | printf(' %s\n', settings.morphs[i].dial.variations) 146 | printf(' modes:\n') 147 | for i in range(len(settings.morphs)): 148 | printf(' %s\n', settings.morphs[i].mode.variations) 149 | printf(' names:\n') 150 | printf(' %s\n', ', '.join( 151 | [ settings.morphs[i].label for i in range(len(settings.morphs))])) 152 | printf(' parameters:\n') 153 | for i in range(len(settings.morphs)): 154 | morph = settings.morphs[i] 155 | printf(' morph %d:\n', i) 156 | for j in range(len(morph.maps)): 157 | printf(' varation %d:\n', j) 158 | for k in range(len(morph.maps[j])): 159 | map = morph.maps[j][k] 160 | printf(' %s:%s range=%d\n', map.param.module.name, 161 | map.param.type.name, map.range) 162 | 163 | def printpatch(patch): 164 | printdescription(patch) 165 | printvariations(patch) 166 | printmodules(patch) 167 | printcables(patch) 168 | printknobs(patch) 169 | printmidicc(patch) 170 | printmorphs(patch) 171 | 172 | #printf('Unknown0x69:\n') 173 | #printf('%s\n', '\n '.join(hexdump(patch.unknown0x69.data).split('\n'))) 174 | #printf('ParamNames fx:\n') 175 | #printf('%s\n', '\n '.join(hexdump(patch.fx.paramnames).split('\n'))) 176 | 177 | -------------------------------------------------------------------------------- /nord/g2/_bits.pyx: -------------------------------------------------------------------------------- 1 | 2 | from cpython.buffer cimport * 3 | 4 | cdef unsigned short crc_table[256] 5 | crc_table[:] = [ 6 | 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 7 | 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 8 | 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 9 | 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 10 | 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 11 | 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 12 | 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 13 | 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 14 | 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 15 | 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 16 | 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 17 | 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 18 | 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 19 | 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 20 | 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 21 | 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 22 | 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 23 | 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 24 | 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 25 | 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 26 | 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 27 | 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 28 | 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 29 | 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 30 | 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 31 | 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 32 | 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 33 | 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 34 | 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 35 | 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 36 | 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 37 | 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, 38 | ] 39 | 40 | cpdef unsigned short crc(o): 41 | '''crc(string) -> crc 42 | 43 | Calculate the crc of a string used in the nord g2 pch2 and prf2 file. 44 | ''' 45 | cdef unsigned int crc = 0 46 | cdef int i, ti 47 | cdef Py_buffer info 48 | cdef char *s 49 | if PyObject_GetBuffer(o, &info, PyBUF_C_CONTIGUOUS) < 0: 50 | raise Exception('Not a buffer, writable, or contiguous') 51 | s = info.buf 52 | for i in range(info.len): 53 | ti = ((crc >> 8) ^ s[i]) & 0xff 54 | crc = (crc_table[ti] ^ (crc << 8)) & 0xffff 55 | PyBuffer_Release(&info) 56 | return crc & 0xffff 57 | 58 | cdef inline int bswap32(int x): 59 | return (((x & 0xff000000) >> 24) | 60 | ((x & 0x00ff0000) >> 8) | 61 | ((x & 0x0000ff00) >> 8) | 62 | ((x & 0x000000ff) >> 24)) 63 | 64 | cdef inline short bswap16(short x): 65 | return ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8) 66 | 67 | cdef inline int _getbits(int x, int p, int n): 68 | return (x >> p) & ~(~0 << n) 69 | 70 | cdef inline int _setbits(int x, int p, int n, int y): 71 | cdef int m = ~(~0 << n) 72 | return (x & ~(m << p)) | ((m & y) << p) 73 | 74 | cpdef getbits(int bit, int nbits, object o, int sign=0): 75 | cdef int byte = bit >> 3 76 | cdef short *sp 77 | cdef int value 78 | cdef Py_buffer info 79 | if PyObject_GetBuffer(o, &info, PyBUF_C_CONTIGUOUS) < 0: 80 | raise Exception('Not a buffer, writable, or contiguous') 81 | sp = (info.buf + byte) 82 | value = _getbits(bswap16(sp[0]), 16-(bit&7)-nbits, nbits) 83 | if (sign and (value >> (nbits-1))): 84 | value |= ~0 << nbits 85 | PyBuffer_Release(&info) 86 | return bit + nbits, value 87 | 88 | cpdef int setbits(int bit, int nbits, object o, int value): 89 | cdef int byte = bit >> 3 90 | cdef short *sp 91 | cdef Py_buffer info 92 | if PyObject_GetBuffer(o, &info, PyBUF_WRITEABLE|PyBUF_C_CONTIGUOUS) < 0: 93 | raise Exception('Not a buffer, writable, or contiguous') 94 | sp = (info.buf + byte) 95 | sp[0] = bswap16(_setbits(bswap16(sp[0]), 16-(bit&7)-nbits, nbits, value)) 96 | PyBuffer_Release(&info) 97 | return bit + nbits 98 | 99 | cdef class BitStream(object): 100 | cdef int bit 101 | cdef object data 102 | cdef Py_buffer info 103 | 104 | def __init__(self, object data, int bit=0): 105 | self.data = None 106 | self.setup(bit, data) 107 | 108 | def __dealloc__(self): 109 | PyBuffer_Release(&self.info) 110 | 111 | def setup(self, int bit=0, object data=None): 112 | self.bit = bit 113 | if self.data != None: 114 | PyBuffer_Release(&self.info) 115 | 116 | if data != None: 117 | self.data = data 118 | if PyObject_GetBuffer(data, &self.info, PyBUF_WRITEABLE|PyBUF_C_CONTIGUOUS) < 0: 119 | raise Exception('Not a buffer, writable, or contiguous') 120 | 121 | cpdef int read_bits(self, int nbits, int sign=0): 122 | cdef int byte = self.bit >> 3 123 | cdef short *sp = (self.info.buf + byte) 124 | cdef int value = _getbits(bswap16(sp[0]), 16-(self.bit&7)-nbits, nbits) 125 | if (sign and (value >> (nbits-1))): 126 | value |= ~0 << nbits 127 | self.bit += nbits 128 | return value 129 | 130 | def seek_bit(self, int bit, int where=0): 131 | if where == 0: 132 | self.bit = bit 133 | elif where == 1: 134 | self.bit += bit 135 | elif where == 2: 136 | self.bit = self.info.len * 8 - bit 137 | 138 | def tell_bit(self): 139 | return self.bit 140 | 141 | def read_bitsa(self, nbitsa): 142 | return [ self.read_bits(nbits) for nbits in nbitsa ] 143 | 144 | def read_bytes(self, int nbytes): 145 | return [ self.read_bits(8) for i in xrange(nbytes) ] 146 | 147 | def read_str(self, int nbytes): 148 | return str(bytearray(self.read_bytes(nbytes))) 149 | 150 | def write_bits(self, int nbits, int value): 151 | cdef int byte = self.bit >> 3 152 | cdef short *sp = (self.info.buf + byte) 153 | sp[0] = bswap16(_setbits(bswap16(sp[0]), 16-(self.bit&7)-nbits, nbits, value)) 154 | self.bit += nbits 155 | 156 | def write_bitsa(self, object nbitsa, object values): 157 | for nbits, value in zip(nbitsa, values): 158 | self.write_bits(nbits, value) 159 | 160 | def write_bytes(self, bytes): 161 | for byte in bytes: 162 | self.write_bits(8, byte) 163 | 164 | def write_str(self, s): 165 | for c in s: 166 | self.write_bits(8, ord(c)) 167 | 168 | def string(self): 169 | return str(self.data[:(self.bit+7)>>3]) 170 | 171 | -------------------------------------------------------------------------------- /nord/convert/inout.py: -------------------------------------------------------------------------------- 1 | # 2 | # inout.py - In/Out tab conversion objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord.utils import setv, getv 23 | from nord.convert import Convert 24 | from nord.convert.table import modtable 25 | 26 | class ConvKeyboard(Convert): 27 | maing2module = 'Keyboard' 28 | outputmap = ['Pitch', 'Gate', 'Lin', 'Release'] 29 | def domodule(self): 30 | self.g2module.area.keyboard = self.g2module 31 | def finalize(self): 32 | noconnections = True 33 | for output in ['Pitch', 'Note', 'Gate', 'Lin', 'Exp', 'Release']: 34 | if getattr(self.g2module.outputs, output).net: 35 | noconnections = False 36 | if noconnections: 37 | self.g2module.area.del_module(self.g2module) 38 | 39 | class ConvKeyboardPatch(Convert): 40 | maing2module = 'MonoKey' 41 | outputmap = ['Pitch', 'Gate', 'Vel', 'Vel'] # just use on vel for off vel 42 | 43 | def domodule(self): 44 | nmm, g2m = self.nmmodule, self.g2module 45 | nmmp, g2mp = nmm.params, g2m.params 46 | setv(g2mp.Mode, 0) 47 | 48 | class ConvMIDIGlobal(Convert): 49 | maing2module = 'ClkGen' 50 | outputmap = ['1/96', 'Sync', 'ClkActive'] 51 | 52 | def domodule(self): 53 | nmm, g2m = self.nmmodule, self.g2module 54 | nmmp, g2mp = nmm.params, g2m.params 55 | setv(g2mp.Source, 1) # Master 56 | 57 | class ConvAudioIn(Convert): 58 | maing2module = '2-In' 59 | outputmap = ['OutL', 'OutR'] 60 | 61 | def domodule(self): 62 | nmm, g2m = self.nmmodule, self.g2module 63 | 64 | class ConvPolyAreaIn(Convert): 65 | maing2module = 'Fx-In' 66 | parammap = [['Pad', '+6Db']] 67 | outputmap = ['OutL', 'OutR'] 68 | 69 | def domodule(self): 70 | nmm, g2m = self.nmmodule, self.g2module 71 | nmmp, g2mp = nmm.params, g2m.params 72 | 73 | setv(g2mp.Pad, [2, 1][getv(getattr(nmmp, '+6Db'))]) 74 | lboost = self.add_module('LevAmp', name='L-Boost') 75 | setv(lboost.params.Type, 0) # Lin 76 | setv(lboost.params.Gain, 96) # x2.00 77 | self.connect(g2m.outputs.OutL, lboost.inputs.In) 78 | self.outputs[0] = lboost.outputs.Out 79 | 80 | rboost = self.add_module('LevAmp', name='R-Boost') 81 | setv(rboost.params.Type, 0) # Lin 82 | setv(rboost.params.Gain, 96) # x2.00 83 | self.connect(g2m.outputs.OutR, rboost.inputs.In) 84 | self.outputs[1] = rboost.outputs.Out 85 | 86 | def isxoutput(module): 87 | return module.type.id in [ 3, 4, 5] 88 | 89 | class Conv1Output(Convert): 90 | maing2module = 'Mix1-1A' 91 | parammap = [None, None, None] # Level, Destination, Mute 92 | inputmap = [''] 93 | 94 | def __init__(self, nmarea, g2area, nmmodule, options): 95 | lev = nmmodule.params.Level 96 | if getv(lev) == 127 and not lev.knob and not lev.morph and not lev.ctrl: 97 | self.maing2module = '2-Out' 98 | elif len(filter(isxoutput, nmarea.modules)) < 2: 99 | self.maing2module = '2-Out' 100 | else: 101 | self.inputmap = ['In'] 102 | Convert.__init__(self, nmarea, g2area, nmmodule, options) 103 | 104 | def domodule(self): 105 | nmm, g2m = self.nmmodule, self.g2module 106 | nmmp, g2mp = nmm.params, g2m.params 107 | 108 | if self.maing2module == 'Mix1-1A': 109 | setv(g2mp.On, 1) 110 | setv(g2mp.ExpLin, 2) 111 | setv(g2mp.Lev, modtable[getv(nmmp.Level)][0]) 112 | out2 = self.add_module('2-Out') 113 | lev = g2m.params.Lev 114 | else: 115 | out2 = g2m 116 | lev = None 117 | 118 | dest = getv(nmmp.Destination) 119 | setv(out2.params.Destination, dest/2) 120 | setv(out2.params.Active, 1-getv(nmmp.Mute)) 121 | 122 | inp = [out2.inputs.InL, out2.inputs.InR][dest % 2] 123 | if self.maing2module == 'Mix1-1A': 124 | self.connect(g2m.outputs.Out, inp) 125 | else: 126 | self.inputs = [inp] 127 | 128 | self.params = [lev, out2.params.Destination, out2.params.Active] 129 | 130 | class Conv2Output(Convert): 131 | maing2module = 'Mix1-1S' 132 | parammap = [None, None, None] # Level, Destination, Mute 133 | inputmap = ['InL', 'InR'] 134 | 135 | def __init__(self, nmarea, g2area, nmmodule, options): 136 | lev = nmmodule.params.Level 137 | if getv(lev) == 127 and not lev.knob and not lev.morph and not lev.ctrl: 138 | self.maing2module = '2-Out' 139 | if len(filter(isxoutput, nmarea.modules)) < 2: 140 | self.maing2module = '2-Out' 141 | Convert.__init__(self, nmarea, g2area, nmmodule, options) 142 | 143 | def domodule(self): 144 | nmm, g2m = self.nmmodule, self.g2module 145 | nmmp, g2mp = nmm.params, g2m.params 146 | 147 | if self.maing2module == 'Mix1-1S': 148 | setv(g2mp.Lev, modtable[getv(nmmp.Level)][0]) 149 | setv(g2mp.On, 1) 150 | out2 = self.add_module('2-Out') 151 | self.connect(g2m.outputs.OutL, out2.inputs.InL) 152 | self.connect(g2m.outputs.OutR, out2.inputs.InR) 153 | lev = g2mp.Lev 154 | else: 155 | out2 = g2m 156 | lev = None 157 | 158 | setv(out2.params.Destination, getv(nmmp.Destination)) 159 | setv(out2.params.Active, 1-getv(nmmp.Mute)) 160 | 161 | self.params = [lev, out2.params.Destination, out2.params.Active] 162 | 163 | class Conv4Output(Convert): 164 | maing2module = '4-Out' 165 | parammap = [None] 166 | inputmap = ['In1', 'In2', 'In3', 'In4'] 167 | def domodule(self): 168 | nmm, g2m = self.nmmodule, self.g2module 169 | nmmp, g2mp = nmm.params, g2m.params 170 | #setv(self.g2area.patch.settings.patchvol, modtable[getv(nmmp.Level)][0]) 171 | 172 | class ConvNoteDetect(Convert): 173 | maing2module = 'NoteDet' 174 | parammap = ['Note'] 175 | outputmap = ['Gate', 'Vel', 'RelVel'] 176 | 177 | class ConvKeyboardSplit(Convert): 178 | maing2module = 'Name' 179 | # Lower, Upper 180 | parammap = [None, None] 181 | 182 | def domodule(self): 183 | nmm, g2m = self.nmmodule, self.g2module 184 | nmmp, g2mp = nmm.params, g2m.params 185 | g2m.name = 'KbdSplit' 186 | 187 | # now lets create the structure 188 | struct = [ ['Constant', 'Upper'], 189 | ['CompLev', 'Lower'], 190 | ['CompSig', '<=Upper'], 191 | ['Gate', 'Gate'], ] 192 | for mod, nm in struct: 193 | self.add_module(mod, name=nm) 194 | 195 | u, l, lu, g = self.g2modules 196 | 197 | setv(u.params.Level, getv(nmmp.Upper)) 198 | setv(l.params.C, getv(nmmp.Lower)) 199 | 200 | self.connect(u.outputs.Out, lu.inputs.A) 201 | self.connect(l.inputs.In, lu.inputs.B) 202 | self.connect(l.outputs.Out, g.inputs.In1_1) 203 | self.connect(lu.outputs.Out, g.inputs.In1_2) 204 | self.connect(g.outputs.Out1, g.inputs.In2_2) 205 | 206 | gout = g.outputs.Out2 207 | 208 | nout = None 209 | if len(nmm.outputs.Note.cables): 210 | n = self.add_module('DlyClock', name='Note') 211 | self.connect(gout, n.inputs.Clk) 212 | self.connect(lu.inputs.B, n.inputs.In) 213 | gout = n.inputs.Clk 214 | nout = n.outputs.Out 215 | 216 | vin = vout = None 217 | if len(nmm.outputs.Vel.cables) or len(nmm.inputs.Vel.cables): 218 | v = self.add_module('DlyClock', name='Vel') 219 | self.connect(gout, v.inputs.Clk) 220 | vin = v.inputs.In 221 | vout = v.outputs.Out 222 | 223 | self.params = [l.params.C, u.params.Level] 224 | self.outputs = [nout, g.outputs.Out2, vout] 225 | self.inputs = [l.inputs.In, g.inputs.In2_1, vin] 226 | 227 | -------------------------------------------------------------------------------- /nord/convert/dx7/dxtable.py: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # dxtable.py - DX7 convertion tables 4 | # 5 | # Copyright (c) 2006,2007 Matt Gerassimoff 6 | # 7 | # This file is part of g2ools. 8 | # 9 | # g2ools is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # g2ools is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Foobar; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | # 23 | # FMAmod conversion table calculated by 3phase 24 | # mod conversion table calculated by 3phase 25 | # kbt conversion table calculated by 3phase 26 | amodsens = [ # [dxamod, g2mod] 27 | [ 0, 0], [ 1, 2], [ 2, 3], [ 3, 4], 28 | ] 29 | 30 | lfo = [ # [lforange, lforate, lfomod, lfoattack] 31 | [ 1, 21, 55, 0], [ 1, 34, 55, 4], [ 1, 47, 55, 7], [ 1, 51, 55, 11], 32 | [ 1, 55, 55, 14], [ 1, 59, 55, 18], [ 1, 64, 55, 21], [ 1, 68, 55, 23], 33 | [ 1, 72, 55, 26], [ 1, 76, 55, 28], [ 1, 80, 55, 29], [ 1, 81, 55, 30], 34 | [ 1, 82, 55, 31], [ 1, 84, 55, 32], [ 1, 85, 55, 33], [ 1, 86, 55, 34], 35 | [ 1, 87, 55, 35], [ 1, 88, 55, 36], [ 1, 90, 55, 37], [ 1, 91, 55, 38], 36 | [ 1, 92, 55, 39], [ 1, 93, 55, 40], [ 1, 93, 55, 40], [ 1, 94, 55, 41], 37 | [ 1, 94, 55, 41], [ 1, 95, 55, 42], [ 1, 96, 55, 43], [ 1, 96, 55, 43], 38 | [ 1, 97, 55, 44], [ 1, 97, 55, 44], [ 1, 98, 55, 45], [ 1, 99, 55, 46], 39 | [ 1, 99, 55, 46], [ 1,100, 55, 47], [ 1,100, 55, 48], [ 1,101, 55, 48], 40 | [ 1,101, 55, 49], [ 1,102, 55, 50], [ 1,102, 55, 50], [ 1,103, 55, 51], 41 | [ 1,103, 55, 52], [ 1,103, 55, 52], [ 1,104, 55, 53], [ 1,104, 55, 54], 42 | [ 1,105, 55, 56], [ 1,105, 55, 57], [ 1,105, 55, 58], [ 1,106, 55, 59], 43 | [ 1,106, 55, 61], [ 1,107, 55, 62], [ 1,107, 55, 63], [ 1,108, 55, 64], 44 | [ 1,108, 55, 65], [ 1,109, 55, 65], [ 1,109, 55, 66], [ 1,110, 55, 67], 45 | [ 1,110, 55, 68], [ 1,111, 55, 69], [ 1,111, 55, 69], [ 1,112, 55, 70], 46 | [ 1,112, 55, 71], [ 1,113, 55, 71], [ 1,113, 55, 72], [ 1,114, 55, 72], 47 | [ 1,114, 55, 72], [ 1,115, 55, 73], [ 1,116, 55, 73], [ 1,116, 55, 73], 48 | [ 1,117, 55, 73], [ 1,117, 55, 74], [ 1,118, 55, 74], [ 2, 70, 55, 75], 49 | [ 2, 71, 55, 75], [ 2, 72, 55, 76], [ 2, 73, 55, 77], [ 2, 74, 55, 78], 50 | [ 2, 74, 55, 78], [ 2, 75, 55, 79], [ 2, 76, 55, 80], [ 2, 77, 55, 80], 51 | [ 2, 78, 55, 81], [ 2, 79, 55, 82], [ 2, 80, 55, 83], [ 2, 81, 55, 83], 52 | [ 2, 82, 55, 84], [ 2, 83, 55, 85], [ 2, 84, 55, 86], [ 2, 85, 55, 87], 53 | [ 2, 86, 55, 87], [ 2, 87, 55, 88], [ 2, 88, 55, 89], [ 2, 89, 55, 90], 54 | [ 2, 90, 55, 91], [ 2, 90, 55, 93], [ 2, 91, 55, 94], [ 2, 92, 55, 95], 55 | [ 2, 93, 55, 96], [ 2, 93, 55, 98], [ 2, 94, 55, 99], [ 2, 95, 55,100], 56 | ] 57 | 58 | pitcheglevs = [ # levels 59 | -48.000000, -43.497081, -38.995993, -35.626132, -31.873615, 60 | -28.495880, -25.500672, -22.872620, -20.998167, -19.496961, 61 | -18.373238, -17.251065, -16.122139, -15.375956, -14.624487, 62 | -13.876516, -13.126351, -12.375000, -12.000000, -11.625000, 63 | -11.250000, -10.875000, -10.500000, -10.125000, -9.750000, 64 | -9.375000, -9.000000, -8.625000, -8.250000, -7.875000, 65 | -7.500000, -7.125000, -6.750000, -6.375000, -6.000000, 66 | -5.625000, -5.250000, -4.875000, -4.500000, -4.125000, 67 | -3.750000, -3.375000, -3.000000, -2.625000, -2.250000, 68 | -1.875000, -1.500000, -1.125000, -0.750000, -0.375000, 69 | 0.000000, 0.375000, 0.750000, 1.125000, 1.500000, 70 | 1.875000, 2.250000, 2.625000, 3.000000, 3.375000, 71 | 3.750000, 4.125000, 4.500000, 4.875000, 5.250000, 72 | 5.625000, 6.000000, 6.375000, 6.750000, 7.125000, 73 | 7.500000, 7.875000, 8.250000, 8.625000, 9.000000, 74 | 9.375000, 9.750000, 10.125000, 10.500000, 10.875000, 75 | 11.250000, 11.625000, 12.000000, 12.375000, 12.750000, 76 | 13.125000, 14.251187, 15.001922, 16.126327, 17.250917, 77 | 18.375718, 19.877643, 21.753528, 24.373913, 27.378021, 78 | 30.748956, 34.499234, 38.627888, 43.122335, 47.624065, 79 | 48.000000, 48.000000, 48.000000, 80 | ] 81 | 82 | pitchegrates = [ # times 83 | 26.000000, 28.000000, 30.100000, 32.300000, 34.800000, 84 | 37.400000, 40.200000, 43.200000, 46.500000, 50.000000, 85 | 52.400000, 54.900000, 57.600000, 60.300000, 63.200000, 86 | 66.300000, 69.500000, 72.800000, 76.300000, 80.000000, 87 | 82.300000, 84.600000, 87.000000, 89.500000, 92.100000, 88 | 94.700000, 97.400000, 100.200000, 103.100000, 106.000000, 89 | 110.500000, 115.100000, 119.900000, 125.000000, 130.200000, 90 | 135.700000, 141.400000, 147.400000, 153.500000, 160.000000, 91 | 163.600000, 167.300000, 171.100000, 174.900000, 178.900000, 92 | 182.900000, 187.000000, 191.300000, 195.600000, 200.000000, 93 | 209.600000, 219.700000, 230.300000, 241.400000, 253.000000, 94 | 265.200000, 277.900000, 291.300000, 305.300000, 320.000000, 95 | 327.200000, 334.600000, 342.200000, 349.900000, 357.800000, 96 | 365.800000, 374.100000, 382.500000, 391.200000, 400.000000, 97 | 420.900000, 442.900000, 466.100000, 490.500000, 516.100000, 98 | 543.100000, 571.500000, 601.400000, 632.900000, 666.000000, 99 | 693.600000, 722.400000, 752.400000, 783.600000, 816.100000, 100 | 849.900000, 885.200000, 921.900000, 960.200000, 887.400000, 101 | 1061.600000, 1270.100000, 1519.500000, 1817.800000, 2174.700000, 102 | 2601.700000, 3112.600000, 3723.800000, 4454.900000, 8000.000000, 103 | ] 104 | 105 | pmodsens = [ # [pmods, g2, lev1, lev2, moffset] 106 | [ 0, 0, 11, 21, -5], [ 1, 32, 11, 21, -5], 107 | [ 2, 52, 11, 21, -5], [ 3, 64, 11, 21, -5], 108 | [ 4, 88, 11, 21, -5], [ 5,108, 11, 24, -5], 109 | [ 6,126, 15, 27, -5], [ 7,127, 75, 47, -5], 110 | ] 111 | 112 | factorycrcs = [ # crc 113 | 0xfadd, 0xdebe, 0xa028, 0x435b, 0x92c3, 0xa114, 0xb534, 0xc4df, 114 | 0xb1f8, 0xc50a, 0x50ea, 0xce65, 0xcc6a, 0xa762, 0xd6a2, 0x3fe1, 115 | 0x77d6, 0xcad3, 0x773a, 0x03b8, 0x8678, 0x020c, 0xd905, 0xe11f, 116 | 0x9bb6, 0xae0e, 0x53e3, 0x1be8, 0x593c, 0xdb40, 0x0170, 0x3231, 117 | 0xaae0, 0xcfa3, 0xbb91, 0x2f0e, 0x9476, 0x315d, 0x021c, 0x963f, 118 | 0xa567, 0x65f7, 0xc500, 0x638e, 0xddbb, 0x0686, 0x2851, 0xb61a, 119 | 0x06b2, 0xd614, 0x0232, 0x309f, 0xb041, 0x58f1, 0x930d, 0xac5e, 120 | 0x92bd, 0xea76, 0xd41a, 0xb446, 0x597f, 0x89dc, 0x3e1e, 0x4724, 121 | 0x0a03, 0x49f5, 0xb1e0, 0x3ec2, 0x82b8, 0x0cb1, 0x27da, 0x803b, 122 | 0xe074, 0x816c, 0x7f17, 0x17f7, 0x602c, 0x65cd, 0x3a5e, 0x1e5a, 123 | 0x9fde, 0x5b6d, 0x5099, 0x66cd, 0x9aca, 0x21c0, 0x1449, 0x966e, 124 | 0x65f9, 0xf866, 0x5fcc, 0x1d7f, 0x25ef, 0xddbb, 0x9a48, 0xfe23, 125 | 0xdfbd, 0xd914, 0xfe5b, 0xe197, 0xb27f, 0x6f2b, 0xd1f5, 0x5360, 126 | 0x9710, 0x388e, 0xf401, 0xd69d, 0x370f, 0x290a, 0xbb71, 0x4a37, 127 | 0xb0ec, 0x6d88, 0xa07d, 0x06a5, 0xedb2, 0x4a56, 0x124e, 0x30b8, 128 | 0xc9f8, 0x6590, 0x723c, 0x61a3, 0x9e15, 0x2c9e, 0xb3f8, 0x5a2f, 129 | 0x2733, 0xec01, 0x6fc6, 0xdcd5, 0x6c17, 0x36c6, 0xf1a5, 0x28d2, 130 | 0xe15d, 0xcad3, 0x7cfc, 0xd6a2, 0xd94f, 0x508e, 0x21fe, 0x00a3, 131 | 0x0a7e, 0xd3ec, 0x8b28, 0xad4b, 0x01ad, 0x6080, 0xa3ad, 0x0ec3, 132 | 0xa0cf, 0x9b1b, 0x898a, 0xc355, 0x593c, 0xaa7a, 0x3cb4, 0x3231, 133 | 0x8324, 0x4655, 0x3a19, 0xee86, 0x96a9, 0x410e, 0xe04b, 0x52ec, 134 | 0x5c37, 0x4665, 0xfc02, 0x548b, 0xf068, 0xcd48, 0x4fde, 0x58a1, 135 | 0xf978, 0xc46a, 0x1e2d, 0xfc36, 0x762a, 0x005b, 0x4a93, 0xc773, 136 | 0x6e88, 0x0067, 0xb446, 0xd786, 0x3d1f, 0x1611, 0x7790, 0x8fa2, 137 | 0xedb9, 0xc483, 0xeb5e, 0x4b03, 0x3590, 0x5174, 0x7053, 0xa19a, 138 | 0xaa37, 0xb7f2, 0xef24, 0xdebe, 0x1ac0, 0x6892, 0xe91e, 0xcadf, 139 | 0x0b53, 0xc947, 0x1fde, 0x43a7, 0xa9d8, 0xb327, 0x2338, 0x65f9, 140 | 0x9194, 0x966e, 0x25ef, 0xddbb, 0xdcff, 0xe2eb, 0x21c0, 0xf719, 141 | 0x4444, 0x946f, 0xec64, 0x073e, 0xe236, 0xb0ec, 0x6d88, 0xe386, 142 | 0x0c31, 0x7623, 0xb534, 0xe908, 0xc894, 0x3800, 0x1cb4, 0x3d8d, 143 | 0x7f82, 0x157e, 0xfe4c, 0x96fb, 0x7d71, 0x733a, 0x124e, 0x22ac, 144 | 0xc9f8, 0x6590, 0x0a1d, 0x4047, 0x9e15, 0xc76a, 0x401c, 0xdb94, 145 | ] 146 | -------------------------------------------------------------------------------- /nord/convert/env.py: -------------------------------------------------------------------------------- 1 | # 2 | # env.py - Env tab conversion objects 3 | # 4 | # Copyright (c) 2006,2007 Matt Gerassimoff 5 | # 6 | # This file is part of g2ools. 7 | # 8 | # g2ools is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # g2ools is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Foobar; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | # 22 | from nord import printf 23 | from nord.utils import setv, getv 24 | from nord.units import nm1adsrtime, g2adsrtime, adsrtime_map 25 | from nord.convert import Convert 26 | from nord.convert.convert import updatevals 27 | 28 | def handleretrig(conv): 29 | gatein, retrig = conv.g2module.inputs.Gate, None 30 | if len(conv.nmmodule.inputs.Retrig.cables): 31 | flipflop = conv.add_module('FlipFlop') 32 | gate = conv.add_module('Gate') 33 | gate.modes.GateMode2.value = 1 34 | conv.connect(flipflop.outputs.Q, flipflop.inputs.Rst) 35 | conv.connect(flipflop.outputs.NotQ, gate.inputs.In1_1) 36 | conv.connect(gate.outputs.Out1, conv.g2module.inputs.Gate) 37 | conv.connect(gate.inputs.In2_1, gate.inputs.In2_2) 38 | conv.connect(gate.outputs.Out2, flipflop.inputs.In) 39 | gatein = gate.inputs.In1_2 40 | retrig = flipflop.inputs.Clk 41 | return gatein, retrig 42 | 43 | def handlegate(conv, name='Gate'): 44 | gate = getattr(conv.nmmodule.inputs, name) 45 | # if gate source Keyboard, disconnect and set KB 46 | if not gate or not gate.net or not gate.net.output: 47 | return 48 | if gate.net.output.module.type.shortnm == 'Keyboard': 49 | conv.nmmodule.area.removeconnector(gate) 50 | setv(conv.g2module.params.KB, 1) 51 | 52 | class ConvADSR_Env(Convert): 53 | maing2module = 'EnvADSR' 54 | parammap = [['Shape', 'AttackShape'], 55 | 'Attack', 'Decay', 'Sustain', 'Release', None ] 56 | inputmap = ['In', 'Gate', '', 'AM'] 57 | outputmap = ['Env', 'Out'] 58 | 59 | def domodule(self): 60 | nmm, g2m = self.nmmodule, self.g2module 61 | nmmp, g2mp = nmm.params, g2m.params 62 | handlegate(self) 63 | 64 | # handle special parameters 65 | updatevals(g2mp, ['Attack', 'Decay', 'Release'], adsrtime_map) 66 | setv(g2mp.OutputType, [0, 3][getv(nmmp.Invert)]) 67 | self.inputs[1:3] = handleretrig(self) 68 | 69 | class ConvAD_Env(Convert): 70 | maing2module = 'EnvADR' 71 | parammap = ['Attack', ['Release', 'Decay'], ['TG', 'Gate']] 72 | inputmap = ['Gate', 'In', 'AM'] 73 | outputmap = ['Env', 'Out'] 74 | 75 | def __init__(self, nmarea, g2area, nmmodule, options): 76 | if options.adsrforad: 77 | self.maing2module = 'EnvADSR' 78 | self.parammap[-1][0] = 'NR' 79 | super(ConvAD_Env, self).__init__(nmarea, g2area, nmmodule, options) 80 | 81 | def domodule(self): 82 | nmm, g2m = self.nmmodule, self.g2module 83 | nmmp, g2mp = nmm.params, g2m.params 84 | handlegate(self, 'Trigger') 85 | 86 | # handle special parameters 87 | updatevals(g2mp, ['Attack', 'Release'], adsrtime_map) 88 | if self.options.adsrforad: 89 | printf('%s\n', g2m.type.shortnm) 90 | setv(g2mp.Sustain, 0) 91 | setv(g2mp.Decay, getv(g2mp.Release)) 92 | 93 | class ConvMod_Env(Convert): 94 | maing2module = 'ModADSR' 95 | parammap = ['Attack', 'Decay', 'Sustain', 'Release', 96 | 'AttackMod', 'DecayMod', 'SustainMod', 'ReleaseMod', None] 97 | inputmap = ['Gate', '', 'AttackMod', 'DecayMod', 'SustainMod', 'ReleaseMod', 98 | 'In', 'AM'] 99 | outputmap = ['Env', 'Out'] 100 | 101 | def domodule(self): 102 | nmm, g2m = self.nmmodule, self.g2module 103 | nmmp, g2mp = nmm.params, g2m.params 104 | handlegate(self) 105 | 106 | # handle special parameters 107 | updatevals(g2mp, ['Attack', 'Decay', 'Release'], adsrtime_map) 108 | if len(nmm.inputs.AttackMod.cables): 109 | levconv = self.add_module('LevConv', name='Attack') 110 | setv(levconv.params.InputType, 0) # Bip 111 | setv(levconv.params.OutputType, 5) # BipInv 112 | self.connect(levconv.outputs.Out, g2m.inputs.AttackMod) 113 | self.inputs[2] = levconv.inputs.In 114 | if len(nmm.inputs.DecayMod.cables): 115 | levconv = self.add_module('LevConv', name='Decay') 116 | setv(levconv.params.InputType, 0) # Bip 117 | setv(levconv.params.OutputType, 5) # BipInv 118 | self.connect(levconv.outputs.Out, g2m.inputs.DecayMod) 119 | self.inputs[3] = levconv.inputs.In 120 | if len(nmm.inputs.ReleaseMod.cables): 121 | levconv = self.add_module('LevConv', name='Release') 122 | setv(levconv.params.InputType, 0) # Bip 123 | setv(levconv.params.OutputType, 5) # BipInv 124 | self.connect(levconv.outputs.Out, g2m.inputs.ReleaseMod) 125 | self.inputs[5] = levconv.inputs.In 126 | setv(g2mp.OutputType, [0, 3][getv(nmmp.Invert)]) 127 | self.inputs[:2] = handleretrig(self) 128 | 129 | class ConvAHD_Env(Convert): 130 | maing2module = 'ModAHD' 131 | parammap = ['Attack', 'Hold', 'Decay', 'AttackMod', 'HoldMod', 'DecayMod'] 132 | inputmap = ['Trig', 'AttackMod', 'HoldMod', 'DecayMod', 'In', 'AM'] 133 | outputmap = ['Env', 'Out'] 134 | 135 | def domodule(self): 136 | nmm, g2m = self.nmmodule, self.g2module 137 | nmmp, g2mp = nmm.params, g2m.params 138 | handlegate(self, 'Trig') 139 | 140 | # handle special parameters 141 | updatevals(g2mp, ['Attack', 'Hold', 'Decay'], adsrtime_map) 142 | if len(nmm.inputs.AttackMod.cables): 143 | levconv = self.add_module('LevConv', name='Attack') 144 | setv(levconv.params.InputType, 0) # Bip 145 | setv(levconv.params.OutputType, 5) # BipInv 146 | self.connect(levconv.outputs.Out, g2m.inputs.AttackMod) 147 | self.inputs[1] = levconv.inputs.In 148 | if len(nmm.inputs.DecayMod.cables): 149 | levconv = self.add_module('LevConv', name='Decay') 150 | setv(levconv.params.InputType, 0) # Bip 151 | setv(levconv.params.OutputType, 5) # BipInv 152 | self.connect(levconv.outputs.Out, g2m.inputs.DecayMod) 153 | self.inputs[3] = levconv.inputs.In 154 | 155 | class ConvMulti_Env(Convert): 156 | maing2module = 'EnvMulti' 157 | parammap = ['Level1', 'Level2', 'Level3', 'Level4', 158 | 'Time1', 'Time2', 'Time3', 'Time4', None, 159 | ['SustainMode', 'Sustain'], ['Shape', 'Curve']] 160 | inputmap = ['Gate', 'In', 'AM'] 161 | outputmap = ['Env', 'Out'] 162 | 163 | def closesttime(self, time): 164 | timeval = 0 165 | timemin = abs(g2adsrtime[0]-time) 166 | for i, adsrtime in enumerate(g2adsrtime): 167 | if abs(adsrtime-time) < timemin: 168 | timemin = abs(adsrtime-time) 169 | timeval = i 170 | return timeval 171 | 172 | def domodule(self): 173 | nmm, g2m = self.nmmodule, self.g2module 174 | nmmp, g2mp = nmm.params, g2m.params 175 | handlegate(self) 176 | 177 | setv(g2mp.SustainMode, [3, 0, 1, 2, 3][getv(nmmp.Sustain)]) 178 | setv(g2mp.Shape, [3, 2, 1][getv(nmmp.Curve)]) 179 | # handle special parameters 180 | updatevals(g2mp, ['Time%d' % i for i in xrange(1, 5)]+['NR'], adsrtime_map) 181 | # if L4 is sustain, deal with it. 182 | sustain = getv(nmmp.Sustain) 183 | if sustain == 4: 184 | adsr = self.add_module('EnvADSR') 185 | setv(adsr.params.Shape, [3, 2, 1][getv(nmmp.Curve)]) 186 | setv(adsr.params.KB, getv(g2mp.KB)) 187 | setv(adsr.params.Attack, 0) 188 | setv(adsr.params.Decay, 0) 189 | setv(adsr.params.Sustain, 127) 190 | setv(adsr.params.Release, getv(nmmp.Time5)) 191 | updatevals(adsr.params, ['Release'], adsrtime_map) 192 | self.connect(g2m.inputs.Gate, adsr.inputs.Gate) 193 | self.connect(adsr.outputs.Env, g2m.inputs.AM) 194 | self.inputs[2] = adsr.inputs.AM 195 | return 196 | elif sustain == 3 and getv(nmmp.Time5) <= 16: # 16=5.3ms 197 | pass 198 | time = nm1adsrtime[getv(nmmp.Time4)]+nm1adsrtime[getv(nmmp.Time5)] 199 | setv(g2mp.Time4, self.closesttime(time)) 200 | setv(g2mp.Level4, 0) 201 | 202 | class ConvEnvFollower(Convert): 203 | maing2module = 'EnvFollow' 204 | parammap = ['Attack', 'Release'] 205 | inputmap = ['In'] 206 | outputmap = ['Out'] 207 | 208 | -------------------------------------------------------------------------------- /pch2tog2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import sys 4 | import string 5 | from nord.g2.file import Pch2File 6 | import nord.g2.file 7 | from nord.g2.categories import g2categories 8 | from nord.g2.colors import g2cablecolors, g2conncolors, g2modulecolors 9 | from nord.g2.file import Morph 10 | from nord import printf, sprintf 11 | 12 | def clean_variations(variations): 13 | v = variations[:] 14 | while len(v) > 1 and v[-2] == v[-1]: 15 | v.pop(-1) 16 | return v 17 | 18 | def format_description(patch): 19 | s = sprintf('# description\n') 20 | description = patch.description 21 | s += sprintf('setting category %s\n', g2categories[description.category]) 22 | s += sprintf('setting voices %d\n', description.voices) 23 | s += sprintf('setting height %d\n', description.height) 24 | s += sprintf('setting monopoly %d\n', description.monopoly) 25 | s += sprintf('setting variation %d\n', description.variation+1) 26 | x = [ description.red, description.blue, description.yellow, 27 | description.orange, description.green, description.purple, 28 | description.white ] 29 | colors = ''.join(['rbyogpw'[i] for i in range(len(x)) if x[i]]) 30 | s += sprintf('setting cables %s\n', colors) 31 | return s 32 | 33 | def format_settings(patch): 34 | settings = patch.settings 35 | s = sprintf('# settings\n') 36 | for group in settings.groups: 37 | for attr in group: 38 | variations = clean_variations(getattr(settings, attr).variations[:]) 39 | variations = ' '.join([ '%d' % v for v in variations]) 40 | s += sprintf('setting %s %s\n', attr, variations) 41 | return s 42 | 43 | def module_loc(module): 44 | return '%s%d' % (string.ascii_lowercase[module.horiz], module.vert) 45 | 46 | def format_modes(module, loc): 47 | s = '' 48 | if hasattr(module, 'modes') and len(module.modes): 49 | for m, mode in enumerate(module.modes): 50 | mtype = module.type.modes[m] 51 | name = mtype.name.lower() 52 | s += sprintf(' mode %s.%s %s\n', loc, name, mode.value) 53 | return s 54 | 55 | def format_params(module, loc): 56 | s = '' 57 | if hasattr(module, 'params') and len(module.params): 58 | for p, param in enumerate(module.params): 59 | variations = param.variations[:] 60 | name = module.type.params[p].name.lower() 61 | while len(variations) > 1 and variations[-2] == variations[-1]: 62 | variations.pop(-1) 63 | variations = ' '.join([ '%d' % v for v in variations]) 64 | s += sprintf(' set %s.%s %s\n', loc, name, variations) 65 | if hasattr(param, 'labels'): 66 | labels = ':'.join(param.labels) 67 | s += sprintf(' label %s.%s %s\n', loc, name, labels) 68 | return s 69 | 70 | def format_modules(area): 71 | s = sprintf(' # modules\n') 72 | modules = area.modules[:] 73 | def by_position(a, b): 74 | x = cmp(a.horiz, b.horiz) 75 | if x: 76 | return x 77 | return cmp(a.vert, b.vert) 78 | modules.sort(by_position) 79 | last_vert = -1 80 | last_horiz = -1 81 | last_col = -1 82 | last_color = -1 83 | for module in modules: 84 | # handle location/color 85 | if module.horiz != last_col: 86 | s += sprintf(' column %s\n' % chr(ord('a')+module.horiz)) 87 | last_vert = 0 88 | last_col = module.horiz 89 | sep = module.vert - last_vert 90 | if sep > module.type.height: 91 | s += sprintf(' separate %d\n', sep - module.type.height) 92 | if module.color != last_color: 93 | s += sprintf(' modulecolor %s\n', g2modulecolors.name(module.color)) 94 | last_color = module.color 95 | # print module 96 | loc = module_loc(module) 97 | module.loc = loc 98 | name = module.name 99 | if name == '': 100 | name = "''" 101 | s += sprintf(' add %s %s %s\n', module.type.shortnm.lower(), loc, name) 102 | name = name.lower() 103 | last_vert = module.vert 104 | last_horiz = module.horiz 105 | 106 | s += format_modes(module, loc) 107 | s += format_params(module, loc) 108 | return s 109 | 110 | def format_netlist(area): 111 | s = sprintf(' # %s netlist\n', area.name) 112 | for net in area.netlist.nets: 113 | s += sprintf('# %s\n', area.netlist.nettos(net)) 114 | return s 115 | 116 | def format_cables(area): 117 | s = sprintf(' # cables\n') 118 | for cable in area.cables: 119 | source, dest = cable.source, cable.dest 120 | smod, dmod = source.module, dest.module 121 | stype, dtype = smod.type, dmod.type 122 | sname = source.type.name.lower() 123 | dname = dest.type.name.lower() 124 | sloc = module_loc(smod) 125 | dloc = module_loc(dmod) 126 | t = sprintf('connect %s.%s %s.%s', sloc, sname, dloc, dname) 127 | u = sprintf('# %s -%s %s', stype.shortnm, 128 | '->'[source.direction], dtype.shortnm) 129 | s += sprintf(' %-35s %s\n', t, u) 130 | return s 131 | 132 | def format_area(area): 133 | s = sprintf('\n# area %s modules\n', area.name) 134 | s += sprintf('area %s\n', area.name) 135 | s += format_modules(area) 136 | #format_netlist(area) 137 | s += format_cables(area) 138 | return s 139 | 140 | def format_settings_param(param): 141 | if param.module.index < 2: # morph 142 | return sprintf('morph.%d.%s', (param.index & 7) + 1, param.name.lower()) 143 | else: 144 | return sprintf('setting.%s', param.name.lower()) 145 | 146 | def format_knob_location(location): 147 | row = location / 24 148 | col = ((location / 8 ) % 3) + 1 149 | knob = (location & 7) + 1 150 | names = ['osc', 'lfo', 'env', 'filter', 'effect'] 151 | return sprintf('%s%d.%d', 'abcde'[row], col, knob), names[row] 152 | 153 | def format_knobs(patch): 154 | s = sprintf("\n# knobs\n") 155 | last_name = '' 156 | for i in range(len(patch.knobs)): 157 | row = i / 24 158 | knob = patch.knobs[i] 159 | if not knob.assigned: 160 | continue 161 | 162 | module = knob.param.module 163 | knob_loc, name = format_knob_location(i) 164 | area = {0:'fx', 1:'voice', 2:'settings'}[module.area.index] 165 | if area == 'settings': # not hasattr(knob.param, 'module'): 166 | s += sprintf('knob %s %s\n', knob_loc, format_settings_param(knob.param)) 167 | continue 168 | 169 | loc = module_loc(module) 170 | t = sprintf('knob %s %s.%s.%s', knob_loc, area, loc, 171 | knob.param.type.name.lower()) 172 | u = sprintf(' # %s:', name) 173 | if module.name != last_name: 174 | u += ' ' + module.name + ' (' + module.type.shortnm.lower() + ')' 175 | s += sprintf('%-35s %s\n', t, u) 176 | last_name = module.name 177 | return s 178 | 179 | def format_midicc(patch): 180 | s = sprintf('\n# midicc\n') 181 | for ctrl in patch.ctrls: 182 | index = ctrl.param.index 183 | area = {0:'fx', 1:'voice', 2:'settings'}[ctrl.param.module.area.index] 184 | if ctrl.param.module.area.index != 2: 185 | loc = module_loc(ctrl.param.module) 186 | t = sprintf('%s.%s', loc, ctrl.param.type.name.lower()) 187 | else: 188 | t = format_settings_param(ctrl.param) 189 | s += sprintf('midicc %2d %s\n', ctrl.midicc, t) 190 | return s 191 | 192 | def format_morphs(patch): 193 | settings = patch.settings 194 | s = sprintf('\n# morphs\n') 195 | s += '# morphs per variation: ' 196 | for morphmap in settings.morphmaps: 197 | s += sprintf('%d ', len(morphmap)) 198 | s += '\n' 199 | s += sprintf('# label morph.