mirror of
https://github.com/vsariola/sointu.git
synced 2026-04-12 17:14:43 -04:00
Compare commits
670 Commits
4klang-3.0
...
feat/vsti-
| Author | SHA1 | Date | |
|---|---|---|---|
| 36df18e2ae | |||
| 6aa6d8813c | |||
| 964b2adbab | |||
| bd20440661 | |||
| ce673578fd | |||
| 0e10cd2ae8 | |||
| 4ee355bb45 | |||
| 7d6daba3d2 | |||
| 2b38e11643 | |||
| f8c522873c | |||
| e49f699f62 | |||
| 6924b63e02 | |||
| 6fc9277113 | |||
| 877556b428 | |||
| 5e65410d27 | |||
| 4e1fdf57d9 | |||
| 1daaf1829c | |||
| 74972b5ff4 | |||
| 9da6c2216c | |||
| 61e7da5dab | |||
| 59fb39d9b3 | |||
| 9cb573d965 | |||
| d46605c638 | |||
| 569958547e | |||
| 012ed10851 | |||
| 5bc6dc6015 | |||
| 350402f8f3 | |||
| 75bd9c591e | |||
| 2667c3c72c | |||
| e09af5ab34 | |||
| db2d9cac9d | |||
| a14e21dff6 | |||
| 58916d3c6d | |||
| 84d90cf0f3 | |||
| 10d20cd26f | |||
| 4a8d4c5a29 | |||
| f074c392f6 | |||
| 20fc12c529 | |||
| 6d4529971c | |||
| beb84d7652 | |||
| c55b27b23b | |||
| e488cd391b | |||
| 7f20bd8baf | |||
| 07bf8f6cdf | |||
| f0f391356c | |||
| b18a284252 | |||
| 1c020fffa3 | |||
| 267973e061 | |||
| 6b3aaf6cc9 | |||
| dfc72cd2c4 | |||
| 8a9cbdea62 | |||
| edee3452f4 | |||
| b70db4d394 | |||
| d5af39e324 | |||
| aa1b4d371b | |||
| dc12f58082 | |||
| aa7a2e56fa | |||
| 17312bbe4e | |||
| 2b3f6d8200 | |||
| db6c9f6052 | |||
| 954b306cc8 | |||
| aec756f921 | |||
| ca4a98eb50 | |||
| 65cfcb045c | |||
| bb32403c78 | |||
| d92426a100 | |||
| 6d3c65e11d | |||
| c08a319eb7 | |||
| 8227691523 | |||
| 04fbc9f6a7 | |||
| f698986718 | |||
| a38a0f4235 | |||
| 3c85f1155c | |||
| 1040eb585d | |||
| 6eb025d7ba | |||
| 9ec8f48f82 | |||
| 391b14493c | |||
| 486bab4185 | |||
| 1e47c5004c | |||
| 900f1611b1 | |||
| beb06727b0 | |||
| b6ec5d1a04 | |||
| ff8e662857 | |||
| a60814bab7 | |||
| 0ce5ca3003 | |||
| 14a0306064 | |||
| d342fb860b | |||
| 453f45c48a | |||
| 50ccfe03da | |||
| 1a8a317464 | |||
| a9517f1511 | |||
| 9073adadb3 | |||
| b772940b1f | |||
| d6abb14b08 | |||
| 64270eaf68 | |||
| 43707e5fd6 | |||
| fdad626279 | |||
| 960bddfae0 | |||
| 7675121a78 | |||
| e28891abd5 | |||
| e010b2da9d | |||
| 98a73795c7 | |||
| 5bbec75120 | |||
| ff4155a08e | |||
| 15a340317f | |||
| b6815f70cb | |||
| 9f7bbce761 | |||
| 01bf409929 | |||
| 87604dd92e | |||
| ccd283d2ea | |||
| 0a67129a0c | |||
| e4a2ed9f32 | |||
| 0187cc66ec | |||
| 33625c6f40 | |||
| 38e9007bf8 | |||
| bb0d4d6800 | |||
| b97d269cc4 | |||
| 192b31917a | |||
| 462faf5f4e | |||
| 97a1b2f766 | |||
| 4899b027ff | |||
| 1a256b1f01 | |||
| b455ef0f3c | |||
| 94589eb2eb | |||
| f5eeabe5f3 | |||
| 61ebd89da0 | |||
| e5691d670a | |||
| 12dd3dada0 | |||
| 8c8232f76e | |||
| 7ee43f199a | |||
| 048de55f00 | |||
| 905637eee3 | |||
| ce7c8a0d3e | |||
| b65d11cbb7 | |||
| df2605fddd | |||
| 12f15d1066 | |||
| e3c7d2cba4 | |||
| 545f32bcc3 | |||
| ee2c83e2cb | |||
| 00850c8001 | |||
| f35f948118 | |||
| 7df8103bf9 | |||
| 1ac2ad3c75 | |||
| 20b0598a57 | |||
| 14e548c4c1 | |||
| c692ff0f16 | |||
| b028fea59a | |||
| 231e055faf | |||
| de3f4d987f | |||
| 8c59ea1b4c | |||
| 98fedd0ed2 | |||
| 607e5b5da0 | |||
| a439a4fa48 | |||
| 29a33a154b | |||
| aba8ff2c85 | |||
| d0efcc3001 | |||
| dff484739c | |||
| 7dd2c246a0 | |||
| 6ec06c760a | |||
| 4135286ed0 | |||
| c7d79035ce | |||
| 568aa1d76d | |||
| d82d151f49 | |||
| c040bdedee | |||
| a0bcac3904 | |||
| 33221b5203 | |||
| 94926c5596 | |||
| 61776f397a | |||
| 5884a8d195 | |||
| cafb43f8c8 | |||
| 5a2e87982e | |||
| 338529012a | |||
| ffb2f18c68 | |||
| ccc8dc906f | |||
| c421748db9 | |||
| 9db6ecb3da | |||
| 8ffe4a70dd | |||
| d2ddba3944 | |||
| 7af7d4332d | |||
| 9d6ca519a2 | |||
| 3da62179e4 | |||
| 8c4f7ee61f | |||
| f5980ecb79 | |||
| 63fc3d0d08 | |||
| 9ef271f1a8 | |||
| cd00067da8 | |||
| 248ba483c6 | |||
| c06ac6ea5e | |||
| a3dcc829c0 | |||
| e7dbb0289c | |||
| 9efddd673d | |||
| cd700ed954 | |||
| 70080c2b9d | |||
| 61c2e980a2 | |||
| 6129076e97 | |||
| e73365b980 | |||
| 7eb473e67e | |||
| 1a5251dbf6 | |||
| eda48491e2 | |||
| a8f8911f03 | |||
| a9b90c4db8 | |||
| 60e4518230 | |||
| 7885c306ee | |||
| ede70380f2 | |||
| 8a94058d44 | |||
| 203e8a3ccc | |||
| a2723829da | |||
| ce6e5d4942 | |||
| 1a89fee665 | |||
| e9834110ec | |||
| e649b9ec54 | |||
| d5f413c5dc | |||
| 5aa16b4a97 | |||
| 442715334e | |||
| d55e9e9880 | |||
| 15cf8a750c | |||
| b2b15f825d | |||
| e544e955cb | |||
| c0a0a5d501 | |||
| 8ba9fb1f00 | |||
| 56ceafdaa6 | |||
| cbc07764a0 | |||
| 40d4d6576e | |||
| 147e8a2513 | |||
| ac95fb65c4 | |||
| 485b783341 | |||
| 2a9284473a | |||
| 1b4f1a8c5e | |||
| 7893c1d1ed | |||
| f3cf4a52ce | |||
| f330ccebf7 | |||
| e9affe31ae | |||
| 0767440e60 | |||
| ce52aa0ee9 | |||
| 68a50247bd | |||
| b4705c941f | |||
| 1eca428801 | |||
| a639e0c5e6 | |||
| 8c7349de12 | |||
| 4ce6abe1e8 | |||
| d04895144b | |||
| 847967c7b7 | |||
| a44c27f4bb | |||
| 58d29b19e9 | |||
| 9a6d92eefd | |||
| f713133a0a | |||
| fc89973848 | |||
| 05e6f6da4e | |||
| f2f54c1579 | |||
| 9a798df55a | |||
| d5d9f48d2d | |||
| 822cb7bac5 | |||
| 4c04f7a38c | |||
| 9b4608e31e | |||
| 763c4f5136 | |||
| b0918e65ff | |||
| 0c2b1a3856 | |||
| c5972bc023 | |||
| dfc864d131 | |||
| 8e55132ddd | |||
| cce99e6508 | |||
| 4b90c1c50a | |||
| d2f4d5d851 | |||
| 3cbc500361 | |||
| c28bacdfc7 | |||
| 452a2f6f04 | |||
| eb61fcb130 | |||
| 42c9e045b7 | |||
| 76cf47a070 | |||
| 0f34674d7f | |||
| 38c0cea40f | |||
| 8ef6de7ffd | |||
| 5daf81f331 | |||
| b6283cd13e | |||
| 01226a2910 | |||
| 87f373370e | |||
| 8a5d337775 | |||
| adc12dde4f | |||
| f9225d70a9 | |||
| 43ef6fa72c | |||
| df9713865f | |||
| 99dbdfe223 | |||
| a3bdf565fd | |||
| b15de7f54a | |||
| 062180db1e | |||
| b7c326a0a7 | |||
| 185173c821 | |||
| cc80fe7317 | |||
| c7448699b6 | |||
| 079d5a9ef1 | |||
| 0f942f73d9 | |||
| 6d2b63a5e9 | |||
| a035845b81 | |||
| e46ece3648 | |||
| 3e7064e166 | |||
| 048b36324c | |||
| 248ca6e30b | |||
| adcf3ebce8 | |||
| fd1d018e82 | |||
| a27494e17d | |||
| 319fc5e853 | |||
| 18d466803f | |||
| 2f0c9a9f04 | |||
| 692615c76d | |||
| 12d5d392c5 | |||
| da6cc0a2b8 | |||
| b095b799a0 | |||
| d49e0a6bc8 | |||
| b21bade6b5 | |||
| c3788e1a24 | |||
| 2853509d1d | |||
| 09a9f072cc | |||
| 088bbc6c58 | |||
| 962d0f1152 | |||
| 0377cd4287 | |||
| 803184cbe7 | |||
| 366a05c766 | |||
| f8ec857c16 | |||
| c781c24ae6 | |||
| 25a4bfd5ac | |||
| 94205b9ab2 | |||
| a470452e99 | |||
| 712a4c927b | |||
| 070833ed9c | |||
| 83d6277ae6 | |||
| 0f136d544c | |||
| e93190892b | |||
| 024245b780 | |||
| 5f7eed4194 | |||
| c60f6e0f0e | |||
| 07052f2530 | |||
| 99d83472cc | |||
| 394e2834e9 | |||
| 24ebc99b92 | |||
| 7c810ac052 | |||
| e2fcfbbc4a | |||
| cece2d77d4 | |||
| 4da225ec33 | |||
| 11b5b5b322 | |||
| 49456cb270 | |||
| 4ed259ff17 | |||
| d01657ab83 | |||
| 10f53bdbf7 | |||
| b9c8218ca4 | |||
| 8cfd915311 | |||
| 35d2ff6308 | |||
| 33bf5ebd49 | |||
| 8f89bf7361 | |||
| 38008bdb87 | |||
| 7408956f77 | |||
| 1d6a18a74c | |||
| 482dd614c9 | |||
| de402eaece | |||
| bb43bf61a8 | |||
| cc2a5f3ad9 | |||
| 4e1731f6e3 | |||
| af52aa9e51 | |||
| 56d8ca574e | |||
| 5588d7ca7d | |||
| 6c0cf6832e | |||
| ef59c4a61a | |||
| b34161b173 | |||
| 73cbc4314f | |||
| 207ae5195d | |||
| 68fbb914cd | |||
| c574b27d34 | |||
| 5e7bd75b36 | |||
| 6307dd51de | |||
| 29b289d2fb | |||
| 21b620c824 | |||
| e25015a60b | |||
| b0dac8454d | |||
| fc9a6b6517 | |||
| 14d4521f40 | |||
| 95054c1877 | |||
| 9b160153c1 | |||
| 3f494661e3 | |||
| 3cf2fc70a8 | |||
| c667ffb4e1 | |||
| 98c8d18a3e | |||
| f3b21cc75f | |||
| 5033e8fa8e | |||
| 22c433b3e4 | |||
| 6c97b5e736 | |||
| 61437db0d6 | |||
| 08dcbb9edb | |||
| eb36a96e29 | |||
| 8f9bf75613 | |||
| 80d87dea8c | |||
| f665a529e5 | |||
| c90f8efbdc | |||
| 2378be5021 | |||
| a29f34734b | |||
| ed67408d6e | |||
| 5124e0bf74 | |||
| 62ea87c709 | |||
| 5a69c14f61 | |||
| dcb0877c71 | |||
| 8b666064b2 | |||
| 5e76fabf21 | |||
| 33bd91764c | |||
| 37185c98b3 | |||
| fa893c94f1 | |||
| e62fe85867 | |||
| 41cd1d21f6 | |||
| 6bdd212336 | |||
| 82771832ed | |||
| eb25ddd864 | |||
| b1df5bb4d5 | |||
| cbf9d34738 | |||
| e480622f57 | |||
| 92ab035101 | |||
| 82d26b79a4 | |||
| 1d524b5815 | |||
| 148bea2827 | |||
| f8103af43c | |||
| 804b4e9c50 | |||
| c032978f05 | |||
| 8b23fb5c05 | |||
| e7cd1b295b | |||
| 492b2252bf | |||
| 91766e198d | |||
| 12e1bde2a2 | |||
| 76dfd103e7 | |||
| 37c09030bc | |||
| 2b38297da2 | |||
| 34eecd59f5 | |||
| f88a74e44a | |||
| 1187c2a200 | |||
| 69f236dbd3 | |||
| 1be75362d0 | |||
| 588488ce54 | |||
| 30379c981d | |||
| 994c11e8db | |||
| ccae4325c3 | |||
| 8b572515e0 | |||
| d328192834 | |||
| 5dd81430b7 | |||
| 06c006086b | |||
| c68d9d3bf5 | |||
| 1d91603e36 | |||
| 2e2b5261ae | |||
| c02c5c3c3d | |||
| 7974f0ff82 | |||
| a69f0a1924 | |||
| 29ba6b3658 | |||
| cd498e775b | |||
| 8029dbd1a8 | |||
| e4490faa2e | |||
| 7e4bcf18e4 | |||
| 7f049acf88 | |||
| 2d00640e06 | |||
| 358db1ca46 | |||
| e6feed1e26 | |||
| 224b8dcb70 | |||
| d0bd877b3f | |||
| 2ad61ff6b2 | |||
| 92c8b70fd2 | |||
| a03d46284c | |||
| 41fa46e954 | |||
| 8ec3a1208b | |||
| 2106ebde56 | |||
| fa163b3884 | |||
| fee637b02a | |||
| c75e54212b | |||
| 1a633778bc | |||
| 975a171d8c | |||
| 9e4bee1b67 | |||
| 1b1a4af5ea | |||
| e1e8d8cae3 | |||
| 50ca02442d | |||
| cd95c5ae37 | |||
| 7bb60de74e | |||
| 83937bb2ee | |||
| e7ae775842 | |||
| 06cb4c521c | |||
| 6b67d6b544 | |||
| d19d513ea8 | |||
| 726e79809d | |||
| efbcf1454e | |||
| a1e7e82d6d | |||
| e2c6d4b70c | |||
| 95c8c9c2b7 | |||
| f076409eb1 | |||
| 725f2096fe | |||
| 335d2af05b | |||
| bca34febcb | |||
| 6d883f43ab | |||
| 1b1dabafb8 | |||
| c39f434c6b | |||
| a799ee2b6d | |||
| 68f97d301d | |||
| cf6a5f6c0d | |||
| f7017892a5 | |||
| 01c39ffc15 | |||
| 90bb1aa61f | |||
| 377132321f | |||
| 5ceab766cc | |||
| 1c0ac08450 | |||
| 788b3721fd | |||
| ae334a5dfe | |||
| e36aea59a5 | |||
| c153239710 | |||
| bcbb5aaf19 | |||
| e65b08d2b3 | |||
| 05899fc185 | |||
| d5886c0920 | |||
| b1ac141ea5 | |||
| d30388a09a | |||
| 5e45e4f1f4 | |||
| 175bbb7743 | |||
| 7a434f69fd | |||
| 9b6249a1a7 | |||
| 77949bdc17 | |||
| 90c3536f3e | |||
| 910bf42da9 | |||
| 9209aa1cba | |||
| 64fe28a240 | |||
| 5eb7cef889 | |||
| 6e141f36c7 | |||
| 551a7cb6c0 | |||
| fa772ddd77 | |||
| 41ce5d1efe | |||
| f584138572 | |||
| df83001a64 | |||
| d99cfd92d9 | |||
| 4eaa54ecee | |||
| ccb6434fac | |||
| c7c752cd73 | |||
| b94bb79366 | |||
| dc88b885e9 | |||
| eb37d8123d | |||
| 9544a130ab | |||
| e0a793ea6d | |||
| 23e8bc0c5f | |||
| 8183c698da | |||
| 64afa9fb48 | |||
| 5f4b85b0a4 | |||
| 7a9ac3489b | |||
| 1d07b4f192 | |||
| f495b0575a | |||
| debeaa181c | |||
| 470ba28592 | |||
| acab824523 | |||
| 6c90ba2067 | |||
| be7a4e21f3 | |||
| 3bb3e5c88e | |||
| aa133b4606 | |||
| 1abc6f22d5 | |||
| 6e85ff674a | |||
| c9e8000c5f | |||
| 163af33c9b | |||
| 896e7e70b1 | |||
| af75dd38aa | |||
| 95b70018cc | |||
| b9ec015b4a | |||
| 7aac3917b7 | |||
| af14cd310b | |||
| 06e8365c06 | |||
| 7e3dc19c83 | |||
| c5b6e6e28c | |||
| 200937aa50 | |||
| 8956f524c9 | |||
| 45e554a9f9 | |||
| 5e05057240 | |||
| b64723323f | |||
| e049bf2dce | |||
| 3cdada41e0 | |||
| ceae6ffcba | |||
| 91b8912015 | |||
| efc6db71ab | |||
| 3b10476dc2 | |||
| cf86a951f5 | |||
| 35b8253776 | |||
| dac5afea60 | |||
| 17c6afceb4 | |||
| 1f92373a63 | |||
| 1eb6974d5d | |||
| 55d9ca0ffc | |||
| a193b8b1ef | |||
| 3198452b9c | |||
| 33d83d29a5 | |||
| 8d0ae21fb6 | |||
| 7de7b49e24 | |||
| 2c6f4f44d5 | |||
| 457c1fdc32 | |||
| 5c25eacd08 | |||
| da52c10f7f | |||
| 79b384a0d6 | |||
| bd005d52a7 | |||
| 6f06306f0c | |||
| afbff66e36 | |||
| 654e5868bc | |||
| 6f7fed4c6b | |||
| dc99157fbb | |||
| adc4a6e45f | |||
| 77b989d88d | |||
| 666fd385d1 | |||
| 5d1145be39 | |||
| fc0ad4c011 | |||
| 71a5a18257 | |||
| 15717557f1 | |||
| f06810d956 | |||
| 3b33b4e4d2 | |||
| d87d2e22cf | |||
| 6a0a2fc36c | |||
| ac5b4dd496 | |||
| 5760f78201 | |||
| e966bc0084 | |||
| 87264c443c | |||
| f9388b028a | |||
| 42ebc52c96 | |||
| d328431413 | |||
| 78d4cd50e8 | |||
| 5c1b87f254 | |||
| 6be7959cd1 | |||
| 3c3fe6caf8 | |||
| 212951c75d | |||
| 9546574f13 | |||
| c63dfd74f9 | |||
| 53a1be9b61 | |||
| 0c08f3d41c | |||
| 8dc7a9b5a0 | |||
| 405ef66b31 | |||
| 660da68a48 | |||
| f97cea2a17 | |||
| 771c0b96e3 | |||
| 09c497fef6 | |||
| 7170b049d3 | |||
| 4b9b1710eb | |||
| a49fba060c | |||
| 41222b09a7 | |||
| 886ee85a09 | |||
| d9f4def1d4 | |||
| cc2babde9c | |||
| 462521518f | |||
| 9c7db45a46 | |||
| 374be5256e | |||
| 83e3ab165e | |||
| cff4538b8c | |||
| d6798bdae3 | |||
| 34a98ebc4a | |||
| 38499e01bb | |||
| 35b2df2a2f | |||
| ce81ef5ef9 | |||
| 398543d67c | |||
| e790549d27 | |||
| 08518a9527 | |||
| b1ba5e9e6b | |||
| f33da76d1e | |||
| 1f0fdfc30e | |||
| 2bee9edd0b | |||
| 8d984cbc38 | |||
| e180694d9e | |||
| e285541203 | |||
| 175b49bc3a | |||
| 391f826de9 | |||
| ccecfc1898 | |||
| b06829eab1 | |||
| 449801b85b | |||
| 7d758d6d66 | |||
| 86828062e8 | |||
| d1f776b473 | |||
| ced4a2b7b9 | |||
| de562f8785 | |||
| 10457b31ec | |||
| 85f963720a | |||
| ed24e757e5 | |||
| e14aefaa8e | |||
| 45a35d8772 |
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Declare files that will always have LF line endings on checkout.
|
||||
# Necessary on windows, as the sointu-compiler formats .yml using only lf so
|
||||
# this would trigger changes in the files, even when they didn't really change.
|
||||
*.yml text eol=lf
|
||||
167
.github/workflows/binaries.yml
vendored
Normal file
167
.github/workflows/binaries.yml
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
name: Binaries
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
name: Create release
|
||||
runs-on: ubuntu-latest
|
||||
# Note this. We are going to use that in further jobs.
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref_name }}
|
||||
body_path: CHANGELOG.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
binaries:
|
||||
needs: create_release # we need to know the upload URL
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
output: sointu-track.exe
|
||||
params: cmd/sointu-track/main.go
|
||||
ldflags: -H=windowsgui
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
output: sointu-compile.exe
|
||||
params: cmd/sointu-compile/main.go
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
output: sointu-track-native.exe
|
||||
params: -tags=native cmd/sointu-track/main.go
|
||||
ldflags: -H=windowsgui
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
output: sointu-vsti.dll
|
||||
params: -buildmode=c-shared -tags=plugin ./cmd/sointu-vsti/
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
output: sointu-vsti-native.dll
|
||||
params: -buildmode=c-shared -tags="plugin,native" ./cmd/sointu-vsti/
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
output: sointu-track
|
||||
params: cmd/sointu-track/main.go
|
||||
packages: libegl-dev libvulkan-dev libxkbcommon-x11-dev libwayland-dev libasound2-dev libx11-xcb-dev libxcursor-dev libxfixes-dev
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
output: sointu-compile
|
||||
params: cmd/sointu-compile/main.go
|
||||
packages: libegl-dev libvulkan-dev libxkbcommon-x11-dev libwayland-dev libasound2-dev libx11-xcb-dev libxcursor-dev libxfixes-dev
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
output: sointu-track-native
|
||||
params: -tags=native cmd/sointu-track/main.go
|
||||
packages: libegl-dev libvulkan-dev libxkbcommon-x11-dev libwayland-dev libasound2-dev libx11-xcb-dev libxcursor-dev libxfixes-dev
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
output: sointu-vsti.so
|
||||
params: -buildmode=c-shared -tags=plugin ./cmd/sointu-vsti/
|
||||
packages: libegl-dev libvulkan-dev libxkbcommon-x11-dev libwayland-dev libasound2-dev libx11-xcb-dev libxcursor-dev libxfixes-dev
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
output: sointu-vsti-native.so
|
||||
params: -buildmode=c-shared -tags="plugin,native" ./cmd/sointu-vsti/
|
||||
packages: libegl-dev libvulkan-dev libxkbcommon-x11-dev libwayland-dev libasound2-dev libx11-xcb-dev libxcursor-dev libxfixes-dev
|
||||
- os: macos-latest
|
||||
asmnasm: /Users/runner/nasm/nasm
|
||||
output: sointu-track
|
||||
params: cmd/sointu-track/main.go
|
||||
- os: macos-latest
|
||||
asmnasm: /Users/runner/nasm/nasm
|
||||
output: sointu-compile
|
||||
params: cmd/sointu-compile/main.go
|
||||
- os: macos-12 # this is intel still
|
||||
asmnasm: /Users/runner/nasm/nasm
|
||||
output: sointu-track-native
|
||||
params: -tags=native cmd/sointu-track/main.go
|
||||
steps:
|
||||
- uses: benjlevesque/short-sha@v3.0
|
||||
id: short-sha
|
||||
with:
|
||||
length: 7
|
||||
- uses: lukka/get-cmake@latest
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v5 # has to be after checkout, see https://medium.com/@s0k0mata/github-actions-and-go-the-new-cache-feature-in-actions-setup-go-v4-and-what-to-watch-out-for-aeea373ed07d
|
||||
with:
|
||||
go-version: '>=1.21.0'
|
||||
- uses: ilammy/setup-nasm@v1.5.1
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: ${{ matrix.config.packages }}
|
||||
version: 1.0
|
||||
if: runner.os == 'Linux'
|
||||
- name: Build library
|
||||
env:
|
||||
ASM_NASM: ${{ matrix.config.asmnasm }}
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja ..
|
||||
ninja sointu
|
||||
- name: Build binary
|
||||
run: |
|
||||
go build -ldflags "-X github.com/vsariola/sointu/version.Version=$(git describe) ${{ matrix.config.ldflags}}" -o ${{ matrix.config.output }} ${{ matrix.config.params }}
|
||||
- name: Upload binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ runner.os }}-${{ steps.short-sha.outputs.sha }}-${{ matrix.config.output }}
|
||||
path: ${{ matrix.config.output }}
|
||||
upload_release_asset:
|
||||
needs: [create_release, binaries]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- os: Windows
|
||||
- os: Linux
|
||||
- os: macOS
|
||||
steps:
|
||||
- uses: benjlevesque/short-sha@v2.2
|
||||
id: short-sha
|
||||
with:
|
||||
length: 7
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ${{ matrix.config.os }}-${{ steps.short-sha.outputs.sha }}-*
|
||||
merge-multiple: true
|
||||
path: sointu-${{ matrix.config.os }}
|
||||
- name: Zip binaries
|
||||
run: |
|
||||
zip ./sointu-${{ matrix.config.os }}.zip sointu-${{ matrix.config.os }}/*
|
||||
- name: Upload release assets
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_name: sointu-${{ matrix.config.os }}.zip
|
||||
asset_path: ./sointu-${{ matrix.config.os }}.zip
|
||||
asset_content_type: application/octet-stream
|
||||
63
.github/workflows/tests.yml
vendored
Normal file
63
.github/workflows/tests.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# Run unit tests using CTest and go tests
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- os: ubuntu-latest
|
||||
asmnasm: /home/runner/nasm/nasm
|
||||
gotests: yes
|
||||
cgo_ldflags:
|
||||
- os: windows-latest
|
||||
asmnasm: C:\Users\runneradmin\nasm\nasm
|
||||
gotests: yes
|
||||
cgo_ldflags:
|
||||
- os: macos-12 # this is intel still
|
||||
asmnasm: /Users/runner/nasm/nasm
|
||||
gotests: yes
|
||||
cgo_ldflags: # -Wl,-no_pie
|
||||
# ld on mac is complaining about position dependent code so this would take the errors away, BUT
|
||||
# suddenly this causes an error, even though worked last week. Let's accept the warnings rather
|
||||
# than let the tests fail because of this.
|
||||
# TODO: win32 builds didn't quite work out, complains gcc broken
|
||||
steps:
|
||||
- uses: lukka/get-cmake@latest
|
||||
- uses: vsariola/setup-wabt@v1.0.2
|
||||
with:
|
||||
version: 1.0.29
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5 # has to be after checkout, see https://medium.com/@s0k0mata/github-actions-and-go-the-new-cache-feature-in-actions-setup-go-v4-and-what-to-watch-out-for-aeea373ed07d
|
||||
with:
|
||||
go-version: '>=1.21.0'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '15'
|
||||
- uses: ilammy/setup-nasm@v1.5.1
|
||||
- name: Run ctest
|
||||
env:
|
||||
ASM_NASM: ${{ matrix.config.asmnasm }}
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja ..
|
||||
ninja tests/all sointu
|
||||
ctest --output-on-failure
|
||||
- name: Run go test
|
||||
if: ${{ matrix.config.gotests == 'yes' }}
|
||||
env:
|
||||
CGO_LDFLAGS: ${{ matrix.config.cgo_ldflags }}
|
||||
run: |
|
||||
go test ./vm ./vm/compiler/bridge ./vm/compiler
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@ -11,4 +11,26 @@
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# CMake
|
||||
build/
|
||||
|
||||
# Project specific
|
||||
old/
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
|
||||
# project specific
|
||||
# this is autogenerated from bridge.go.in
|
||||
build/
|
||||
build32/
|
||||
build64/
|
||||
out/
|
||||
.cache/
|
||||
actual_output/
|
||||
**/__debug_bin
|
||||
*.exe
|
||||
*.dll
|
||||
|
||||
**/testdata/fuzz/
|
||||
.DS_Store
|
||||
522
4klang.go
Normal file
522
4klang.go
Normal file
@ -0,0 +1,522 @@
|
||||
package sointu
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Read4klangPatch reads a 4klang patch (a file usually with .4kp extension)
|
||||
// from r and returns a Patch, making best attempt to convert 4klang file to a
|
||||
// sointu Patch. It returns an error if the file is malformed or if the 4kp file
|
||||
// version is not supported.
|
||||
func Read4klangPatch(r io.Reader) (patch Patch, err error) {
|
||||
var versionTag uint32
|
||||
var version int
|
||||
var polyphonyUint32 uint32
|
||||
var instrumentNames [_4KLANG_MAX_INSTRS]string
|
||||
patch = make(Patch, 0)
|
||||
if err := binary.Read(r, binary.LittleEndian, &versionTag); err != nil {
|
||||
return nil, fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
var ok bool
|
||||
if version, ok = _4klangVersionTags[versionTag]; !ok {
|
||||
return nil, fmt.Errorf("unknown 4klang version tag: %d", versionTag)
|
||||
}
|
||||
if err := binary.Read(r, binary.LittleEndian, &polyphonyUint32); err != nil {
|
||||
return nil, fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
for i := range instrumentNames {
|
||||
instrumentNames[i], err = read4klangName(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read4klangName: %w", err)
|
||||
}
|
||||
}
|
||||
m := make(_4klangTargetMap)
|
||||
id := 1
|
||||
for instrIndex := 0; instrIndex < _4KLANG_MAX_INSTRS; instrIndex++ {
|
||||
var units []Unit
|
||||
if units, err = read4klangUnits(r, version, instrIndex, m, &id); err != nil {
|
||||
return nil, fmt.Errorf("read4klangUnits: %w", err)
|
||||
}
|
||||
if len(units) > 0 {
|
||||
patch = append(patch, Instrument{Name: instrumentNames[instrIndex], NumVoices: 1, Units: units})
|
||||
}
|
||||
}
|
||||
var units []Unit
|
||||
if units, err = read4klangUnits(r, version, _4KLANG_MAX_INSTRS, m, &id); err != nil {
|
||||
return nil, fmt.Errorf("read4klangUnits: %w", err)
|
||||
}
|
||||
if len(units) > 0 {
|
||||
patch = append(patch, Instrument{Name: "Global", NumVoices: 1, Units: units})
|
||||
}
|
||||
for i, instr := range patch {
|
||||
fix4klangTargets(i, instr, m)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Read4klangInstrument reads a 4klang instrument (a file usually with .4ki
|
||||
// extension) from r and returns an Instrument, making best attempt to convert
|
||||
// 4ki file to a sointu Instrument. It returns an error if the file is malformed
|
||||
// or if the 4ki file version is not supported.
|
||||
func Read4klangInstrument(r io.Reader) (instr Instrument, err error) {
|
||||
var versionTag uint32
|
||||
var version int
|
||||
var name string
|
||||
if err := binary.Read(r, binary.LittleEndian, &versionTag); err != nil {
|
||||
return Instrument{}, fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
var ok bool
|
||||
if version, ok = _4klangVersionTags[versionTag]; !ok {
|
||||
return Instrument{}, fmt.Errorf("unknown 4klang version tag: %d", versionTag)
|
||||
}
|
||||
if name, err = read4klangName(r); err != nil {
|
||||
return Instrument{}, fmt.Errorf("read4klangName: %w", err)
|
||||
}
|
||||
var units []Unit
|
||||
id := 1
|
||||
m := make(_4klangTargetMap)
|
||||
if units, err = read4klangUnits(r, version, 0, m, &id); err != nil {
|
||||
return Instrument{}, fmt.Errorf("read4klangUnits: %w", err)
|
||||
}
|
||||
ret := Instrument{Name: name, NumVoices: 1, Units: units}
|
||||
fix4klangTargets(0, ret, m)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type (
|
||||
_4klangStackUnit struct {
|
||||
stack, unit int
|
||||
}
|
||||
|
||||
_4klangTargetMap map[_4klangStackUnit]int
|
||||
|
||||
_4klangPorts struct {
|
||||
UnitType string
|
||||
PortName [8]string
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
_4KLANG_MAX_INSTRS = 16
|
||||
_4KLANG_MAX_UNITS = 64
|
||||
_4KLANG_MAX_SLOTS = 16
|
||||
_4KLANG_MAX_NAME_LEN = 64
|
||||
)
|
||||
|
||||
var (
|
||||
_4klangVersionTags map[uint32]int = map[uint32]int{
|
||||
0x31316b34: 11, // 4k11
|
||||
0x32316b34: 12, // 4k12
|
||||
0x33316b34: 13, // 4k13
|
||||
0x34316b34: 14, // 4k14
|
||||
}
|
||||
|
||||
_4klangDelays []int = []int{ // these are the numerators, if denominator is 48, fraction of beat time
|
||||
4, // 0 = 4.0f * (1.0f/32.0f) * (2.0f/3.0f)
|
||||
6, // 1 = 4.0f * (1.0f/32.0f),
|
||||
9, // 2 = 4.0f * (1.0f/32.0f) * (3.0f/2.0f),
|
||||
8, // 3 = 4.0f * (1.0f/16.0f) * (2.0f/3.0f),
|
||||
12, // 4 = 4.0f * (1.0f/16.0f),
|
||||
18, // 5 = 4.0f * (1.0f/16.0f) * (3.0f/2.0f),
|
||||
16, // 6 = 4.0f * (1.0f/8.0f) * (2.0f/3.0f),
|
||||
24, // 7 = 4.0f * (1.0f/8.0f),
|
||||
36, // 8 = 4.0f * (1.0f/8.0f) * (3.0f/2.0f),
|
||||
32, // 9 = 4.0f * (1.0f/4.0f) * (2.0f/3.0f),
|
||||
48, // 10 = 4.0f * (1.0f/4.0f),
|
||||
72, // 11 = 4.0f * (1.0f/4.0f) * (3.0f/2.0f),
|
||||
64, // 12 = 4.0f * (1.0f/2.0f) * (2.0f/3.0f),
|
||||
96, // 13 = 4.0f * (1.0f/2.0f),
|
||||
144, // 14 = 4.0f * (1.0f/2.0f) * (3.0f/2.0f),
|
||||
128, // 15 = 4.0f * (1.0f) * (2.0f/3.0f),
|
||||
192, // 16 = 4.0f * (1.0f),
|
||||
288, // 17 = 4.0f * (1.0f) * (3.0f/2.0f),
|
||||
256, // 18 = 4.0f * (2.0f) * (2.0f/3.0f),
|
||||
384, // 19 = 4.0f * (2.0f),
|
||||
576, // 20 = 4.0f * (2.0f) * (3.0f/2.0f),
|
||||
72, // 21 = 4.0f * (3.0f/8.0f),
|
||||
120, // 22 = 4.0f * (5.0f/8.0f),
|
||||
168, // 23 = 4.0f * (7.0f/8.0f),
|
||||
216, // 24 = 4.0f * (9.0f/8.0f),
|
||||
264, // 25 = 4.0f * (11.0f/8.0f),
|
||||
312, // 26 = 4.0f * (13.0f/8.0f),
|
||||
360, // 27 = 4.0f * (15.0f/8.0f),
|
||||
144, // 28 = 4.0f * (3.0f/4.0f),
|
||||
240, // 29 = 4.0f * (5.0f/4.0f),
|
||||
336, // 30 = 4.0f * (7.0f/4.0f),
|
||||
288, // 31 = 4.0f * (3.0f/2.0f),
|
||||
288, // 32 = 4.0f * (3.0f/2.0f),
|
||||
}
|
||||
|
||||
_4klangUnitPorts []_4klangPorts = []_4klangPorts{
|
||||
{"", [8]string{"", "", "", "", "", "", "", ""}},
|
||||
{"envelope", [8]string{"", "", "gain", "attack", "decay", "", "release", ""}},
|
||||
{"oscillator", [8]string{"", "transpose", "detune", "", "phase", "color", "shape", "gain"}},
|
||||
{"filter", [8]string{"", "", "", "", "frequency", "resonance", "", ""}},
|
||||
{"envelope", [8]string{"", "", "drive", "frequency", "", "", "", ""}},
|
||||
{"delay", [8]string{"pregain", "feedback", "dry", "damp", "", "", "", ""}},
|
||||
{"", [8]string{"", "", "", "", "", "", "", ""}},
|
||||
{"", [8]string{"", "", "", "", "", "", "", ""}},
|
||||
{"pan", [8]string{"panning", "", "", "", "", "", "", ""}},
|
||||
{"outaux", [8]string{"auxgain", "outgain", "", "", "", "", "", ""}},
|
||||
{"", [8]string{"", "", "", "", "", "", "", ""}},
|
||||
{"load", [8]string{"value", "", "", "", "", "", "", ""}},
|
||||
}
|
||||
)
|
||||
|
||||
func read4klangName(r io.Reader) (string, error) {
|
||||
var name [_4KLANG_MAX_NAME_LEN]byte
|
||||
if err := binary.Read(r, binary.LittleEndian, &name); err != nil {
|
||||
return "", fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
n := bytes.IndexByte(name[:], 0)
|
||||
if n == -1 {
|
||||
n = _4KLANG_MAX_NAME_LEN
|
||||
}
|
||||
return string(name[:n]), nil
|
||||
}
|
||||
|
||||
func read4klangUnits(r io.Reader, version, instrIndex int, m _4klangTargetMap, id *int) (units []Unit, err error) {
|
||||
numUnits := _4KLANG_MAX_UNITS
|
||||
if version <= 13 {
|
||||
numUnits = 32
|
||||
}
|
||||
units = make([]Unit, 0, numUnits)
|
||||
for unitIndex := 0; unitIndex < numUnits; unitIndex++ {
|
||||
var u []Unit
|
||||
if u, err = read4klangUnit(r, version); err != nil {
|
||||
return nil, fmt.Errorf("read4klangUnit: %w", err)
|
||||
}
|
||||
if u == nil {
|
||||
continue
|
||||
}
|
||||
m[_4klangStackUnit{instrIndex, unitIndex}] = *id
|
||||
for i := range u {
|
||||
u[i].ID = *id
|
||||
*id++
|
||||
}
|
||||
units = append(units, u...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func read4klangUnit(r io.Reader, version int) ([]Unit, error) {
|
||||
var unitType byte
|
||||
if err := binary.Read(r, binary.LittleEndian, &unitType); err != nil {
|
||||
return nil, fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
var vals [15]byte
|
||||
if err := binary.Read(r, binary.LittleEndian, &vals); err != nil {
|
||||
return nil, fmt.Errorf("binary.Read: %w", err)
|
||||
}
|
||||
if version <= 13 {
|
||||
// versions <= 13 had 16 unused slots for each unit
|
||||
if written, err := io.CopyN(io.Discard, r, 16); err != nil || written < 16 {
|
||||
return nil, fmt.Errorf("io.CopyN: %w", err)
|
||||
}
|
||||
}
|
||||
switch unitType {
|
||||
case 1:
|
||||
return read4klangENV(vals, version), nil
|
||||
case 2:
|
||||
return read4klangVCO(vals, version), nil
|
||||
case 3:
|
||||
return read4klangVCF(vals, version), nil
|
||||
case 4:
|
||||
return read4klangDST(vals, version), nil
|
||||
case 5:
|
||||
return read4klangDLL(vals, version), nil
|
||||
case 6:
|
||||
return read4klangFOP(vals, version), nil
|
||||
case 7:
|
||||
return read4klangFST(vals, version), nil
|
||||
case 8:
|
||||
return read4klangPAN(vals, version), nil
|
||||
case 9:
|
||||
return read4klangOUT(vals, version), nil
|
||||
case 10:
|
||||
return read4klangACC(vals, version), nil
|
||||
case 11:
|
||||
return read4klangFLD(vals, version), nil
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func read4klangENV(vals [15]byte, version int) []Unit {
|
||||
return []Unit{{
|
||||
Type: "envelope",
|
||||
Parameters: map[string]int{
|
||||
"stereo": 0,
|
||||
"attack": int(vals[0]),
|
||||
"decay": int(vals[1]),
|
||||
"sustain": int(vals[2]),
|
||||
"release": int(vals[3]),
|
||||
"gain": int(vals[4]),
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangVCO(vals [15]byte, version int) []Unit {
|
||||
v := vals[:8]
|
||||
var transpose, detune, phase, color, gate, shape, gain, flags, stereo, typ, lfo int
|
||||
transpose, v = int(v[0]), v[1:]
|
||||
detune, v = int(v[0]), v[1:]
|
||||
phase, v = int(v[0]), v[1:]
|
||||
if version <= 11 {
|
||||
gate = 0x55
|
||||
} else {
|
||||
gate, v = int(v[0]), v[1:]
|
||||
}
|
||||
color, v = int(v[0]), v[1:]
|
||||
shape, v = int(v[0]), v[1:]
|
||||
gain, v = int(v[0]), v[1:]
|
||||
flags, v = int(v[0]), v[1:]
|
||||
if flags&0x10 == 0x10 {
|
||||
lfo = 1
|
||||
}
|
||||
if flags&0x40 == 0x40 {
|
||||
stereo = 1
|
||||
}
|
||||
switch {
|
||||
case flags&0x01 == 0x01: // Sine
|
||||
typ = Sine
|
||||
if version <= 13 {
|
||||
color = 128
|
||||
}
|
||||
case flags&0x02 == 0x02: // Trisaw
|
||||
typ = Trisaw
|
||||
case flags&0x04 == 0x04: // Pulse
|
||||
typ = Pulse
|
||||
case flags&0x08 == 0x08: // Noise is handled differently in sointu
|
||||
return []Unit{{
|
||||
Type: "noise",
|
||||
Parameters: map[string]int{
|
||||
"stereo": stereo,
|
||||
"shape": shape,
|
||||
"gain": gain,
|
||||
},
|
||||
}}
|
||||
case flags&0x20 == 0x20: // Gate
|
||||
color = gate
|
||||
}
|
||||
return []Unit{{
|
||||
Type: "oscillator",
|
||||
Parameters: map[string]int{
|
||||
"stereo": stereo,
|
||||
"transpose": transpose,
|
||||
"detune": detune,
|
||||
"phase": phase,
|
||||
"color": color,
|
||||
"shape": shape,
|
||||
"gain": gain,
|
||||
"type": typ,
|
||||
"lfo": lfo,
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangVCF(vals [15]byte, version int) []Unit {
|
||||
flags := vals[2]
|
||||
var stereo, lowpass, bandpass, highpass, neghighpass int
|
||||
if flags&0x01 == 0x01 {
|
||||
lowpass = 1
|
||||
}
|
||||
if flags&0x02 == 0x02 {
|
||||
highpass = 1
|
||||
}
|
||||
if flags&0x04 == 0x04 {
|
||||
bandpass = 1
|
||||
}
|
||||
if flags&0x08 == 0x08 {
|
||||
lowpass = 1
|
||||
neghighpass = 1
|
||||
}
|
||||
if flags&0x10 == 0x10 {
|
||||
stereo = 1
|
||||
}
|
||||
return []Unit{{
|
||||
Type: "filter",
|
||||
Parameters: map[string]int{
|
||||
"stereo": stereo,
|
||||
"frequency": int(vals[0]),
|
||||
"resonance": int(vals[1]),
|
||||
"lowpass": lowpass,
|
||||
"bandpass": bandpass,
|
||||
"highpass": highpass,
|
||||
"negbandpass": 0,
|
||||
"neghighpass": neghighpass,
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func read4klangDST(vals [15]byte, version int) []Unit {
|
||||
return []Unit{
|
||||
{Type: "distort", Parameters: map[string]int{"drive": int(vals[0]), "stereo": int(vals[2])}},
|
||||
{Type: "hold", Parameters: map[string]int{"holdfreq": int(vals[1]), "stereo": int(vals[2])}},
|
||||
}
|
||||
}
|
||||
|
||||
func read4klangDLL(vals [15]byte, version int) []Unit {
|
||||
var delaytimes []int
|
||||
var notetracking int
|
||||
if vals[11] > 0 {
|
||||
if vals[10] > 0 { // left reverb
|
||||
delaytimes = []int{1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618}
|
||||
} else { // right reverb
|
||||
delaytimes = []int{1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642}
|
||||
}
|
||||
} else {
|
||||
synctype := vals[9]
|
||||
switch synctype {
|
||||
case 0:
|
||||
delaytimes = []int{int(vals[8]) * 16}
|
||||
case 1: // relative to BPM
|
||||
notetracking = 2
|
||||
index := vals[8] >> 2
|
||||
delaytime := 48
|
||||
if int(index) < len(_4klangDelays) {
|
||||
delaytime = _4klangDelays[index]
|
||||
}
|
||||
delaytimes = []int{delaytime}
|
||||
case 2: // notetracking
|
||||
notetracking = 1
|
||||
delaytimes = []int{10787}
|
||||
}
|
||||
}
|
||||
return []Unit{{
|
||||
Type: "delay",
|
||||
Parameters: map[string]int{
|
||||
"stereo": 0,
|
||||
"pregain": int(vals[0]),
|
||||
"dry": int(vals[1]),
|
||||
"feedback": int(vals[2]),
|
||||
"damp": int(vals[3]),
|
||||
"notetracking": notetracking,
|
||||
},
|
||||
VarArgs: delaytimes,
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangFOP(vals [15]byte, version int) []Unit {
|
||||
var t string
|
||||
var stereo int
|
||||
switch vals[0] {
|
||||
case 1:
|
||||
t, stereo = "pop", 0
|
||||
case 2:
|
||||
t, stereo = "addp", 0
|
||||
case 3:
|
||||
t, stereo = "mulp", 0
|
||||
case 4:
|
||||
t, stereo = "push", 0
|
||||
case 5:
|
||||
t, stereo = "xch", 0
|
||||
case 6:
|
||||
t, stereo = "add", 0
|
||||
case 7:
|
||||
t, stereo = "mul", 0
|
||||
case 8:
|
||||
t, stereo = "addp", 1
|
||||
case 9:
|
||||
return []Unit{{Type: "loadnote", Parameters: map[string]int{"stereo": stereo}}, // 4klang loadnote gives 0..1, sointu gives -1..1
|
||||
{Type: "loadval", Parameters: map[string]int{"value": 128, "stereo": stereo}},
|
||||
{Type: "addp", Parameters: map[string]int{"stereo": stereo}},
|
||||
{Type: "gain", Parameters: map[string]int{"stereo": stereo, "gain": 64}}}
|
||||
default:
|
||||
t, stereo = "mulp", 1
|
||||
}
|
||||
return []Unit{{
|
||||
Type: t,
|
||||
Parameters: map[string]int{"stereo": stereo},
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangFST(vals [15]byte, version int) []Unit {
|
||||
sendpop := 0
|
||||
if vals[1]&0x40 == 0x40 {
|
||||
sendpop = 1
|
||||
}
|
||||
return []Unit{{
|
||||
Type: "send",
|
||||
Parameters: map[string]int{
|
||||
"amount": int(vals[0]),
|
||||
"sendpop": sendpop,
|
||||
"dest_stack": int(vals[2]),
|
||||
"dest_unit": int(vals[3]),
|
||||
"dest_slot": int(vals[4]),
|
||||
"dest_id": int(vals[5]),
|
||||
}}}
|
||||
}
|
||||
|
||||
func fix4klangTargets(instrIndex int, instr Instrument, m _4klangTargetMap) {
|
||||
for _, u := range instr.Units {
|
||||
if u.Type == "send" {
|
||||
destStack := u.Parameters["dest_stack"]
|
||||
if destStack == 255 {
|
||||
destStack = instrIndex
|
||||
}
|
||||
fourKlangTarget := _4klangStackUnit{
|
||||
destStack,
|
||||
u.Parameters["dest_unit"]}
|
||||
u.Parameters["target"] = m[fourKlangTarget]
|
||||
if u.Parameters["dest_id"] < len(_4klangUnitPorts) && u.Parameters["dest_slot"] < 8 {
|
||||
if u.Parameters["dest_id"] == 4 && u.Parameters["dest_slot"] == 3 { // distortion is split into 2 units
|
||||
u.Parameters["target"]++
|
||||
u.Parameters["port"] = 0
|
||||
} else {
|
||||
modTarget := _4klangUnitPorts[u.Parameters["dest_id"]]
|
||||
for i, s := range Ports[modTarget.UnitType] {
|
||||
if s == modTarget.PortName[u.Parameters["dest_slot"]] {
|
||||
u.Parameters["port"] = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(u.Parameters, "dest_stack")
|
||||
delete(u.Parameters, "dest_unit")
|
||||
delete(u.Parameters, "dest_slot")
|
||||
delete(u.Parameters, "dest_id")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func read4klangPAN(vals [15]byte, version int) []Unit {
|
||||
return []Unit{{
|
||||
Type: "pan",
|
||||
Parameters: map[string]int{
|
||||
"stereo": 0,
|
||||
"panning": int(vals[0]),
|
||||
}}}
|
||||
}
|
||||
|
||||
func read4klangOUT(vals [15]byte, version int) []Unit {
|
||||
return []Unit{{
|
||||
Type: "outaux",
|
||||
Parameters: map[string]int{
|
||||
"stereo": 1,
|
||||
"outgain": int(vals[0]),
|
||||
"auxgain": int(vals[1])},
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangACC(vals [15]byte, version int) []Unit {
|
||||
c := 0
|
||||
if vals[0] != 0 {
|
||||
c = 2
|
||||
}
|
||||
return []Unit{{
|
||||
Type: "in",
|
||||
Parameters: map[string]int{"stereo": 1, "channel": c},
|
||||
}}
|
||||
}
|
||||
|
||||
func read4klangFLD(vals [15]byte, version int) []Unit {
|
||||
return []Unit{{
|
||||
Type: "loadval",
|
||||
Parameters: map[string]int{"stereo": 0, "value": int(vals[0])},
|
||||
}}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,898 +0,0 @@
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // useful macros
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // export function (make it accessable from main.cpp)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%macro export_func 1
|
||||
global _%1
|
||||
_%1:
|
||||
%endmacro
|
||||
%define USE_SECTIONS
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // basic defines for the song/synth
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%define SAMPLE_RATE 44100
|
||||
%define MAX_INSTRUMENTS 9
|
||||
%define MAX_VOICES 1
|
||||
%define HLD 1 ; // can be adjusted to give crinkler some other possibilities
|
||||
%define BPM 100
|
||||
%define MAX_PATTERNS 62
|
||||
%define PATTERN_SIZE_SHIFT 4
|
||||
%define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
%define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
%define SAMPLES_PER_TICK (SAMPLE_RATE*4*60/(BPM*16))
|
||||
%define DEF_LFO_NORMALIZE 0.000038
|
||||
%define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // some defines for unit usage, which reduce synth code size
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;%define GO4K_USE_16BIT_OUTPUT ; // removing this will output to 32bit floating point buffer
|
||||
;%define GO4K_USE_GROOVE_PATTERN ; // removing this skips groove pattern code
|
||||
;%define GO4K_USE_ENVELOPE_RECORDINGS ; // removing this skips envelope recording code
|
||||
;%define GO4K_USE_NOTE_RECORDINGS ; // removing this skips note recording code
|
||||
%define GO4K_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units
|
||||
%define GO4K_CLIP_OUTPUT ; // removing this skips clipping code for the final output
|
||||
%define GO4K_USE_DST ; // removing this will skip DST unit
|
||||
%define GO4K_USE_DLL ; // removing this will skip DLL unit
|
||||
%define GO4K_USE_PAN ; // removing this will skip PAN unit
|
||||
%define GO4K_USE_GLOBAL_DLL ; // removing this will skip global dll processing
|
||||
%define GO4K_USE_FSTG ; // removing this will skip global store unit
|
||||
%define GO4K_USE_FLD ; // removing this will skip float load unit
|
||||
%define GO4K_USE_ENV_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_ENV_MOD_GM ; // removing this will skip env gain modulation code
|
||||
%define GO4K_USE_ENV_MOD_ADR ; // removing this will skip env attack/decay/release modulation code
|
||||
%define GO4K_USE_VCO_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code
|
||||
%define GO4K_USE_VCO_SHAPE ; // removing this skips waveshaping code
|
||||
%define GO4K_USE_VCO_GATE ; // removing this skips gate code
|
||||
%define GO4K_USE_VCO_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCO_MOD_PM ; // removing this skips phase modulation code
|
||||
%define GO4K_USE_VCO_MOD_TM ; // removing this skips transpose modulation code
|
||||
%define GO4K_USE_VCO_MOD_DM ; // removing this skips detune modulation code
|
||||
%define GO4K_USE_VCO_MOD_CM ; // removing this skips color modulation code
|
||||
%define GO4K_USE_VCO_MOD_GM ; // removing this skips gain modulation code
|
||||
%define GO4K_USE_VCO_MOD_SM ; // removing this skips shaping modulation code
|
||||
%define GO4K_USE_VCF_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCF_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCF_MOD_RM ; // removing this skips resonance modulation code
|
||||
%define GO4K_USE_VCF_HIGH ; // removing this skips code for high output
|
||||
%define GO4K_USE_VCF_BAND ; // removing this skips code for band output
|
||||
%define GO4K_USE_VCF_PEAK ; // removing this skips code for peak output
|
||||
%define GO4K_USE_DST_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_DST_SH ; // removing this skips sample and hold code
|
||||
%define GO4K_USE_DST_MOD_DM ; // removing this skips distortion modulation code
|
||||
%define GO4K_USE_DST_MOD_SH ; // removing this skips sample and hold modulation code
|
||||
%define GO4K_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong)
|
||||
%define GO4K_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code
|
||||
%define GO4K_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping
|
||||
%define GO4K_USE_DLL_DAMP ; // removing this will skip dll damping code
|
||||
%define GO4K_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code
|
||||
%define GO4K_USE_FOP_LOADNOTE ; // removing this will skip load note code
|
||||
%define GO4K_USE_FSTG_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_PAN_MOD ; // removing this will skip panning modulation code
|
||||
%define GO4K_USE_OUT_MOD_AM ; // removing this skips output aux send modulation code
|
||||
%define GO4K_USE_OUT_MOD_GM ; // removing this skips output gain modulation code
|
||||
%define GO4K_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code
|
||||
%define GO4K_USE_FLD_MOD_VM ; // removing this will skip float load modulation code
|
||||
%define GO4K_USE_DLL_MOD ; // define this to enable modulations for delay line
|
||||
%define GO4K_USE_DLL_MOD_PM ; // define this to enable pregain modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_FM ; // define this to enable feebback modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_IM ; // define this to enable dry modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_DM ; // define this to enable damping modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_SM ; // define this to enable lfo freq modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_AM ; // define this to enable lfo depth modulation for delay line
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // synth defines
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%define MAX_DELAY 65536
|
||||
%define MAX_WORKSPACE_SLOTS 8
|
||||
%define GO4K_BEGIN_CMDDEF(def_name)
|
||||
%define GO4K_END_CMDDEF db 0
|
||||
%define GO4K_BEGIN_PARAMDEF(def_name)
|
||||
%define GO4K_END_PARAMDEF
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ENV structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ENV_ID equ 1
|
||||
%macro GO4K_ENV 5
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
%endmacro
|
||||
%define ATTAC(val) val
|
||||
%define DECAY(val) val
|
||||
%define SUSTAIN(val) val
|
||||
%define RELEASE(val) val
|
||||
%define GAIN(val) val
|
||||
struc go4kENV_val
|
||||
;// unit paramters
|
||||
.attac resd 1
|
||||
.decay resd 1
|
||||
.sustain resd 1
|
||||
.release resd 1
|
||||
.gain resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kENV_wrk
|
||||
;// work variables
|
||||
.state resd 1
|
||||
.level resd 1
|
||||
;// modulation targets
|
||||
.gm resd 1
|
||||
.am resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%define ENV_STATE_ATTAC 0
|
||||
%define ENV_STATE_DECAY 1
|
||||
%define ENV_STATE_SUSTAIN 2
|
||||
%define ENV_STATE_RELEASE 3
|
||||
%define ENV_STATE_OFF 4
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCO structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCO_ID equ 2
|
||||
|
||||
%macro GO4K_VCO 8
|
||||
db %1
|
||||
db %2
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
db %3
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
db %4
|
||||
%endif
|
||||
db %5
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
db %6
|
||||
%else
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define TRANSPOSE(val) val
|
||||
%define DETUNE(val) val
|
||||
%define PHASE(val) val
|
||||
%define GATES(val) val
|
||||
%define COLOR(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
%define SINE 0x01
|
||||
%define TRISAW 0x02
|
||||
%define PULSE 0x04
|
||||
%define NOISE 0x08
|
||||
%define LFO 0x10
|
||||
%define GATE 0x20
|
||||
struc go4kVCO_val
|
||||
;// unit paramters
|
||||
.transpose resd 1
|
||||
.detune resd 1
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
.phaseofs resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
.gate resd 1
|
||||
%endif
|
||||
.color resd 1
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
.shape resd 1
|
||||
%endif
|
||||
.gain resd 1
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCO_wrk
|
||||
;// work variables
|
||||
.phase resd 1
|
||||
;// modulation targets
|
||||
.tm resd 1
|
||||
.dm resd 1
|
||||
.fm resd 1
|
||||
.pm resd 1
|
||||
.cm resd 1
|
||||
.sm resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCF structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCF_ID equ 3
|
||||
%macro GO4K_VCF 3
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%endmacro
|
||||
%define LOWPASS 0x1
|
||||
%define HIGHPASS 0x2
|
||||
%define BANDPASS 0x4
|
||||
%define BANDSTOP 0x3
|
||||
%define ALLPASS 0x7
|
||||
%define PEAK 0x8
|
||||
%define FREQUENCY(val) val
|
||||
%define RESONANCE(val) val
|
||||
%define VCFTYPE(val) val
|
||||
struc go4kVCF_val
|
||||
;// unit paramters
|
||||
.freq resd 1
|
||||
.res resd 1
|
||||
.type resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCF_wrk
|
||||
;// work variables
|
||||
.low resd 1
|
||||
.high resd 1
|
||||
.band resd 1
|
||||
.freq resd 1
|
||||
;// modulation targets
|
||||
.fm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DST_ID equ 4
|
||||
%macro GO4K_DST 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define DRIVE(val) val
|
||||
%define SNHFREQ(val) val
|
||||
struc go4kDST_val
|
||||
;// unit paramters
|
||||
.drive resd 1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
.snhfreq resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDST_wrk
|
||||
.out resd 1
|
||||
.snhphase resd 1
|
||||
;// modulation targets
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DLL structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DLL_ID equ 5
|
||||
%macro GO4K_DLL 8
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
db %4
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
db %5
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define PREGAIN(val) val
|
||||
%define DRY(val) val
|
||||
%define FEEDBACK(val) val
|
||||
%define DEPTH(val) val
|
||||
%define DAMP(val) val
|
||||
%define DELAY(val) val
|
||||
%define COUNT(val) val
|
||||
struc go4kDLL_val
|
||||
;// unit paramters
|
||||
.pregain resd 1
|
||||
.dry resd 1
|
||||
.feedback resd 1
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
.damp resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
.freq resd 1
|
||||
.depth
|
||||
%endif
|
||||
.delay resd 1
|
||||
.count resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk
|
||||
;// work variables
|
||||
.index resd 1
|
||||
.store resd 1
|
||||
.dcin resd 1
|
||||
.dcout resd 1
|
||||
.phase resd 1
|
||||
;// the delay buffer
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk2
|
||||
;// modulation targets
|
||||
.pm resd 1
|
||||
.fm resd 1
|
||||
.im resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.am resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FOP structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FOP_ID equ 6
|
||||
%macro GO4K_FOP 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OP(val) val
|
||||
%define FOP_POP 0x1
|
||||
%define FOP_ADDP 0x2
|
||||
%define FOP_MULP 0x3
|
||||
%define FOP_PUSH 0x4
|
||||
%define FOP_XCH 0x5
|
||||
%define FOP_ADD 0x6
|
||||
%define FOP_MUL 0x7
|
||||
%define FOP_ADDP2 0x8
|
||||
%define FOP_LOADNOTE 0x9
|
||||
struc go4kFOP_val
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFOP_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FST_ID equ 7
|
||||
%macro GO4K_FST 2
|
||||
db %1
|
||||
db %2
|
||||
%endmacro
|
||||
%define AMOUNT(val) val
|
||||
%define DEST(val) val
|
||||
struc go4kFST_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFST_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // PAN structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_PAN_ID equ 8
|
||||
%macro GO4K_PAN 1
|
||||
%ifdef GO4K_USE_PAN
|
||||
db %1
|
||||
%endif
|
||||
%endmacro
|
||||
%define PANNING(val) val
|
||||
struc go4kPAN_val
|
||||
%ifdef GO4K_USE_PAN
|
||||
.panning resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kPAN_wrk
|
||||
;// modulation targets
|
||||
.pm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // OUT structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_OUT_ID equ 9
|
||||
%macro GO4K_OUT 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define AUXSEND(val) val
|
||||
struc go4kOUT_val
|
||||
.gain resd 1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
.auxsend resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kOUT_wrk
|
||||
;// modulation targets
|
||||
.am resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ACC structs (this is for the synth def only)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ACC_ID equ 10
|
||||
%macro GO4K_ACC 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OUTPUT 0
|
||||
%define AUX 8
|
||||
%define ACCTYPE(val) val
|
||||
struc go4kACC_val
|
||||
.acctype resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kACC_wrk
|
||||
.size
|
||||
endstruc
|
||||
%ifdef GO4K_USE_FLD
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FLD structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FLD_ID equ 11
|
||||
%macro GO4K_FLD 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define VALUE(val) val
|
||||
struc go4kFLD_val
|
||||
.value resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFLD_wrk
|
||||
;// modulation targets
|
||||
.vm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
%ifdef GO4K_USE_FSTG
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FSTG structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FSTG_ID equ 12
|
||||
%macro GO4K_FSTG 2
|
||||
db %1
|
||||
dd %2
|
||||
%endmacro
|
||||
struc go4kFSTG_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFSTG_wrk
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Voice struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_instrument
|
||||
.release resd 1
|
||||
.note resd 1
|
||||
.workspace resd 256
|
||||
.dlloutl resd 1
|
||||
.dlloutr resd 1
|
||||
.outl resd 1
|
||||
.outr resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Synth struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_synth
|
||||
.instruments resb go4k_instrument.size * MAX_INSTRUMENTS * MAX_VOICES
|
||||
.global resb go4k_instrument.size * MAX_VOICES
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Data, reduced by 967 patterns
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc1 data align=1
|
||||
%else
|
||||
section .data align=1
|
||||
%endif
|
||||
go4k_patterns
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 81, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 84, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 88, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 52, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 57, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 60, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 64, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 72, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 64, HLD, 40, 52, 64, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 57, 0, 0, 57, 0, 0, 69, 0, 0, 69, 0, 0, 57, HLD, HLD, HLD,
|
||||
db 52, 64, 0, 57, 0, 69, 48, 0, 48, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 40, HLD, 40, 40, 40, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, 0, 0, 52, 0, 0, 40, 0, 52, 40, 0, 52, 0, 40, 0, 0,
|
||||
db 45, 0, 0, 57, 0, 0, 45, 0, 57, 45, 0, 57, 0, 45, 0, 0,
|
||||
db 48, 0, 0, 60, 0, 0, 48, 0, 60, 48, 0, 60, 0, 48, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 45, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 36, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 60, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 60, HLD, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 60, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
|
||||
db 91, 0, 0, 88, 0, 0, 76, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 88, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 84, 0, 0, 86, 0, 0, 88, 0, 0, 91, 0, 0, 84, 0, 0, 0,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
go4k_patterns_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Index List
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc2 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_pattern_lists
|
||||
Instrument0List db 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 1, 2, 3, 0, 4, 5, 6, 7, 8, 2, 9, 0, 0, 0,
|
||||
Instrument1List db 9, 7, 10, 7, 11, 7, 12, 7, 9, 7, 10, 7, 11, 7, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 13, 7, 14, 7, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 0, 0,
|
||||
Instrument2List db 15, 0, 16, 0, 17, 0, 18, 0, 19, 0, 16, 0, 17, 0, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 23, 15, 24, 16, 25, 17, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 0, 0, 0, 0,
|
||||
Instrument3List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0,
|
||||
Instrument4List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 29, 27, 29, 27, 29, 27, 29, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 0, 0, 0,
|
||||
Instrument5List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 0, 0,
|
||||
Instrument6List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 0, 0, 0, 0,
|
||||
Instrument7List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, 0, 37, 38, 36, 0, 39, 35, 36, 0, 37, 38, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument8List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 41, 0,
|
||||
go4k_pattern_lists_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Instrument Commands
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc3 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_instructions
|
||||
GO4K_BEGIN_CMDDEF(Instrument0)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument1)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument2)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument3)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument4)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument5)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument6)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument7)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument8)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FOP_ID
|
||||
GO4K_END_CMDDEF
|
||||
;// global commands
|
||||
GO4K_BEGIN_CMDDEF(Global)
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
go4k_synth_instructions_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Intrument Data
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc4 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_parameter_values
|
||||
GO4K_BEGIN_PARAMDEF(Instrument0)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
GO4K_FST AMOUNT(64),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(61),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(26),RESONANCE(128),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(104), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument1)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
GO4K_FST AMOUNT(64),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(112),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(80),DETUNE(112),PHASE(0),GATES(0),COLOR(64),SHAPE(16),GAIN(128),FLAGS(PULSE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(60),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(24),VCFTYPE(LOWPASS)
|
||||
GO4K_VCF FREQUENCY(48),RESONANCE(24),VCFTYPE(HIGHPASS)
|
||||
GO4K_DST DRIVE(64), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument2)
|
||||
GO4K_ENV ATTAC(32),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(64)
|
||||
GO4K_FST AMOUNT(120),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(60),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(18),RESONANCE(64),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(32),RESONANCE(48),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(88), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument3)
|
||||
GO4K_ENV ATTAC(0),DECAY(76),SUSTAIN(0),RELEASE(0),GAIN(32)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument4)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(96),RELEASE(64),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(70),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_DST DRIVE(32), SNHFREQ(128)
|
||||
GO4K_FST AMOUNT(80),DEST(6*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(46),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(128), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument5)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(128),RESONANCE(128),VCFTYPE(BANDPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument6)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(72),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(56),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_FST AMOUNT(108),DEST(6*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FST AMOUNT(72),DEST(7*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(32),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(80),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(64),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(104),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(22),RESONANCE(32),VCFTYPE(HIGHPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument7)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(96),RELEASE(32),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument8)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(128),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(48),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW|LFO)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_FSTG AMOUNT(72),DEST(2*go4k_instrument.size*MAX_VOICES+10*MAX_WORKSPACE_SLOTS*4+4*4+go4k_instrument.workspace)
|
||||
GO4K_FSTG AMOUNT(66),DEST(1*go4k_instrument.size*MAX_VOICES+10*MAX_WORKSPACE_SLOTS*4+4*4+go4k_instrument.workspace)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_END_PARAMDEF
|
||||
;// global parameters
|
||||
GO4K_BEGIN_PARAMDEF(Global)
|
||||
GO4K_ACC ACCTYPE(AUX)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(0),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(8),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_ACC ACCTYPE(OUTPUT)
|
||||
GO4K_FOP OP(FOP_ADDP2)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
go4k_synth_parameter_values_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Delay/Reverb Times
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc5 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL
|
||||
global _go4k_delay_times
|
||||
_go4k_delay_times
|
||||
dw 0
|
||||
dw 1116
|
||||
dw 1188
|
||||
dw 1276
|
||||
dw 1356
|
||||
dw 1422
|
||||
dw 1492
|
||||
dw 1556
|
||||
dw 1618
|
||||
dw 1140
|
||||
dw 1212
|
||||
dw 1300
|
||||
dw 1380
|
||||
dw 1446
|
||||
dw 1516
|
||||
dw 1580
|
||||
dw 1642
|
||||
times 100 dw 0
|
||||
%endif
|
||||
@ -1,131 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#ifndef __Go4kVSTi__
|
||||
#include "Go4kVSTi.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Go4kVSTi
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
Go4kVSTi::Go4kVSTi (audioMasterCallback audioMaster) : AudioEffectX (audioMaster, 0, 0)
|
||||
{
|
||||
if (audioMaster)
|
||||
{
|
||||
setNumInputs (0); // no inputs
|
||||
setNumOutputs (2); // 2 outputs, stereo
|
||||
canProcessReplacing ();
|
||||
hasVu (false);
|
||||
hasClip (false);
|
||||
isSynth ();
|
||||
setUniqueID ('4klg');
|
||||
}
|
||||
initProcess ();
|
||||
suspend ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
Go4kVSTi::~Go4kVSTi ()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setProgram (long program)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setProgramName (char *name)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getProgramName (char *name)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterLabel (long index, char *label)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterDisplay (long index, char *text)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterName (long index, char *label)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setParameter (long index, float value)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float Go4kVSTi::getParameter (long index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getOutputProperties (long index, VstPinProperties* properties)
|
||||
{
|
||||
if (index < 2)
|
||||
{
|
||||
sprintf (properties->label, "Vstx %1d", index + 1);
|
||||
properties->flags = kVstPinIsActive;
|
||||
properties->flags |= kVstPinIsStereo; // test, make channel 1+2 stereo
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getProgramNameIndexed (long category, long index, char* text)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::copyProgram (long destination)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getEffectName (char* name)
|
||||
{
|
||||
strcpy (name, "4klang");
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getVendorString (char* text)
|
||||
{
|
||||
strcpy (text, "Alcatraz");
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getProductString (char* text)
|
||||
{
|
||||
strcpy (text, "4klang");
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::canDo (char* text)
|
||||
{
|
||||
if (!strcmp (text, "receiveVstEvents"))
|
||||
return 1;
|
||||
if (!strcmp (text, "receiveVstMidiEvent"))
|
||||
return 1;
|
||||
if (!strcmp (text, "receiveVstTimeInfo"))
|
||||
return 1;
|
||||
return -1; // explicitly can't do; 0 => don't know
|
||||
}
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
#ifndef __Go4kVSTi__
|
||||
#define __Go4kVSTi__
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#ifndef __AudioEffectX__
|
||||
#include "audioeffectx.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
class Go4kVSTi : public AudioEffectX
|
||||
{
|
||||
public:
|
||||
Go4kVSTi(audioMasterCallback audioMaster);
|
||||
~Go4kVSTi();
|
||||
|
||||
virtual void process(float **inputs, float **outputs, long sampleframes);
|
||||
virtual void processReplacing(float **inputs, float **outputs, long sampleframes);
|
||||
void processAnyhow(float **inputs, float **outputs, long sampleFrames);
|
||||
virtual long processEvents(VstEvents* events);
|
||||
|
||||
virtual void setProgram(long program);
|
||||
virtual void setProgramName(char *name);
|
||||
virtual void getProgramName(char *name);
|
||||
virtual void setParameter(long index, float value);
|
||||
virtual float getParameter(long index);
|
||||
virtual void getParameterLabel(long index, char *label);
|
||||
virtual void getParameterDisplay(long index, char *text);
|
||||
virtual void getParameterName(long index, char *text);
|
||||
virtual void setSampleRate(float sampleRate);
|
||||
virtual void setBlockSize(long blockSize);
|
||||
virtual void suspend();
|
||||
virtual void resume();
|
||||
virtual bool getOutputProperties (long index, VstPinProperties* properties);
|
||||
virtual bool getProgramNameIndexed (long category, long index, char* text);
|
||||
virtual bool copyProgram (long destination);
|
||||
virtual bool getEffectName (char* name);
|
||||
virtual bool getVendorString (char* text);
|
||||
virtual bool getProductString (char* text);
|
||||
virtual long getVendorVersion () {return 1;}
|
||||
virtual long canDo (char* text);
|
||||
|
||||
private:
|
||||
void initProcess();
|
||||
void ApplyEvent(VstMidiEvent *event);
|
||||
|
||||
std::vector<VstMidiEvent*> m_currentEvents;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,294 +0,0 @@
|
||||
#include "windows.h"
|
||||
|
||||
// init synth
|
||||
void Go4kVSTi_Init();
|
||||
|
||||
// clear instrument slot
|
||||
void Go4kVSTi_ClearInstrumentSlot(char channel, int slot);
|
||||
// clear instrument workspace
|
||||
void Go4kVSTi_ClearInstrumentWorkspace(char channel);
|
||||
// clear global slot
|
||||
void Go4kVSTi_ClearGlobalSlot(int slot);
|
||||
// clear global workspace
|
||||
void Go4kVSTi_ClearGlobalWorkspace();
|
||||
|
||||
// reset instrument to default values
|
||||
void Go4kVSTi_ResetInstrument(char channel);
|
||||
// reset global to default values
|
||||
void Go4kVSTi_ResetGlobal();
|
||||
// reset the synth to default values
|
||||
void Go4kVSTi_ResetPatch();
|
||||
|
||||
// flip 2 neighbour instrument slots
|
||||
void Go4kVSTi_FlipInstrumentSlots(char channel, int a, int b);
|
||||
// flip 2 neighbour global slots
|
||||
void Go4kVSTi_FlipGlobalSlots(int a, int b);
|
||||
|
||||
// init a slot with given type with default values
|
||||
void Go4kVSTi_InitSlot(BYTE* slot, int channel, int type);
|
||||
// init a instrument slot
|
||||
void Go4kVSTi_InitInstrumentSlot(char channel, int s, int type);
|
||||
// init a global slot
|
||||
void Go4kVSTi_InitGlobalSlot(int s, int type);
|
||||
|
||||
// set global bpm
|
||||
void Go4kVSTi_SetBPM(float bpm);
|
||||
float Go4kVSTi_GetBPM();
|
||||
|
||||
// activate solo mode
|
||||
void Go4kVSTi_Solo(int channel, int solo);
|
||||
// stream recording activation/deactivation
|
||||
void Go4kVSTi_Record(bool record, int patternsize, float patternquant);
|
||||
// panic
|
||||
void Go4kVSTi_Panic();
|
||||
// update dll times (e.g. sync to current bpm)
|
||||
void Go4kVSTi_UpdateDelayTimes();
|
||||
// clear delay lines
|
||||
void Go4kVSTi_ClearDelayLines();
|
||||
|
||||
// one tick the whole synth pipeline. results are left and right output sample
|
||||
void Go4kVSTi_Tick(float *oleft, float *oright, int samples);
|
||||
// add a voice with given parameters to synth
|
||||
void Go4kVSTi_AddVoice(int channel, int note);
|
||||
// stop a voice with given parameters in synth
|
||||
void Go4kVSTi_StopVoice(int channel, int note);
|
||||
|
||||
// load binary patch data
|
||||
void Go4kVSTi_LoadPatch(char *filename);
|
||||
// save binary patch data
|
||||
void Go4kVSTi_SavePatch(char *filename);
|
||||
// load instrumen data to specified channel
|
||||
void Go4kVSTi_LoadInstrument(char* filename, char channel);
|
||||
// save instrument data from current channel
|
||||
void Go4kVSTi_SaveInstrument(char* filename, char channel);
|
||||
// load unit data into specified slot
|
||||
void Go4kVSTi_LoadUnit(char* filename, BYTE* slot);
|
||||
// save unit date from specified slot
|
||||
void Go4kVSTi_SaveUnit(char* filename, BYTE* slot);
|
||||
|
||||
#define EXPORT_OBJECT_FILE_
|
||||
void Go4kVSTi_SaveByteStream(HINSTANCE hInst, char* filename, int useenvlevels, int useenotevalues, int clipoutput, int undenormalize, int objformat, int output16);
|
||||
|
||||
#define MAX_POLYPHONY 2
|
||||
#define MAX_INSTRUMENTS 16
|
||||
#define MAX_SLOT_VALUES 32
|
||||
|
||||
#define MAX_SLOTS 32
|
||||
|
||||
enum UnitID
|
||||
{
|
||||
M_NONE = 0,
|
||||
M_ENV,
|
||||
M_VCO,
|
||||
M_VCF,
|
||||
M_DST,
|
||||
M_DLL,
|
||||
M_FOP,
|
||||
M_FST,
|
||||
M_PAN,
|
||||
M_OUT,
|
||||
M_ACC,
|
||||
M_FLD,
|
||||
NUM_MODULES
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// value definitions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define ENV_STATE_ATTAC 0
|
||||
#define ENV_STATE_DECAY 1
|
||||
#define ENV_STATE_SUSTAIN 2
|
||||
#define ENV_STATE_RELEASE 3
|
||||
#define ENV_STATE_OFF 4
|
||||
|
||||
typedef struct ENV_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE attac;
|
||||
BYTE decay;
|
||||
BYTE sustain;
|
||||
BYTE release;
|
||||
BYTE gain;
|
||||
// GUI STUFF
|
||||
} *ENV_valP;
|
||||
|
||||
#define VCO_SINE 0x01
|
||||
#define VCO_TRISAW 0x02
|
||||
#define VCO_PULSE 0x04
|
||||
#define VCO_NOISE 0x08
|
||||
#define VCO_LFO 0x10
|
||||
#define VCO_GATE 0x20
|
||||
typedef struct VCO_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE transpose;
|
||||
BYTE detune;
|
||||
BYTE phaseofs;
|
||||
BYTE gate;
|
||||
BYTE color;
|
||||
BYTE shape;
|
||||
BYTE gain;
|
||||
BYTE flags;
|
||||
// GUI STUFF
|
||||
} *VCO_valP;
|
||||
|
||||
typedef struct VCO11_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE transpose;
|
||||
BYTE detune;
|
||||
BYTE phaseofs;
|
||||
BYTE color;
|
||||
BYTE shape;
|
||||
BYTE gain;
|
||||
BYTE flags;
|
||||
// GUI STUFF
|
||||
} *VCO11_valP;
|
||||
|
||||
#define VCF_LOWPASS 0x1
|
||||
#define VCF_HIGHPASS 0x2
|
||||
#define VCF_BANDPASS 0x4
|
||||
#define VCF_BANDSTOP 0x3
|
||||
#define VCF_ALLPASS 0x7
|
||||
#define VCF_PEAK 0x8
|
||||
typedef struct VCF_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE freq;
|
||||
BYTE res;
|
||||
BYTE type;
|
||||
// GUI STUFF
|
||||
} *VCF_valP;
|
||||
|
||||
typedef struct DST_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE drive;
|
||||
BYTE snhfreq;
|
||||
// GUI STUFF
|
||||
} *DST_valP;
|
||||
|
||||
typedef struct DLL_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE pregain;
|
||||
BYTE dry;
|
||||
BYTE feedback;
|
||||
BYTE damp;
|
||||
BYTE freq;
|
||||
BYTE depth;
|
||||
BYTE delay;
|
||||
BYTE count;
|
||||
// GUI STUFF
|
||||
BYTE guidelay;
|
||||
BYTE synctype;
|
||||
BYTE leftreverb;
|
||||
BYTE reverb;
|
||||
} *DLL_valP;
|
||||
|
||||
typedef struct DLL10_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE pregain;
|
||||
BYTE dry;
|
||||
BYTE feedback;
|
||||
BYTE damp;
|
||||
BYTE delay;
|
||||
BYTE count;
|
||||
// GUI STUFF
|
||||
BYTE guidelay;
|
||||
BYTE synctype;
|
||||
BYTE leftreverb;
|
||||
BYTE reverb;
|
||||
} *DLL10_valP;
|
||||
|
||||
#define FOP_POP 0x1
|
||||
#define FOP_ADDP 0x2
|
||||
#define FOP_MULP 0x3
|
||||
#define FOP_PUSH 0x4
|
||||
#define FOP_XCH 0x5
|
||||
#define FOP_ADD 0x6
|
||||
#define FOP_MUL 0x7
|
||||
#define FOP_ADDP2 0x8
|
||||
#define FOP_LOADNOTE 0x9
|
||||
typedef struct FOP_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE flags;
|
||||
} *FOP_valP;
|
||||
|
||||
typedef struct FST_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE amount;
|
||||
BYTE dest;
|
||||
// GUI STUFF
|
||||
char dest_stack;
|
||||
char dest_unit;
|
||||
char dest_slot;
|
||||
char dest_id;
|
||||
} *FST_valP;
|
||||
|
||||
typedef struct PAN_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE panning;
|
||||
// GUI STUFF
|
||||
} *PAN_valP;
|
||||
|
||||
typedef struct OUT_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE gain;
|
||||
BYTE auxsend;
|
||||
// GUI STUFF
|
||||
} *OUT_valP;
|
||||
|
||||
#define ACC_OUT 0
|
||||
#define ACC_AUX 8
|
||||
typedef struct ACC_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE flags;
|
||||
} *ACC_valP;
|
||||
|
||||
typedef struct FLD_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE value;
|
||||
// GUI STUFF
|
||||
} *FLD_valP;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// workspace definitions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct InstrumentWorkspace
|
||||
{
|
||||
DWORD release;
|
||||
DWORD note;
|
||||
float workspace[256];
|
||||
float dlloutl;
|
||||
float dlloutr;
|
||||
float outl;
|
||||
float outr;
|
||||
} *InstrumentWorkspaceP;
|
||||
|
||||
typedef struct SynthObject
|
||||
{
|
||||
DWORD Polyphony;
|
||||
char InstrumentNames[MAX_INSTRUMENTS][64];
|
||||
BYTE InstrumentValues[MAX_INSTRUMENTS][MAX_SLOTS][MAX_SLOT_VALUES]; // 16 instruments a 32 slots a 32 dowrds
|
||||
BYTE GlobalValues[MAX_SLOTS][MAX_SLOT_VALUES]; // 32 slots a 32 dwords
|
||||
InstrumentWorkspace InstrumentWork[MAX_INSTRUMENTS*MAX_POLYPHONY];
|
||||
InstrumentWorkspace GlobalWork;
|
||||
DWORD InstrumentSignalValid[MAX_INSTRUMENTS];
|
||||
DWORD GlobalSignalValid;
|
||||
float SignalTrace[MAX_INSTRUMENTS];
|
||||
int ControlInstrument[MAX_INSTRUMENTS];
|
||||
int VoiceIndex[MAX_INSTRUMENTS];
|
||||
} *SynthObjectP;
|
||||
|
||||
SynthObjectP Go4kVSTi_GetSynthObject();
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,182 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#define ButtonGroupChanged(btn_firstid, btn_lastid, test_id, seltab, result_index) \
|
||||
{ \
|
||||
result_index = 0; \
|
||||
if (LOWORD(test_id) >= btn_firstid && \
|
||||
LOWORD(test_id) <= btn_lastid) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
if (LOWORD(test_id) == bgci) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), false); \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), true); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EnableButtonGroup(btn_firstid, btn_lastid, seltab, btn_show) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), btn_show); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SetCheckboxGroupBitmask(btn_firstid, btn_lastid, seltab, input_bits) \
|
||||
{ \
|
||||
WORD curbitsel = 0x0001; \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++,curbitsel*=2) \
|
||||
{ \
|
||||
SendDlgItemMessage(ModuleWnd[seltab], bgci, BM_SETCHECK, input_bits & curbitsel, 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GetCheckboxGroupBitmask(btn_firstid, btn_lastid, test_id, seltab, result_bits, result_index) \
|
||||
{ \
|
||||
result_index = 0; \
|
||||
result_bits = 0; \
|
||||
WORD curbitsel = 0x0001; \
|
||||
if (LOWORD(test_id) >= btn_firstid && \
|
||||
LOWORD(test_id) <= btn_lastid) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++,curbitsel*=2) \
|
||||
{ \
|
||||
if (LOWORD(test_id) == bgci) \
|
||||
{ \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
if (SendDlgItemMessage(ModuleWnd[seltab], bgci, BM_GETCHECK, 0, 0)==BST_CHECKED) \
|
||||
{ \
|
||||
result_bits |= curbitsel; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
result_bits &= ~curbitsel; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define InitSlider(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", slider_pos); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderCenter(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", slider_pos-64); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderCenter2(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", (slider_pos-64)*2); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderNoGUI(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
}
|
||||
|
||||
#define DisableButtonGroup(btn_firstid, btn_lastid, seltab) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define InterleavedButtonGroupChanged(btn_firstid, btn_count, test_id, result_index)\
|
||||
{ \
|
||||
result_index = -1; \
|
||||
if (((LOWORD(test_id)-btn_firstid) % 6) == 0) \
|
||||
{ \
|
||||
for (WORD bgci = 0; bgci < btn_count; bgci++) \
|
||||
{ \
|
||||
WORD ibtn = btn_firstid+bgci*6; \
|
||||
if (LOWORD(test_id) == ibtn) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[SelectedTab], ibtn), false); \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[SelectedTab], ibtn), true); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DisableInterleavedButtonGroup(btn_firstid, btn_count, seltab) \
|
||||
{ \
|
||||
for (WORD bgci = 0; bgci < btn_count; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[seltab], btn_firstid+bgci*6), true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define UpdateSliderValue(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", usv_v); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define UpdateSliderValueCenter(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", usv_v-64); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define UpdateSliderValueCenter2(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", (usv_v-64)*2); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
void Go4kVSTiGUI_Create(HINSTANCE hInst);
|
||||
void Go4kVSTiGUI_Show(int showCommand);
|
||||
void Go4kVSTiGUI_Destroy();
|
||||
|
||||
bool InitTabDlg();
|
||||
|
||||
bool ButtonPressed(WPARAM id, LPARAM lParam);
|
||||
bool ScrollbarChanged(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
|
||||
bool StackButtonPressed(WPARAM id);
|
||||
void TabChanged(int index);
|
||||
|
||||
void UpdateSignalCount(int channel);
|
||||
void UpdateControls(int channel);
|
||||
void UpdateModuleParamWindow(int tab, int unit);
|
||||
void UpdateVoiceDisplay(int i);
|
||||
|
||||
void GetStreamFileName();
|
||||
|
||||
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <stddef.h>
|
||||
#include "Go4kVSTi.h"
|
||||
#include "Go4kVSTiGUI.h"
|
||||
|
||||
static AudioEffect *effect = 0;
|
||||
bool oome = false;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// prototype of the export function main
|
||||
int main (audioMasterCallback audioMaster);
|
||||
|
||||
int main (audioMasterCallback audioMaster)
|
||||
{
|
||||
// get vst version
|
||||
if(!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
|
||||
return 0; // old version
|
||||
|
||||
effect = new Go4kVSTi (audioMaster);
|
||||
if (!effect)
|
||||
return 0;
|
||||
if (oome)
|
||||
{
|
||||
delete effect;
|
||||
return 0;
|
||||
}
|
||||
return (int)effect->getAeffect();
|
||||
}
|
||||
|
||||
void* hInstance;
|
||||
BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
// wird aufgerufen, wenn zum ersten mal das plugin aktiviert wird
|
||||
// also hier init f<>r den synth
|
||||
case DLL_PROCESS_ATTACH:
|
||||
//MessageBox(NULL, "DLL_PROCESS_ATTACH", "DllMain", MB_OK);
|
||||
Go4kVSTiGUI_Create(hInst);
|
||||
Go4kVSTiGUI_Show(SW_SHOW);
|
||||
break;
|
||||
// wird aufgerufen, wenn das plugin nicht mehr verwendet wird
|
||||
// entweder bei entfernen des letzten, schliessen des songs oder
|
||||
// des programms. Also hier Deinit und zerst<73>rung des Synths
|
||||
case DLL_PROCESS_DETACH:
|
||||
//MessageBox(NULL, "DLL_PROCESS_DETACH", "DllMain", MB_OK);
|
||||
Go4kVSTiGUI_Destroy();
|
||||
effect = 0;
|
||||
break;
|
||||
// die beiden brauchts wohl nicht
|
||||
case DLL_THREAD_ATTACH:
|
||||
//MessageBox(NULL, "DLL_THREAD_ATTACH", "DllMain", MB_OK);
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
//MessageBox(NULL, "DLL_THREAD_DETACH", "DllMain", MB_OK);
|
||||
break;
|
||||
}
|
||||
hInstance = hInst;
|
||||
return 1;
|
||||
}
|
||||
@ -1,158 +0,0 @@
|
||||
#ifndef __Go4kVSTi__
|
||||
#include "Go4kVSTi.h"
|
||||
#include "Go4kVSTiCore.h"
|
||||
#include "stdio.h"
|
||||
#endif
|
||||
|
||||
#include "math.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setSampleRate (float sampleRate)
|
||||
{
|
||||
AudioEffectX::setSampleRate (sampleRate);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setBlockSize (long blockSize)
|
||||
{
|
||||
AudioEffectX::setBlockSize (blockSize);
|
||||
// you may need to have to do something here...
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::suspend ()
|
||||
{
|
||||
m_currentEvents.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::resume ()
|
||||
{
|
||||
wantEvents ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::initProcess ()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::process (float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
processAnyhow(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::processReplacing (float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
processAnyhow(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
void Go4kVSTi::processAnyhow(float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
float* outl = outputs[0];
|
||||
float* outr = outputs[1];
|
||||
static int bpmCheck = 0;
|
||||
if ( bpmCheck <= 0 )
|
||||
{
|
||||
VstTimeInfo* myTime = getTimeInfo ( kVstTempoValid );
|
||||
Go4kVSTi_SetBPM(myTime->tempo);
|
||||
bpmCheck = 20; // only check every 20th call of this function (bpm shouldnt change that often)
|
||||
}
|
||||
bpmCheck--;
|
||||
|
||||
int start = 0;
|
||||
// midi events will occur this frame, so render partially
|
||||
if (m_currentEvents.size() > 0)
|
||||
{
|
||||
// for all events
|
||||
for (unsigned int i = 0; i < m_currentEvents.size(); i++)
|
||||
{
|
||||
// process samples until next event
|
||||
int todo = m_currentEvents[i]->deltaFrames - start;
|
||||
Go4kVSTi_Tick(outl+start, outr+start, todo);
|
||||
start = m_currentEvents[i]->deltaFrames;
|
||||
// apply changes due to event
|
||||
ApplyEvent(m_currentEvents[i]);
|
||||
}
|
||||
}
|
||||
Go4kVSTi_Tick(outl+start, outr+start, sampleFrames - start);
|
||||
|
||||
// clear event list (old event pointer wont be valid next frame anyway)
|
||||
m_currentEvents.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::processEvents(VstEvents* ev)
|
||||
{
|
||||
for (long i = 0; i < ev->numEvents; i++)
|
||||
{
|
||||
if ((ev->events[i])->type != kVstMidiType)
|
||||
continue;
|
||||
VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
|
||||
m_currentEvents.push_back(event);
|
||||
}
|
||||
return 1; // want more
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::ApplyEvent(VstMidiEvent *event)
|
||||
{
|
||||
char* midiData = event->midiData;
|
||||
byte status = midiData[0] & 0xf0; // status
|
||||
byte channel = midiData[0] & 0x0f; // channel
|
||||
|
||||
// note on/off events
|
||||
if (status == 0x90 || status == 0x80)
|
||||
{
|
||||
byte note = midiData[1] & 0x7f;
|
||||
byte velocity = midiData[2] & 0x7f;
|
||||
if (status == 0x80)
|
||||
velocity = 0;
|
||||
// note off
|
||||
if (!velocity)
|
||||
{
|
||||
Go4kVSTi_StopVoice(channel, note);
|
||||
}
|
||||
// note on
|
||||
else
|
||||
{
|
||||
Go4kVSTi_AddVoice(channel, note);
|
||||
}
|
||||
}
|
||||
/* // polyphonic aftertouch
|
||||
else if (status == 0xA)
|
||||
{
|
||||
byte note = midiData[1] & 0x7f;
|
||||
byte pressure = midiData[2] & 0x7f;
|
||||
Go4kVSTi_PolyAftertouch(channel, note, pressure);
|
||||
}
|
||||
// channel aftertouch
|
||||
else if (status == 0xD)
|
||||
{
|
||||
byte pressure = midiData[1] & 0x7f;
|
||||
Go4kVSTi_ChannelAftertouch(channel, pressure);
|
||||
}
|
||||
// Controller Change
|
||||
else if (status == 0xB0)
|
||||
{
|
||||
byte number = midiData[1] & 0x7f;
|
||||
byte value = midiData[2] & 0x7f;
|
||||
// Go4kVSTi_ControllerChange(channel, number, value, event->deltaFrames);
|
||||
}
|
||||
// Pitch Bend
|
||||
else if (status == 0xE0)
|
||||
{
|
||||
byte lsb = midiData[1] & 0x7f;
|
||||
byte msb = midiData[2] & 0x7f;
|
||||
int value = (((int)(msb)) << 7) + lsb;
|
||||
// Go4kVSTi_PitchBend(channel, value); // 0 - 16383, center 8192
|
||||
// dont use full precision for the sake of equally sized streams
|
||||
// Go4kVSTi_PitchBend(channel, value >> 7, event->deltaFrames); // 0 - 127, center 64
|
||||
}*/
|
||||
// all notes off (dont seem to come anyway
|
||||
else if (status == 0xb0 && midiData[1] == 0x7e) // all notes off
|
||||
{
|
||||
Go4kVSTi_StopVoice(channel, 0);
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
#ifndef __AEffEditor__
|
||||
#define __AEffEditor__
|
||||
|
||||
class AudioEffect;
|
||||
|
||||
struct ERect
|
||||
{
|
||||
short top;
|
||||
short left;
|
||||
short bottom;
|
||||
short right;
|
||||
};
|
||||
|
||||
class AEffEditor
|
||||
{
|
||||
public:
|
||||
AEffEditor (AudioEffect *effect) {this->effect = effect; updateFlag = 0; }
|
||||
virtual ~AEffEditor() {}
|
||||
|
||||
virtual long getRect(ERect **rect) {*rect = 0; return 0;}
|
||||
virtual long open(void *ptr) {systemWindow = ptr; return 0;}
|
||||
virtual void close() {}
|
||||
virtual void idle() { if(updateFlag) {updateFlag = 0; update();} }
|
||||
|
||||
#if MAC
|
||||
virtual void draw(ERect *rect) {rect = rect;}
|
||||
virtual long mouse(long x, long y) {x = x; y = y; return 0;}
|
||||
virtual long key(long keyCode) {keyCode = keyCode; return 0;}
|
||||
virtual void top() {}
|
||||
virtual void sleep() {}
|
||||
#endif
|
||||
virtual void update() {}
|
||||
virtual void postUpdate() {updateFlag = 1;}
|
||||
|
||||
protected:
|
||||
AEffEditor () {};
|
||||
|
||||
AudioEffect *effect;
|
||||
void *systemWindow;
|
||||
long updateFlag;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
#ifndef __AEffect__
|
||||
#define __AEffect__
|
||||
|
||||
/*
|
||||
to create an Audio Effect for power pc's, create a
|
||||
code resource
|
||||
file type: 'aPcs'
|
||||
resource type: 'aEff'
|
||||
ppc header: none (raw pef)
|
||||
|
||||
for windows, it's a .dll
|
||||
|
||||
the only symbol searched for is:
|
||||
AEffect *main(float (*audioMaster)(AEffect *effect, long opcode, long index,
|
||||
long value, void *ptr, float opt));
|
||||
*/
|
||||
|
||||
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#elif defined CBUILDER
|
||||
#pragma -a8
|
||||
#elif defined(WIN32) || defined(__FLAT__)
|
||||
#pragma pack(push)
|
||||
#pragma pack(8)
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(__FLAT__) || defined CBUILDER
|
||||
#define VSTCALLBACK __cdecl
|
||||
#else
|
||||
#define VSTCALLBACK
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// misc def's
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct AEffect AEffect;
|
||||
typedef long (VSTCALLBACK *audioMasterCallback)(AEffect *effect, long opcode, long index,
|
||||
long value, void *ptr, float opt);
|
||||
|
||||
// prototype for plug-in main
|
||||
// AEffect *main(audioMasterCallback audioMaster);
|
||||
|
||||
#ifdef CBUILDER
|
||||
#define kEffectMagic 'PtsV'
|
||||
#else
|
||||
#define kEffectMagic 'VstP'
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
struct AEffect
|
||||
{
|
||||
long magic; // must be kEffectMagic ('VstP')
|
||||
long (VSTCALLBACK *dispatcher)(AEffect *effect, long opCode, long index, long value,
|
||||
void *ptr, float opt);
|
||||
void (VSTCALLBACK *process)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
|
||||
void (VSTCALLBACK *setParameter)(AEffect *effect, long index, float parameter);
|
||||
float (VSTCALLBACK *getParameter)(AEffect *effect, long index);
|
||||
|
||||
long numPrograms;
|
||||
long numParams; // all programs are assumed to have numParams parameters
|
||||
long numInputs; //
|
||||
long numOutputs; //
|
||||
long flags; // see constants
|
||||
long resvd1; // reserved, must be 0
|
||||
long resvd2; // reserved, must be 0
|
||||
long initialDelay; // for algorithms which need input in the first place
|
||||
long realQualities; // number of realtime qualities (0: realtime)
|
||||
long offQualities; // number of offline qualities (0: realtime only)
|
||||
float ioRatio; // input samplerate to output samplerate ratio, not used yet
|
||||
void *object; // for class access (see AudioEffect.hpp), MUST be 0 else!
|
||||
void *user; // user access
|
||||
long uniqueID; // pls choose 4 character as unique as possible.
|
||||
// this is used to identify an effect for save+load
|
||||
long version; //
|
||||
void (VSTCALLBACK *processReplacing)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
|
||||
char future[60]; // pls zero
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// flags bits
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
#define effFlagsHasEditor 1 // if set, is expected to react to editor messages
|
||||
#define effFlagsHasClip 2 // return > 1. in getVu() if clipped
|
||||
#define effFlagsHasVu 4 // return vu value in getVu(); > 1. means clipped
|
||||
#define effFlagsCanMono 8 // if numInputs == 2, makes sense to be used for mono in
|
||||
#define effFlagsCanReplacing 16 // supports in place output (processReplacing() exsists)
|
||||
#define effFlagsProgramChunks 32 // program data are handled in formatless chunks
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dispatcher opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
effOpen = 0, // initialise
|
||||
effClose, // exit, release all memory and other resources!
|
||||
|
||||
effSetProgram, // program no in <value>
|
||||
effGetProgram, // return current program no.
|
||||
effSetProgramName, // user changed program name (max 24 char + 0) to as passed in string
|
||||
effGetProgramName, // stuff program name (max 24 char + 0) into string
|
||||
|
||||
effGetParamLabel, // stuff parameter <index> label (max 8 char + 0) into string
|
||||
// (examples: sec, dB, type)
|
||||
effGetParamDisplay, // stuff parameter <index> textual representation into string
|
||||
// (examples: 0.5, -3, PLATE)
|
||||
effGetParamName, // stuff parameter <index> label (max 8 char + 0) into string
|
||||
// (examples: Time, Gain, RoomType)
|
||||
effGetVu, // called if (flags & (effFlagsHasClip | effFlagsHasVu))
|
||||
|
||||
// system
|
||||
|
||||
effSetSampleRate, // in opt (float)
|
||||
effSetBlockSize, // in value
|
||||
effMainsChanged, // the user has switched the 'power on' button to
|
||||
// value (0 off, else on). This only switches audio
|
||||
// processing; you should flush delay buffers etc.
|
||||
// editor
|
||||
|
||||
effEditGetRect, // stuff rect (top, left, bottom, right) into ptr
|
||||
effEditOpen, // system dependant Window pointer in ptr
|
||||
effEditClose, // no arguments
|
||||
effEditDraw, // draw method, ptr points to rect
|
||||
effEditMouse, // index: x, value: y
|
||||
effEditKey, // system keycode in value
|
||||
effEditIdle, // no arguments. Be gentle!
|
||||
effEditTop, // window has topped, no arguments
|
||||
effEditSleep, // window goes to background
|
||||
|
||||
// new
|
||||
|
||||
effIdentify, // returns 'NvEf'
|
||||
effGetChunk, // host requests pointer to chunk into (void**)ptr, byteSize returned
|
||||
effSetChunk, // plug-in receives saved chunk, byteSize passed
|
||||
|
||||
effNumOpcodes
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// audioMaster opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
audioMasterAutomate = 0, // index, value, returns 0
|
||||
audioMasterVersion, // vst version, currently 2 (0 for older)
|
||||
audioMasterCurrentId, // returns the unique id of a plug that's currently
|
||||
// loading
|
||||
audioMasterIdle, // call application idle routine (this will
|
||||
// call effEditIdle for all open editors too)
|
||||
audioMasterPinConnected // inquire if an input or output is beeing connected;
|
||||
// index enumerates input or output counting from zero,
|
||||
// value is 0 for input and != 0 otherwise. note: the
|
||||
// return value is 0 for <true> such that older versions
|
||||
// will always return true.
|
||||
|
||||
};
|
||||
|
||||
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
|
||||
#pragma options align=reset
|
||||
#elif defined(WIN32) || defined(__FLAT__)
|
||||
#pragma pack(pop)
|
||||
#elif defined CBUILDER
|
||||
#pragma -a-
|
||||
#endif
|
||||
|
||||
#endif // __AEffect__
|
||||
@ -1,382 +0,0 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "AudioEffect.hpp"
|
||||
#include "AEffEditor.hpp"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long dispatchEffectClass (AEffect *e, long opCode,
|
||||
long index, long value, void *ptr, float opt)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
|
||||
if(opCode == effClose)
|
||||
{
|
||||
ae->dispatcher(opCode, index, value, ptr, opt);
|
||||
delete ae;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ae->dispatcher(opCode, index, value, ptr, opt);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
float getParameterClass(AEffect *e, long index)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
return ae->getParameter(index);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setParameterClass(AEffect *e, long index, float value)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->setParameter(index, value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->process(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->processReplacing(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
AudioEffect::AudioEffect(audioMasterCallback audioMaster, long numPrograms, long numParams)
|
||||
{
|
||||
this->audioMaster = audioMaster;
|
||||
editor = 0;
|
||||
this->numPrograms = numPrograms;
|
||||
this->numParams = numParams;
|
||||
curProgram = 0;
|
||||
|
||||
memset(&cEffect, 0, sizeof(cEffect));
|
||||
cEffect.magic = kEffectMagic;
|
||||
cEffect.dispatcher = dispatchEffectClass;
|
||||
cEffect.process = processClass;
|
||||
cEffect.setParameter = setParameterClass;
|
||||
cEffect.getParameter = getParameterClass;
|
||||
cEffect.numPrograms = numPrograms;
|
||||
cEffect.numParams = numParams;
|
||||
cEffect.numInputs = 1;
|
||||
cEffect.numOutputs = 2;
|
||||
cEffect.flags = 0;
|
||||
cEffect.resvd1 = 0;
|
||||
cEffect.resvd2 = 0;
|
||||
cEffect.initialDelay = 0;
|
||||
cEffect.realQualities = 0;
|
||||
cEffect.offQualities = 0;
|
||||
cEffect.ioRatio = 1.f;
|
||||
cEffect.object = this;
|
||||
cEffect.user = 0;
|
||||
cEffect.uniqueID = 'NoEf'; // you must set this!
|
||||
cEffect.version = 1;
|
||||
cEffect.processReplacing = processClassReplacing;
|
||||
|
||||
sampleRate = 44100.f;
|
||||
blockSize = 1024L;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
AudioEffect::~AudioEffect()
|
||||
{
|
||||
if(editor)
|
||||
delete editor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::dispatcher(long opCode, long index, long value, void *ptr, float opt)
|
||||
{
|
||||
long v = 0;
|
||||
|
||||
switch(opCode)
|
||||
{
|
||||
case effOpen: open(); break;
|
||||
case effClose: close(); break;
|
||||
case effSetProgram: if(value < numPrograms) setProgram(value); break;
|
||||
case effGetProgram: v = getProgram(); break;
|
||||
case effSetProgramName: setProgramName((char *)ptr); break;
|
||||
case effGetProgramName: getProgramName((char *)ptr); break;
|
||||
case effGetParamLabel: getParameterLabel(index, (char *)ptr); break;
|
||||
case effGetParamDisplay: getParameterDisplay(index, (char *)ptr); break;
|
||||
case effGetParamName: getParameterName(index, (char *)ptr); break;
|
||||
|
||||
case effSetSampleRate: setSampleRate(opt); break;
|
||||
case effSetBlockSize: setBlockSize(value); break;
|
||||
case effMainsChanged: if(!value) suspend(); else resume(); break;
|
||||
case effGetVu: v = (long)(getVu() * 32767.); break;
|
||||
|
||||
// editor
|
||||
|
||||
case effEditGetRect: if(editor) v = editor->getRect((ERect **)ptr); break;
|
||||
case effEditOpen: if(editor) v = editor->open(ptr); break;
|
||||
case effEditClose: if(editor) editor->close(); break;
|
||||
case effEditIdle: if(editor) editor->idle(); break;
|
||||
|
||||
#if MAC
|
||||
case effEditDraw: if(editor) editor->draw((ERect *)ptr); break;
|
||||
case effEditMouse: if(editor) v = editor->mouse(index, value); break;
|
||||
case effEditKey: if(editor) v = editor->key(value); break;
|
||||
case effEditTop: if(editor) editor->top(); break;
|
||||
case effEditSleep: if(editor) editor->sleep(); break;
|
||||
#endif
|
||||
|
||||
// new
|
||||
|
||||
case effIdentify: v = 'NvEf'; break;
|
||||
case effGetChunk: v = getChunk((void**)ptr, index ? true : false); break;
|
||||
case effSetChunk: v = setChunk(ptr, value, index ? true : false); break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::getMasterVersion()
|
||||
{
|
||||
long version = 1;
|
||||
if(audioMaster)
|
||||
{
|
||||
version = audioMaster(&cEffect, audioMasterVersion, 0, 0, 0, 0);
|
||||
if(!version) // old
|
||||
version = 1;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::getCurrentUniqueId()
|
||||
{
|
||||
long id = 0;
|
||||
if(audioMaster)
|
||||
id = audioMaster(&cEffect, audioMasterCurrentId, 0, 0, 0, 0);
|
||||
return id;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::masterIdle()
|
||||
{
|
||||
if(audioMaster)
|
||||
audioMaster(&cEffect, audioMasterIdle, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AudioEffect::isInputConnected(long input)
|
||||
{
|
||||
long ret = 0;
|
||||
if(audioMaster)
|
||||
ret = audioMaster(&cEffect, audioMasterPinConnected, input, 0, 0, 0);
|
||||
return ret ? false : true; // return value is 0 for true
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AudioEffect::isOutputConnected(long output)
|
||||
{
|
||||
long ret = 0;
|
||||
if(audioMaster)
|
||||
ret = audioMaster(&cEffect, audioMasterPinConnected, output, 1, 0, 0);
|
||||
return ret ? false : true; // return value is 0 for true
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// flags
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::hasVu(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsHasVu;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsHasVu;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::hasClip(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsHasClip;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsHasClip;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::canMono(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsCanMono;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsCanMono;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::canProcessReplacing(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsCanReplacing;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsCanReplacing;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::programsAreChunks(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsProgramChunks;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsProgramChunks;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setRealtimeQualities(long qualities)
|
||||
{
|
||||
cEffect.realQualities = qualities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setOfflineQualities(long qualities)
|
||||
{
|
||||
cEffect.offQualities = qualities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setInitialDelay(long delay)
|
||||
{
|
||||
cEffect.initialDelay = delay;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::dB2string(float value, char *text)
|
||||
{
|
||||
if(value <= 0)
|
||||
#if MAC
|
||||
strcpy(text, " -<2D> ");
|
||||
#else
|
||||
strcpy(text, " -oo ");
|
||||
#endif
|
||||
else
|
||||
float2string((float)(20. * log10(value)), text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::Hz2string(float samples, char *text)
|
||||
{
|
||||
float sampleRate = getSampleRate();
|
||||
if(!samples)
|
||||
float2string(0, text);
|
||||
else
|
||||
float2string(sampleRate / samples, text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::ms2string(float samples, char *text)
|
||||
{
|
||||
float2string((float)(samples * 1000. / getSampleRate()), text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::float2string(float value, char *text)
|
||||
{
|
||||
long c = 0, neg = 0;
|
||||
char string[32];
|
||||
char *s;
|
||||
double v, integ, i10, mantissa, m10, ten = 10.;
|
||||
|
||||
v = (double)value;
|
||||
if(v < 0)
|
||||
{
|
||||
neg = 1;
|
||||
value = -value;
|
||||
v = -v;
|
||||
c++;
|
||||
if(v > 9999999.)
|
||||
{
|
||||
strcpy(string, " Huge! ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(v > 99999999.)
|
||||
{
|
||||
strcpy(string, " Huge! ");
|
||||
return;
|
||||
}
|
||||
|
||||
s = string + 31;
|
||||
*s-- = 0;
|
||||
*s-- = '.';
|
||||
c++;
|
||||
|
||||
integ = floor(v);
|
||||
i10 = fmod(integ, ten);
|
||||
*s-- = (long)i10 + '0';
|
||||
integ /= ten;
|
||||
c++;
|
||||
while(integ >= 1. && c < 8)
|
||||
{
|
||||
i10 = fmod(integ, ten);
|
||||
*s-- = (long)i10 + '0';
|
||||
integ /= ten;
|
||||
c++;
|
||||
}
|
||||
if(neg)
|
||||
*s-- = '-';
|
||||
strcpy(text, s + 1);
|
||||
if(c >= 8)
|
||||
return;
|
||||
|
||||
s = string + 31;
|
||||
*s-- = 0;
|
||||
mantissa = fmod(v, 1.);
|
||||
mantissa *= pow(ten, (double)(8 - c));
|
||||
while(c < 8)
|
||||
{
|
||||
if(mantissa <= 0)
|
||||
*s-- = '0';
|
||||
else
|
||||
{
|
||||
m10 = fmod(mantissa, ten);
|
||||
*s-- = (long)m10 + '0';
|
||||
mantissa /= 10.;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
strcat(text, s + 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::long2string(long value, char *text)
|
||||
{
|
||||
char string[32];
|
||||
|
||||
if(value >= 100000000)
|
||||
{
|
||||
strcpy(text, " Huge! ");
|
||||
return;
|
||||
}
|
||||
sprintf(string, "%7d", value);
|
||||
string[8] = 0;
|
||||
strcpy(text, (char *)string);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setParameterAutomated(long index, float value)
|
||||
{
|
||||
setParameter(index, value);
|
||||
if(audioMaster)
|
||||
audioMaster(&cEffect, audioMasterAutomate, index, 0, 0, value); // value is in opt
|
||||
}
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
#ifndef __AudioEffect__
|
||||
#define __AudioEffect__
|
||||
|
||||
#include "AEffect.h" // "c" interface
|
||||
#include <string.h>
|
||||
|
||||
class AEffEditor;
|
||||
class AudioEffect;
|
||||
|
||||
// Needs to be defined by the audio effect and is
|
||||
// called to create the audio effect object instance.
|
||||
AudioEffect* createEffectInstance (audioMasterCallback audioMaster);
|
||||
|
||||
long dispatchEffectClass(AEffect *e,
|
||||
long opCode, long index, long value, void *ptr, float opt);
|
||||
float getParameterClass(long index);
|
||||
void setParameterClass(long index, float value);
|
||||
void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
|
||||
class AudioEffect
|
||||
{
|
||||
friend class AEffEditor;
|
||||
friend long dispatchEffectClass(AEffect *e, long opCode, long index, long value, void *ptr, float opt);
|
||||
friend float getParameterClass(AEffect *e, long index);
|
||||
friend void setParameterClass(AEffect *e, long index, float value);
|
||||
friend void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
friend void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
|
||||
public:
|
||||
AudioEffect(audioMasterCallback audioMaster, long numPrograms, long numParams);
|
||||
virtual ~AudioEffect();
|
||||
|
||||
virtual void setParameter(long index, float value) {index = index; value = value;}
|
||||
virtual float getParameter(long index) {index = index; return 0;}
|
||||
virtual void setParameterAutomated(long index, float value);
|
||||
|
||||
AEffect *getAeffect() {return &cEffect;}
|
||||
void setEditor(AEffEditor *editor)
|
||||
{ this->editor = editor;
|
||||
if(editor) cEffect.flags |= effFlagsHasEditor;
|
||||
else cEffect.flags &= ~effFlagsHasEditor;}
|
||||
|
||||
// called from audio master
|
||||
virtual void process(float **inputs, float **outputs, long sampleFrames) = 0;
|
||||
virtual void processReplacing(float **inputs, float **outputs, long sampleFrames)
|
||||
{inputs = inputs; outputs = outputs; sampleFrames = sampleFrames;}
|
||||
virtual long dispatcher(long opCode, long index, long value, void *ptr, float opt);
|
||||
virtual void open() {}
|
||||
virtual void close() {}
|
||||
virtual long getProgram() {return curProgram;}
|
||||
virtual void setProgram(long program) {curProgram = program;} // don't forget to set curProgram
|
||||
virtual void setProgramName(char *name) {*name = 0;} // all following refer to curProgram
|
||||
virtual void getProgramName(char *name) {*name = 0;}
|
||||
virtual void getParameterLabel(long index, char *label) {index = index; *label = 0;}
|
||||
virtual void getParameterDisplay(long index, char *text) {index = index; *text = 0;}
|
||||
virtual void getParameterName(long index, char *text) {index = index; *text = 0;}
|
||||
virtual float getVu() {return 0;}
|
||||
virtual long getChunk(void** data, bool isPreset = false) {return 0;} // returns byteSize
|
||||
virtual long setChunk(void* data, long byteSize, bool isPreset = false) {return 0;}
|
||||
virtual void setSampleRate(float sampleRate) {this->sampleRate = sampleRate;}
|
||||
virtual void setBlockSize(long blockSize) {this->blockSize = blockSize;}
|
||||
virtual void suspend() {}
|
||||
virtual void resume() {}
|
||||
|
||||
// setup
|
||||
virtual void setUniqueID(long iD) {cEffect.uniqueID = iD;} // must call this!
|
||||
virtual void setNumInputs(long inputs) {cEffect.numInputs = inputs;}
|
||||
virtual void setNumOutputs(long outputs) {cEffect.numOutputs = outputs;}
|
||||
virtual void hasVu(bool state = true);
|
||||
virtual void hasClip(bool state = true);
|
||||
virtual void canMono(bool state = true);
|
||||
virtual void canProcessReplacing(bool state = true);
|
||||
virtual void programsAreChunks(bool state = true);
|
||||
virtual void setRealtimeQualities(long qualities);
|
||||
virtual void setOfflineQualities(long qualities);
|
||||
virtual void setInitialDelay(long delay);
|
||||
|
||||
// inquiry
|
||||
virtual float getSampleRate() {return sampleRate;}
|
||||
virtual long getBlockSize() {return blockSize;}
|
||||
|
||||
// host communication
|
||||
virtual long getMasterVersion();
|
||||
virtual long getCurrentUniqueId();
|
||||
virtual void masterIdle();
|
||||
virtual bool isInputConnected(long input);
|
||||
virtual bool isOutputConnected(long output);
|
||||
|
||||
// tools
|
||||
virtual void dB2string(float value, char *text);
|
||||
virtual void Hz2string(float samples, char *text);
|
||||
virtual void ms2string(float samples, char *text);
|
||||
virtual void float2string(float value, char *string);
|
||||
virtual void long2string(long value, char *text);
|
||||
|
||||
protected:
|
||||
// members
|
||||
float sampleRate;
|
||||
AEffEditor *editor;
|
||||
audioMasterCallback audioMaster;
|
||||
long numPrograms;
|
||||
long numParams;
|
||||
long curProgram;
|
||||
long blockSize;
|
||||
AEffect cEffect;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,534 +0,0 @@
|
||||
#ifndef __aeffectx__
|
||||
#define __aeffectx__
|
||||
|
||||
#ifndef __AEffect__
|
||||
#include "AEffect.h"
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstEvent
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstEvent VstEvent;
|
||||
typedef struct VstMidiEvent VstMidiEvent;
|
||||
typedef struct VstEvents VstEvents;
|
||||
|
||||
struct VstEvent // a generic timestamped event
|
||||
{
|
||||
long type; // see enum below
|
||||
long byteSize; // of this event, excl. type and byteSize
|
||||
long deltaFrames; // sample frames related to the current block start sample position
|
||||
long flags; // generic flags, none defined yet (0)
|
||||
|
||||
char data[16]; // size may vary but is usually 16
|
||||
};
|
||||
|
||||
enum // VstEvent types
|
||||
{
|
||||
kVstMidiType = 1, // midi event, can be cast as VstMidiEvent (see below)
|
||||
kVstAudioType, // audio
|
||||
kVstVideoType, // video
|
||||
kVstParameterType, // parameter
|
||||
kVstTriggerType // trigger
|
||||
// ...etc
|
||||
};
|
||||
|
||||
struct VstMidiEvent // to be casted from a VstEvent
|
||||
{
|
||||
long type; // kVstMidiType
|
||||
long byteSize; // 24
|
||||
long deltaFrames; // sample frames related to the current block start sample position
|
||||
long flags; // none defined yet
|
||||
|
||||
long noteLength; // (in sample frames) of entire note, if available, else 0
|
||||
long noteOffset; // offset into note from note start if available, else 0
|
||||
|
||||
char midiData[4]; // 1 thru 3 midi bytes; midiData[3] is reserved (zero)
|
||||
char detune; // -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
|
||||
char noteOffVelocity;
|
||||
char reserved1; // zero
|
||||
char reserved2; // zero
|
||||
};
|
||||
|
||||
struct VstEvents // a block of events for the current audio block
|
||||
{
|
||||
long numEvents;
|
||||
long reserved; // zero
|
||||
VstEvent* events[2]; // variable
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstTimeInfo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstTimeInfo VstTimeInfo;
|
||||
|
||||
// VstTimeInfo as requested via audioMasterGetTime (getTimeInfo())
|
||||
// refers to the current time slice. note the new slice is
|
||||
// already started when processEvents() is called
|
||||
|
||||
struct VstTimeInfo
|
||||
{
|
||||
double samplePos; // current location
|
||||
double sampleRate;
|
||||
double nanoSeconds; // system time
|
||||
double ppqPos; // 1 ppq
|
||||
double tempo; // in bpm
|
||||
double barStartPos; // last bar start, in 1 ppq
|
||||
double cycleStartPos; // 1 ppq
|
||||
double cycleEndPos; // 1 ppq
|
||||
long timeSigNumerator; // time signature
|
||||
long timeSigDenominator;
|
||||
long smpteOffset;
|
||||
long smpteFrameRate; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, 5:30 df
|
||||
long samplesToNextClock; // midi clock resolution (24 ppq), can be negative
|
||||
long flags; // see below
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kVstTransportChanged = 1,
|
||||
kVstTransportPlaying = 1 << 1,
|
||||
kVstTransportCycleActive = 1 << 2,
|
||||
|
||||
kVstAutomationWriting = 1 << 6,
|
||||
kVstAutomationReading = 1 << 7,
|
||||
|
||||
// flags which indicate which of the fields in this VstTimeInfo
|
||||
// are valid; samplePos and sampleRate are always valid
|
||||
kVstNanosValid = 1 << 8,
|
||||
kVstPpqPosValid = 1 << 9,
|
||||
kVstTempoValid = 1 << 10,
|
||||
kVstBarsValid = 1 << 11,
|
||||
kVstCyclePosValid = 1 << 12, // start and end
|
||||
kVstTimeSigValid = 1 << 13,
|
||||
kVstSmpteValid = 1 << 14,
|
||||
kVstClockValid = 1 << 15
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VarIo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstVariableIo VstVariableIo;
|
||||
|
||||
struct VstVariableIo
|
||||
{
|
||||
float **inputs;
|
||||
float **outputs;
|
||||
long numSamplesInput;
|
||||
long numSamplesOutput;
|
||||
long *numSamplesInputProcessed;
|
||||
long *numSamplesOutputProcessed;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// new audioMaster opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
// VstEvents + VstTimeInfo
|
||||
audioMasterWantMidi = audioMasterPinConnected + 2, // <value> is a filter which is currently ignored
|
||||
audioMasterGetTime, // returns const VstTimeInfo* (or 0 if not supported)
|
||||
// <value> should contain a mask indicating which fields are required
|
||||
// (see valid masks above), as some items may require extensive
|
||||
// conversions
|
||||
audioMasterProcessEvents, // VstEvents* in <ptr>
|
||||
audioMasterSetTime, // VstTimenfo* in <ptr>, filter in <value>, not supported
|
||||
audioMasterTempoAt, // returns tempo (in bpm * 10000) at sample frame location passed in <value>
|
||||
|
||||
// parameters
|
||||
audioMasterGetNumAutomatableParameters,
|
||||
audioMasterGetParameterQuantization, // returns the integer value for +1.0 representation,
|
||||
// or 1 if full single float precision is maintained
|
||||
// in automation. parameter index in <value> (-1: all, any)
|
||||
// connections, configuration
|
||||
audioMasterIOChanged, // numInputs and/or numOutputs has changed
|
||||
audioMasterNeedIdle, // plug needs idle calls (outside its editor window)
|
||||
audioMasterSizeWindow, // index: width, value: height
|
||||
audioMasterGetSampleRate,
|
||||
audioMasterGetBlockSize,
|
||||
audioMasterGetInputLatency,
|
||||
audioMasterGetOutputLatency,
|
||||
audioMasterGetPreviousPlug, // input pin in <value> (-1: first to come), returns cEffect*
|
||||
audioMasterGetNextPlug, // output pin in <value> (-1: first to come), returns cEffect*
|
||||
|
||||
// realtime info
|
||||
audioMasterWillReplaceOrAccumulate, // returns: 0: not supported, 1: replace, 2: accumulate
|
||||
audioMasterGetCurrentProcessLevel, // returns: 0: not supported,
|
||||
// 1: currently in user thread (gui)
|
||||
// 2: currently in audio thread (where process is called)
|
||||
// 3: currently in 'sequencer' thread (midi, timer etc)
|
||||
// 4: currently offline processing and thus in user thread
|
||||
// other: not defined, but probably pre-empting user thread.
|
||||
audioMasterGetAutomationState, // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
|
||||
|
||||
// offline
|
||||
audioMasterOfflineStart,
|
||||
audioMasterOfflineRead, // ptr points to offline structure, see below. return 0: error, 1 ok
|
||||
audioMasterOfflineWrite, // same as read
|
||||
audioMasterOfflineGetCurrentPass,
|
||||
audioMasterOfflineGetCurrentMetaPass,
|
||||
|
||||
// other
|
||||
audioMasterSetOutputSampleRate, // for variable i/o, sample rate in <opt>
|
||||
audioMasterGetSpeakerArrangement, // (long)input in <value>, output in <ptr>
|
||||
audioMasterGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
|
||||
audioMasterGetProductString, // fills <ptr> with a string with product name (max 64 char)
|
||||
audioMasterGetVendorVersion, // returns vendor-specific version
|
||||
audioMasterVendorSpecific, // no definition, vendor specific handling
|
||||
audioMasterSetIcon, // void* in <ptr>, format not defined yet
|
||||
audioMasterCanDo, // string in ptr, see below
|
||||
audioMasterGetLanguage, // see enum
|
||||
audioMasterOpenWindow, // returns platform specific ptr
|
||||
audioMasterCloseWindow, // close window, platform specific handle in <ptr>
|
||||
audioMasterGetDirectory, // get plug directory, FSSpec on MAC, else char*
|
||||
audioMasterUpdateDisplay // something has changed, update 'multi-fx' display
|
||||
};
|
||||
|
||||
enum VstHostLanguage
|
||||
{
|
||||
kVstLangEnglish = 1,
|
||||
kVstLangGerman,
|
||||
kVstLangFrench,
|
||||
kVstLangItalian,
|
||||
kVstLangSpanish,
|
||||
kVstLangJapanese
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dispatcher opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
// VstEvents
|
||||
effProcessEvents = effSetChunk + 1, // VstEvents* in <ptr>
|
||||
|
||||
// parameters and programs
|
||||
effCanBeAutomated, // parameter index in <index>
|
||||
effString2Parameter, // parameter index in <index>, string in <ptr>
|
||||
effGetNumProgramCategories, // no arguments. this is for dividing programs into groups (like GM)
|
||||
effGetProgramNameIndexed, // get program name of category <value>, program <index> into <ptr>.
|
||||
// category (that is, <value>) may be -1, in which case program indices
|
||||
// are enumerated linearily (as usual); otherwise, each category starts
|
||||
// over with index 0.
|
||||
effCopyProgram, // copy current program to destination <index>
|
||||
// note: implies setParameter
|
||||
// connections, configuration
|
||||
effConnectInput, // input at <index> has been (dis-)connected;
|
||||
// <value> == 0: disconnected, else connected
|
||||
effConnectOutput, // same as input
|
||||
effGetInputProperties, // <index>, VstPinProperties* in ptr, return != 0 => true
|
||||
effGetOutputProperties, // dto
|
||||
effGetPlugCategory, // no parameter, return value is category
|
||||
|
||||
// realtime
|
||||
effGetCurrentPosition, // for external dsp, see flag bits below
|
||||
effGetDestinationBuffer, // for external dsp, see flag bits below. returns float*
|
||||
|
||||
// offline
|
||||
effOfflineNotify, // ptr = VstAudioFile array, value = count, index = start flag
|
||||
effOfflinePrepare, // ptr = VstOfflineTask array, value = count
|
||||
effOfflineRun, // dto
|
||||
|
||||
// other
|
||||
effProcessVarIo, // VstVariableIo* in <ptr>
|
||||
effSetSpeakerArrangement, // VstSpeakerArrangement* pluginInput in <value>
|
||||
// VstSpeakerArrangement* pluginOutput in <ptr>
|
||||
effSetBlockSizeAndSampleRate, // block size in <value>, sampleRate in <opt>
|
||||
effSetBypass, // onOff in <value> (0 = off)
|
||||
effGetEffectName, // char* name (max 32 bytes) in <ptr>
|
||||
effGetErrorText, // char* text (max 256 bytes) in <ptr>
|
||||
effGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
|
||||
effGetProductString, // fills <ptr> with a string with product name (max 64 char)
|
||||
effGetVendorVersion, // returns vendor-specific version
|
||||
effVendorSpecific, // no definition, vendor specific handling
|
||||
effCanDo, // <ptr>
|
||||
effGetTailSize, // returns tail size; 0 is default (return 1 for 'no tail')
|
||||
effIdle, // idle call in response to audioMasterneedIdle. must
|
||||
// return 1 to keep idle calls beeing issued
|
||||
|
||||
// gui
|
||||
effGetIcon, // void* in <ptr>, not yet defined
|
||||
effSetViewPosition, // set view position (in window) to x <index> y <value>
|
||||
|
||||
// and...
|
||||
effGetParameterProperties, // of param <index>, VstParameterProperties* in <ptr>
|
||||
effKeysRequired, // returns 0: needs keys (default for 1.0 plugs), 1: don't need
|
||||
effGetVstVersion, // returns 2; older versions return 0
|
||||
|
||||
effNumV2Opcodes
|
||||
// note that effNumOpcodes doesn't apply anymore
|
||||
};
|
||||
|
||||
typedef struct VstParameterProperties VstParameterProperties;
|
||||
typedef struct VstPinProperties VstPinProperties;
|
||||
|
||||
struct VstParameterProperties
|
||||
{
|
||||
float stepFloat;
|
||||
float smallStepFloat;
|
||||
float largeStepFloat;
|
||||
char label[64];
|
||||
long flags;
|
||||
long minInteger;
|
||||
long maxInteger;
|
||||
long stepInteger;
|
||||
long largeStepInteger;
|
||||
char shortLabel[8]; // recommended: 6 + delimiter
|
||||
char future[48];
|
||||
};
|
||||
|
||||
// parameter properties flags
|
||||
enum
|
||||
{
|
||||
kVstParameterIsSwitch = 1 << 0,
|
||||
kVstParameterUsesIntegerMinMax = 1 << 1,
|
||||
kVstParameterUsesFloatStep = 1 << 2,
|
||||
kVstParameterUsesIntStep = 1 << 3
|
||||
};
|
||||
|
||||
struct VstPinProperties
|
||||
{
|
||||
char label[64];
|
||||
long flags;
|
||||
long reserved;
|
||||
char shortLabel[8]; // recommended: 6 + delimiter
|
||||
char future[48];
|
||||
};
|
||||
|
||||
// pin properties flags
|
||||
enum
|
||||
{
|
||||
kVstPinIsActive = 1 << 0,
|
||||
kVstPinIsStereo = 1 << 1
|
||||
};
|
||||
|
||||
// category
|
||||
enum VstPlugCategory
|
||||
{
|
||||
kPlugCategUnknown = 0,
|
||||
kPlugCategEffect,
|
||||
kPlugCategSynth,
|
||||
kPlugCategAnalysis,
|
||||
kPlugCategMastering,
|
||||
kPlugCategSpacializer, // 'panners'
|
||||
kPlugCategRoomFx, // delays and reverbs
|
||||
kPlugSurroundFx // dedicated surround processor
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// flags bits
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
effFlagsIsSynth = 1 << 8, // host may assign mixer channels for its outputs
|
||||
effFlagsNoSoundInStop = 1 << 9, // does not produce sound when input is all silence
|
||||
effFlagsExtIsAsync = 1 << 10, // for external dsp; plug returns immedeately from process()
|
||||
// host polls plug position (current block) via effGetCurrentPosition
|
||||
effFlagsExtHasBuffer = 1 << 11 // external dsp, may have their own output buffe (32 bit float)
|
||||
// host then requests this via effGetDestinationBuffer
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// surround setup
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstSpeakerProperties VstSpeakerProperties;
|
||||
typedef struct VstSpeakerArrangement VstSpeakerArrangement;
|
||||
|
||||
struct VstSpeakerProperties
|
||||
{ // units: range: except:
|
||||
float azimuth; // rad -PI...PI 10.f for LFE channel
|
||||
float elevation; // rad -PI/2...PI/2 10.f for LFE channel
|
||||
float radius; // meter 0.f for LFE channel
|
||||
float reserved; // 0.
|
||||
char name[64]; // for new setups, new names should be given (L/R/C... won't do)
|
||||
char future[32];
|
||||
};
|
||||
|
||||
// note: the origin for azimuth is right (as by math conventions dealing with radians);
|
||||
// the elevation origin is also right, visualizing a rotation of a circle across the
|
||||
// -pi/pi axis of the horizontal circle. thus, an elevation of -pi/2 corresponds
|
||||
// to bottom, and a speaker standing on the left, and 'beaming' upwards would have
|
||||
// an azimuth of -pi, and an elevation of pi/2.
|
||||
// for user interface representation, grads are more likely to be used, and the
|
||||
// origins will obviously 'shift' accordingly.
|
||||
|
||||
struct VstSpeakerArrangement
|
||||
{
|
||||
float lfeGain; // LFE channel gain is adjusted [dB] higher than other channels
|
||||
long numChannels; // number of channels in this speaker arrangement
|
||||
VstSpeakerProperties speakers[8]; // variable
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstOfflineTask VstOfflineTask;
|
||||
typedef struct VstAudioFile VstAudioFile;
|
||||
typedef struct VstAudioFileMarker VstAudioFileMarker;
|
||||
|
||||
struct VstOfflineTask
|
||||
{
|
||||
char processName[96]; // set by plug
|
||||
|
||||
// audio access
|
||||
double readPosition; // set by plug/host
|
||||
double writePosition; // set by plug/host
|
||||
long readCount; // set by plug/host
|
||||
long writeCount; // set by plug
|
||||
long sizeInputBuffer; // set by host
|
||||
long sizeOutputBuffer; // set by host
|
||||
void* inputBuffer; // set by host
|
||||
void* outputBuffer; // set by host
|
||||
double positionToProcessFrom; // set by host
|
||||
double numFramesToProcess; // set by host
|
||||
double maxFramesToWrite; // set by plug
|
||||
|
||||
// other data access
|
||||
void* extraBuffer; // set by plug
|
||||
long value; // set by host or plug
|
||||
long index; // set by host or plug
|
||||
|
||||
// file attributes
|
||||
double numFramesInSourceFile; // set by host
|
||||
double sourceSampleRate; // set by host or plug
|
||||
double destinationSampleRate; // set by host or plug
|
||||
long numSourceChannels; // set by host or plug
|
||||
long numDestinationChannels; // set by host or plug
|
||||
long sourceFormat; // set by host
|
||||
long destinationFormat; // set by plug
|
||||
char outputText[512]; // set by plug or host
|
||||
|
||||
// progress notification
|
||||
double progress; // set by plug
|
||||
long progressMode; // reserved for future
|
||||
char progressText[100]; // set by plug
|
||||
|
||||
long flags; // set by host and plug; see VstOfflineTaskFlags
|
||||
long returnValue; // reserved for future
|
||||
void* hostOwned; // set by host
|
||||
void* plugOwned; // set by plug
|
||||
|
||||
char future[1024];
|
||||
};
|
||||
|
||||
enum VstOfflineTaskFlags
|
||||
{
|
||||
// set by host
|
||||
kVstOfflineUnvalidParameter = 1 << 0,
|
||||
kVstOfflineNewFile = 1 << 1,
|
||||
|
||||
// set by plug
|
||||
kVstOfflinePlugError = 1 << 10,
|
||||
kVstOfflineInterleavedAudio = 1 << 11,
|
||||
kVstOfflineTempOutputFile = 1 << 12,
|
||||
kVstOfflineFloatOutputFile = 1 << 13,
|
||||
kVstOfflineRandomWrite = 1 << 14,
|
||||
kVstOfflineStretch = 1 << 15,
|
||||
kVstOfflineNoThread = 1 << 16
|
||||
};
|
||||
|
||||
// option passed to offlineRead/offlineWrite
|
||||
|
||||
enum VstOfflineOption
|
||||
{
|
||||
kVstOfflineAudio, // reading/writing audio samples
|
||||
kVstOfflinePeaks, // reading graphic representation
|
||||
kVstOfflineParameter, // reading/writing parameters
|
||||
kVstOfflineMarker, // reading/writing marker
|
||||
kVstOfflineCursor, // reading/moving edit cursor
|
||||
kVstOfflineSelection, // reading/changing selection
|
||||
kVstOfflineQueryFiles // to request the host to call asynchronously offlineNotify
|
||||
};
|
||||
|
||||
// structure passed to offlineNotify and offlineStart
|
||||
|
||||
struct VstAudioFile
|
||||
{
|
||||
long flags; // see enum VstAudioFileFlags
|
||||
void* hostOwned; // any data private to host
|
||||
void* plugOwned; // any data private to plugin
|
||||
char name[100]; // file title
|
||||
long uniqueId; // uniquely identify a file during a session
|
||||
double sampleRate; // file sample rate
|
||||
long numChannels; // number of channels (1 for mono, 2 for stereo...)
|
||||
double numFrames; // number of frames in the audio file
|
||||
long format; // reserved for future
|
||||
double editCursorPosition; // -1 if no such cursor
|
||||
double selectionStart; // frame index of first selected frame, or -1
|
||||
double selectionSize; // number of frames in selection, or 0
|
||||
long selectedChannelsMask; // 1 bit per channel
|
||||
long numMarkers; // number of markers in the file
|
||||
long timeRulerUnit; // see doc for possible values
|
||||
double timeRulerOffset; // offset in time ruler (positive or negative)
|
||||
double tempo; // as bpm
|
||||
long timeSigNumerator; // time signature numerator
|
||||
long timeSigDenominator; // time signature denominator
|
||||
long ticksPerBlackNote; // resolution
|
||||
long smpteFrameRate; // smpte rate (set as in VstTimeInfo)
|
||||
|
||||
char future[64];
|
||||
};
|
||||
|
||||
enum VstAudioFileFlags
|
||||
{
|
||||
// set by host (in call offlineNotify)
|
||||
kVstOfflineReadOnly = 1 << 0,
|
||||
kVstOfflineNoRateConversion = 1 << 1,
|
||||
kVstOfflineNoChannelChange = 1 << 2,
|
||||
|
||||
// Set by plug (in function offlineStart)
|
||||
kVstOfflineCanProcessSelection = 1 << 10,
|
||||
kVstOfflineNoCrossfade = 1 << 11,
|
||||
kVstOfflineWantRead = 1 << 12,
|
||||
kVstOfflineWantWrite = 1 << 13,
|
||||
kVstOfflineWantWriteMarker = 1 << 14,
|
||||
kVstOfflineWantMoveCursor = 1 << 15,
|
||||
kVstOfflineWantSelect = 1 << 16
|
||||
};
|
||||
|
||||
struct VstAudioFileMarker
|
||||
{
|
||||
double position;
|
||||
char name[32];
|
||||
long type;
|
||||
long id;
|
||||
long reserved;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// others
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
// structure passed to openWindow and closeWindow
|
||||
|
||||
struct VstWindow
|
||||
{
|
||||
char title[128]; // title
|
||||
short xPos; // position and size
|
||||
short yPos;
|
||||
short width;
|
||||
short height;
|
||||
long style; // 0: with title, 1: without title
|
||||
|
||||
void *parent; // parent of this window
|
||||
void *userHandle; // reserved
|
||||
void *winHandle; // reserved
|
||||
|
||||
char future[104];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,558 +0,0 @@
|
||||
#ifndef __audioeffectx__
|
||||
#include "audioeffectx.h"
|
||||
#endif
|
||||
|
||||
// *** steinberg developers: this is a public file, *do not edit!*
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//
|
||||
// you should not have to edit this file
|
||||
// use override methods instead, as suggested in the class declaration (audioeffectx.h)
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// 'canDo' strings. note other 'canDos' can be evaluated by calling the according
|
||||
// function, for instance if getSampleRate returns 0, you
|
||||
// will certainly want to assume that this selector is not supported.
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
const char* hostCanDos [] =
|
||||
{
|
||||
"sendVstEvents",
|
||||
"sendVstMidiEvent",
|
||||
"sendVstTimeInfo",
|
||||
"receiveVstEvents",
|
||||
"receiveVstMidiEvent",
|
||||
"receiveVstTimeInfo",
|
||||
|
||||
"reportConnectionChanges",
|
||||
"acceptIOChanges",
|
||||
"sizeWindow",
|
||||
|
||||
"asyncProcessing",
|
||||
"offline",
|
||||
"supplyIdle",
|
||||
"supportShell" // 'shell' handling via uniqueID as suggested by Waves
|
||||
};
|
||||
|
||||
const char* plugCanDos [] =
|
||||
{
|
||||
"sendVstEvents",
|
||||
"sendVstMidiEvent",
|
||||
"sendVstTimeInfo",
|
||||
"receiveVstEvents",
|
||||
"receiveVstMidiEvent",
|
||||
"receiveVstTimeInfo",
|
||||
"offline",
|
||||
"plugAsChannelInsert",
|
||||
"plugAsSend",
|
||||
"mixDryWet",
|
||||
"noRealTime",
|
||||
"multipass",
|
||||
"metapass",
|
||||
"1in1out",
|
||||
"1in2out",
|
||||
"2in1out",
|
||||
"2in2out",
|
||||
"2in4out",
|
||||
"4in2out",
|
||||
"4in4out",
|
||||
"4in8out", // 4:2 matrix to surround bus
|
||||
"8in4out", // surround bus to 4:2 matrix
|
||||
"8in8out"
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// AudioEffectX extends AudioEffect with the new features. so you should derive
|
||||
// your plug from AudioEffectX
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstEvents + VstTimeInfo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AudioEffectX::AudioEffectX (audioMasterCallback audioMaster, long numPrograms, long numParams)
|
||||
: AudioEffect (audioMaster, numPrograms, numParams)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AudioEffectX::~AudioEffectX ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::dispatcher (long opCode, long index, long value, void *ptr, float opt)
|
||||
{
|
||||
long v = 0;
|
||||
switch(opCode)
|
||||
{
|
||||
// VstEvents
|
||||
case effProcessEvents:
|
||||
v = processEvents ((VstEvents*)ptr);
|
||||
break;
|
||||
|
||||
// parameters and programs
|
||||
case effCanBeAutomated:
|
||||
v = canParameterBeAutomated (index) ? 1 : 0;
|
||||
break;
|
||||
case effString2Parameter:
|
||||
v = string2parameter (index, (char*)ptr) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case effGetNumProgramCategories:
|
||||
v = getNumCategories ();
|
||||
break;
|
||||
case effGetProgramNameIndexed:
|
||||
v = getProgramNameIndexed (value, index, (char*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effCopyProgram:
|
||||
v = copyProgram (index) ? 1 : 0;
|
||||
break;
|
||||
|
||||
// connections, configuration
|
||||
case effConnectInput:
|
||||
inputConnected (index, value ? true : false);
|
||||
v = 1;
|
||||
break;
|
||||
case effConnectOutput:
|
||||
outputConnected (index, value ? true : false);
|
||||
v = 1;
|
||||
break;
|
||||
case effGetInputProperties:
|
||||
v = getInputProperties (index, (VstPinProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetOutputProperties:
|
||||
v = getOutputProperties (index, (VstPinProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetPlugCategory:
|
||||
v = (long)getPlugCategory ();
|
||||
break;
|
||||
|
||||
// realtime
|
||||
case effGetCurrentPosition:
|
||||
v = reportCurrentPosition ();
|
||||
break;
|
||||
|
||||
case effGetDestinationBuffer:
|
||||
v = (long)reportDestinationBuffer ();
|
||||
break;
|
||||
|
||||
// offline
|
||||
case effOfflineNotify:
|
||||
v = offlineNotify ((VstAudioFile*)ptr, value, index != 0);
|
||||
break;
|
||||
case effOfflinePrepare:
|
||||
v = offlinePrepare ((VstOfflineTask*)ptr, value);
|
||||
break;
|
||||
case effOfflineRun:
|
||||
v = offlineRun ((VstOfflineTask*)ptr, value);
|
||||
break;
|
||||
|
||||
// other
|
||||
case effSetSpeakerArrangement:
|
||||
v = setSpeakerArrangement ((VstSpeakerArrangement*)value, (VstSpeakerArrangement*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effProcessVarIo:
|
||||
v = processVariableIo ((VstVariableIo*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effSetBlockSizeAndSampleRate:
|
||||
setBlockSizeAndSampleRate (value, opt);
|
||||
v = 1;
|
||||
break;
|
||||
case effSetBypass:
|
||||
v = setBypass (value ? true : false) ? 1 : 0;
|
||||
break;
|
||||
case effGetEffectName:
|
||||
v = getEffectName ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetErrorText:
|
||||
v = getErrorText ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetVendorString:
|
||||
v = getVendorString ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetProductString:
|
||||
v = getProductString ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetVendorVersion:
|
||||
v = getVendorVersion ();
|
||||
break;
|
||||
case effVendorSpecific:
|
||||
v = vendorSpecific (index, value, ptr, opt);
|
||||
break;
|
||||
case effCanDo:
|
||||
v = canDo ((char*)ptr);
|
||||
break;
|
||||
case effGetIcon:
|
||||
v = (long)getIcon ();
|
||||
break;
|
||||
case effSetViewPosition:
|
||||
v = setViewPosition (index, value) ? 1 : 0;
|
||||
break;
|
||||
case effGetTailSize:
|
||||
v = getGetTailSize ();
|
||||
break;
|
||||
case effIdle:
|
||||
v = fxIdle ();
|
||||
break;
|
||||
|
||||
case effGetParameterProperties:
|
||||
v = getParameterProperties (index, (VstParameterProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case effKeysRequired:
|
||||
v = (keysRequired () ? 0 : 1); // reversed to keep v1 compatibility
|
||||
break;
|
||||
case effGetVstVersion:
|
||||
v = getVstVersion ();
|
||||
break;
|
||||
|
||||
// version 1.0 or unknown
|
||||
default:
|
||||
v = AudioEffect::dispatcher (opCode, index, value, ptr, opt);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::wantEvents (long filter)
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterWantMidi, 0, filter, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
VstTimeInfo* AudioEffectX::getTimeInfo (long filter)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (VstTimeInfo*) audioMaster (&cEffect, audioMasterGetTime, 0, filter, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::tempoAt (long pos)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterTempoAt, 0, pos, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::sendVstEventsToHost (VstEvents* events)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterProcessEvents, 0, 0, events, 0) == 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// parameters
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getNumAutomatableParameters ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetNumAutomatableParameters, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getParameterQuantization ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetParameterQuantization, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// configuration
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::ioChanged ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterIOChanged, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::needIdle ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterNeedIdle, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::sizeWindow (long width, long height)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterSizeWindow, width, height, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
double AudioEffectX::updateSampleRate ()
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterGetSampleRate, 0, 0, 0, 0); // calls setSampleRate if implemented
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::updateBlockSize ()
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterGetBlockSize, 0, 0, 0, 0); // calls setBlockSize if implemented
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getInputLatency ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetInputLatency, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getOutputLatency ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetOutputLatency, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AEffect* AudioEffectX::getPreviousPlug (long input)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (AEffect*) audioMaster (&cEffect, audioMasterGetPreviousPlug, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AEffect* AudioEffectX::getNextPlug (long output)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (AEffect*) audioMaster (&cEffect, audioMasterGetNextPlug, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// configuration
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::willProcessReplacing ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterWillReplaceOrAccumulate, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getCurrentProcessLevel ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetCurrentProcessLevel, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getAutomationState ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetAutomationState, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::wantAsyncOperation (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsExtIsAsync;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsExtIsAsync;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::hasExternalBuffer (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsExtHasBuffer;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsExtHasBuffer;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineRead, readSource, option, offline, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineWrite (VstOfflineTask* offline, VstOfflineOption option)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineWrite, 0, option, offline, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineStart (VstAudioFile* audioFiles, long numAudioFiles, long numNewAudioFiles)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineStart, numNewAudioFiles, numAudioFiles, audioFiles, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::offlineGetCurrentPass ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineGetCurrentPass, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::offlineGetCurrentMetaPass ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineGetCurrentMetaPass, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// other
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::setOutputSamplerate (float sampleRate)
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterSetOutputSampleRate, 0, 0, 0, sampleRate);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetSpeakerArrangement, 0, (long)pluginInput, pluginOutput, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getHostVendorString (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetVendorString, 0, 0, text, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getHostProductString (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetProductString, 0, 0, text, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getHostVendorVersion ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetVendorVersion, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterVendorSpecific, lArg1, lArg2, ptrArg, floatArg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::canHostDo (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterCanDo, 0, 0, text, 0) != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::isSynth (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsIsSynth;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsIsSynth;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::noTail (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsNoSoundInStop;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsNoSoundInStop;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getHostLanguage ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetLanguage, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void* AudioEffectX::openWindow (VstWindow* window)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (void*)audioMaster (&cEffect, audioMasterOpenWindow, 0, 0, window, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::closeWindow (VstWindow* window)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterCloseWindow, 0, 0, window, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void* AudioEffectX::getDirectory ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (void*)(audioMaster (&cEffect, audioMasterGetDirectory, 0, 0, 0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::updateDisplay()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterUpdateDisplay, 0, 0, 0, 0)) ? true : false;
|
||||
return 0;
|
||||
}
|
||||
@ -1,185 +0,0 @@
|
||||
#ifndef __audioeffectx__
|
||||
#define __audioeffectx__
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __AudioEffect__
|
||||
#include "AudioEffect.hpp" // version 1.0 base class AudioEffect
|
||||
#endif
|
||||
|
||||
#ifndef __aeffectx__
|
||||
#include "aeffectx.h" // version 2.0 'C' extensions and structures
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// AudioEffectX extends AudioEffect with the new features. so you should derive
|
||||
// your plug from AudioEffectX
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class AudioEffectX : public AudioEffect
|
||||
{
|
||||
public:
|
||||
AudioEffectX (audioMasterCallback audioMaster, long numPrograms, long numParams);
|
||||
virtual ~AudioEffectX ();
|
||||
|
||||
virtual long dispatcher (long opCode, long index, long value, void *ptr, float opt);
|
||||
|
||||
// 'host' are methods which go from plug to host, and are usually not overridden
|
||||
// 'plug' are methods which you may override to implement the according functionality (to host)
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// events + time
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual void wantEvents (long filter = 1); // filter is currently ignored, midi channel data only (default)
|
||||
virtual VstTimeInfo* getTimeInfo (long filter);
|
||||
// returns const VstTimeInfo* (or 0 if not supported)
|
||||
// filter should contain a mask indicating which fields are requested
|
||||
// (see valid masks in aeffectx.h), as some items may require extensive
|
||||
// conversions
|
||||
virtual long tempoAt (long pos); // returns tempo (in bpm * 10000) at sample frame location <pos>
|
||||
bool sendVstEventsToHost (VstEvents* events); // true:success
|
||||
|
||||
// plug
|
||||
virtual long processEvents (VstEvents* events) {return 0;} // wants no more...else return 1!
|
||||
// VstEvents and VstMidiEvents are declared in aeffectx.h
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// parameters and programs
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual long getNumAutomatableParameters ();
|
||||
virtual long getParameterQuantization (); // returns the integer value for +1.0 representation,
|
||||
// or 1 if full single float precision is maintained
|
||||
// in automation. parameter index in <value> (-1: all, any)
|
||||
// plug
|
||||
virtual bool canParameterBeAutomated (long index) { return true; }
|
||||
virtual bool string2parameter (long index, char* text) {return false;} // note: implies setParameter. text==0 is to be
|
||||
// expected to check the capability (returns true).
|
||||
virtual float getChannelParameter (long channel, long index) {return 0;}
|
||||
virtual long getNumCategories () {return 1L;}
|
||||
virtual bool getProgramNameIndexed (long category, long index, char* text) {return false;}
|
||||
virtual bool copyProgram (long destination) {return false;}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// connections, configuration
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual bool ioChanged (); // tell host numInputs and/or numOutputs and/or numParameters has changed
|
||||
virtual bool needIdle (); // plug needs idle calls (outside its editor window)
|
||||
virtual bool sizeWindow (long width, long height);
|
||||
virtual double updateSampleRate (); // gets and returns sample rate from host (may issue setSampleRate() )
|
||||
virtual long updateBlockSize (); // same for block size
|
||||
virtual long getInputLatency ();
|
||||
virtual long getOutputLatency ();
|
||||
virtual AEffect* getPreviousPlug (long input); // input can be -1 in which case the first found is returned
|
||||
virtual AEffect* getNextPlug (long output); // output can be -1 in which case the first found is returned
|
||||
|
||||
// plug
|
||||
virtual void inputConnected (long index, bool state) {} // input at <index> has been (dis-)connected,
|
||||
virtual void outputConnected (long index, bool state) {} // same as input; state == true: connected
|
||||
virtual bool getInputProperties (long index, VstPinProperties* properties) {return false;}
|
||||
virtual bool getOutputProperties (long index, VstPinProperties* properties) {return false;}
|
||||
virtual VstPlugCategory getPlugCategory()
|
||||
{ if (cEffect.flags & effFlagsIsSynth) return kPlugCategSynth; return kPlugCategUnknown; }
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// realtime
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual long willProcessReplacing (); // returns 0: not implemented, 1: replacing, 2: accumulating
|
||||
virtual long getCurrentProcessLevel (); // returns: 0: not supported,
|
||||
// 1: currently in user thread (gui)
|
||||
// 2: currently in audio thread or irq (where process is called)
|
||||
// 3: currently in 'sequencer' thread or irq (midi, timer etc)
|
||||
// 4: currently offline processing and thus in user thread
|
||||
// other: not defined, but probably pre-empting user thread.
|
||||
virtual long getAutomationState (); // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
|
||||
virtual void wantAsyncOperation (bool state = true); // notify host that we want to operate asynchronously.
|
||||
// process() will return immedeately; host will poll getCurrentPosition
|
||||
// to see if data are available in time.
|
||||
virtual void hasExternalBuffer (bool state = true); // external dsp, may have their own output buffe (32 bit float)
|
||||
// host then requests this via effGetDestinationBuffer
|
||||
|
||||
// plug
|
||||
virtual long reportCurrentPosition () {return 0;} // for external dsp, see wantAsyncOperation ()
|
||||
virtual float* reportDestinationBuffer () {return 0;} // for external dsp (dma option)
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual bool offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource = true);
|
||||
virtual bool offlineWrite (VstOfflineTask* offline, VstOfflineOption option);
|
||||
virtual bool offlineStart (VstAudioFile* ptr, long numAudioFiles, long numNewAudioFiles);
|
||||
virtual long offlineGetCurrentPass ();
|
||||
virtual long offlineGetCurrentMetaPass ();
|
||||
|
||||
// plug
|
||||
virtual bool offlineNotify (VstAudioFile* ptr, long numAudioFiles, bool start) { return false; }
|
||||
virtual bool offlinePrepare (VstOfflineTask* offline, long count) {return false;}
|
||||
virtual bool offlineRun (VstOfflineTask* offline, long count) {return false;}
|
||||
|
||||
virtual long offlineGetNumPasses () {return 0;}
|
||||
virtual long offlineGetNumMetaPasses () {return 0;}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// other
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual void setOutputSamplerate (float samplerate);
|
||||
virtual bool getSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput);
|
||||
virtual bool getHostVendorString (char* text); // fills <text> with a string identifying the vendor (max 64 char)
|
||||
virtual bool getHostProductString (char* text); // fills <text> with a string with product name (max 64 char)
|
||||
virtual long getHostVendorVersion (); // returns vendor-specific version
|
||||
virtual long hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg); // no definition
|
||||
virtual long canHostDo (char* text); // see 'hostCanDos' in audioeffectx.cpp
|
||||
// returns 0: don't know (default), 1: yes, -1: no
|
||||
virtual void isSynth (bool state = true); // will call wantEvents if true
|
||||
virtual void noTail (bool state = true); // true: tells host we produce no output when silence comes in
|
||||
// enables host to omit process() when no data are present
|
||||
// on any one input.
|
||||
virtual long getHostLanguage (); // returns VstHostLanguage
|
||||
virtual void* openWindow (VstWindow*); // create new window
|
||||
virtual bool closeWindow (VstWindow*); // close a newly created window
|
||||
virtual void* getDirectory (); // get the plug's directory, FSSpec on mac, else char*
|
||||
virtual bool updateDisplay(); // something has changed, update 'multi-fx' display
|
||||
// returns true if supported
|
||||
|
||||
// plug
|
||||
virtual bool processVariableIo (VstVariableIo* varIo) {return false;}
|
||||
virtual bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput) {return false;}
|
||||
virtual void setBlockSizeAndSampleRate (long blockSize, float sampleRate)
|
||||
{this->blockSize = blockSize; this->sampleRate = sampleRate;}
|
||||
virtual bool setBypass(bool onOff) {return false;} // for 'soft-bypass; process() still called
|
||||
virtual bool getEffectName (char* name) {return false;} // name max 32 char
|
||||
virtual bool getErrorText (char* text) {return false;} // max 256 char
|
||||
virtual bool getVendorString (char* text) {return false;} // fill text with a string identifying the vendor (max 64 char)
|
||||
virtual bool getProductString (char* text) {return false;} // fill text with a string identifying the product name (max 64 char) // fills <ptr> with a string with product name (max 64 char)
|
||||
virtual long getVendorVersion () {return 0;} // return vendor-specific version
|
||||
virtual long vendorSpecific (long lArg, long lArg2, void* ptrArg, float floatArg) {return 0;}
|
||||
// no definition, vendor specific handling
|
||||
virtual long canDo (char* text) {return 0;} // see 'plugCanDos' in audioeffectx.cpp. return values:
|
||||
// 0: don't know (default), 1: yes, -1: no
|
||||
virtual void* getIcon () {return 0;} // not yet defined
|
||||
virtual bool setViewPosition (long x, long y) {return false;}
|
||||
virtual long getGetTailSize () {return 0; }
|
||||
virtual long fxIdle () {return 0;}
|
||||
virtual bool getParameterProperties (long index, VstParameterProperties* p) {return false;}
|
||||
virtual bool keysRequired () {return false;} // version 1 plugs will return true
|
||||
virtual long getVstVersion () {return 2;}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,628 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// Simple user interface framework for VST plugins
|
||||
// Standard control objects
|
||||
//
|
||||
// Version 1.0
|
||||
//
|
||||
// First version : Wolfgang Kundrus
|
||||
// Added new objects : Michael Schmidt 08.97
|
||||
// Added new objects : Yvan Grabit 01.98
|
||||
//
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __vstcontrols__
|
||||
#define __vstcontrols__
|
||||
|
||||
#ifndef __vstgui__
|
||||
#include "vstgui.h"
|
||||
#endif
|
||||
|
||||
//------------------
|
||||
// defines
|
||||
//------------------
|
||||
#ifndef kPI
|
||||
#define kPI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef k2PI
|
||||
#define k2PI 6.28318530717958647692
|
||||
#endif
|
||||
|
||||
#ifndef kPI_2
|
||||
#define kPI_2 1.57079632679489661923f
|
||||
#endif
|
||||
#ifndef kPI_4
|
||||
#define kPI_4 0.78539816339744830962
|
||||
#endif
|
||||
|
||||
#ifndef kE
|
||||
#define kE 2.7182818284590452354
|
||||
#endif
|
||||
|
||||
#ifndef kLN2
|
||||
#define kLN2 0.69314718055994530942
|
||||
#endif
|
||||
|
||||
|
||||
//------------------
|
||||
// CControlEnum type
|
||||
//------------------
|
||||
enum CControlEnum
|
||||
{
|
||||
kHorizontal = 1 << 0,
|
||||
kVertical = 1 << 1,
|
||||
kShadowText = 1 << 2,
|
||||
kLeft = 1 << 3,
|
||||
kRight = 1 << 4,
|
||||
kTop = 1 << 5,
|
||||
kBottom = 1 << 6,
|
||||
k3DIn = 1 << 7,
|
||||
k3DOut = 1 << 8,
|
||||
kPopupStyle = 1 << 9,
|
||||
kCheckStyle = 1 << 10
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CControlListener
|
||||
{
|
||||
public:
|
||||
virtual void valueChanged (CDrawContext *context, CControl *control) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CControl : public CView
|
||||
{
|
||||
public:
|
||||
CControl (CRect &size, CControlListener *listener, int tag);
|
||||
virtual ~CControl ();
|
||||
|
||||
virtual void draw (CDrawContext *context) = 0;
|
||||
virtual void update (CDrawContext *context);
|
||||
virtual void doIdleStuff () { if (parent) parent->doIdleStuff (); }
|
||||
|
||||
virtual void setValue (float val) { value = val; }
|
||||
virtual float getValue () { return value; };
|
||||
|
||||
virtual void setMin (float val) { vmin = val; }
|
||||
virtual float getMin () { return vmin; }
|
||||
virtual void setMax (float val) { vmax = val; }
|
||||
virtual float getMax () { return vmax; }
|
||||
|
||||
virtual void setOldValue (float val) { oldValue = val; }
|
||||
virtual float getOldValue (void) { return oldValue; }
|
||||
virtual void setDefaultValue (float val) { defaultValue = val; }
|
||||
virtual float getDefaultValue (void) { return defaultValue; }
|
||||
|
||||
inline int getTag () { return tag; }
|
||||
|
||||
virtual void setMouseEnabled (bool bEnable = true) { bMouseEnabled = bEnable; }
|
||||
virtual bool getMouseEnabled () { return bMouseEnabled; }
|
||||
|
||||
protected:
|
||||
CControlListener *listener;
|
||||
long tag;
|
||||
bool dirty;
|
||||
bool bMouseEnabled;
|
||||
float oldValue;
|
||||
float defaultValue;
|
||||
float value;
|
||||
float vmin;
|
||||
float vmax;
|
||||
float step;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class COnOffButton : public CControl
|
||||
{
|
||||
public:
|
||||
COnOffButton (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *handle);
|
||||
virtual ~COnOffButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CParamDisplay : public CControl
|
||||
{
|
||||
public:
|
||||
CParamDisplay (CRect &size, CBitmap *background = 0, int style = 0);
|
||||
virtual ~CParamDisplay ();
|
||||
|
||||
virtual void setFont (CFont fontID);
|
||||
virtual void setFontColor (CColor color);
|
||||
virtual void setBackColor (CColor color);
|
||||
virtual void setFrameColor (CColor color);
|
||||
virtual void setShadowColor (CColor color);
|
||||
|
||||
virtual void setHoriAlign (CHoriTxtAlign hAlign);
|
||||
virtual void setBackOffset (CPoint &offset);
|
||||
virtual void setStringConvert (void (*stringConvert) (float value, char *string));
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
|
||||
protected:
|
||||
void drawText (CDrawContext *context, char *string, CBitmap *newBack = 0);
|
||||
|
||||
CHoriTxtAlign horiTxtAlign;
|
||||
int style;
|
||||
|
||||
CFont fontID;
|
||||
CColor fontColor;
|
||||
CColor backColor;
|
||||
CColor frameColor;
|
||||
CColor shadowColor;
|
||||
CPoint offset;
|
||||
|
||||
CBitmap *background;
|
||||
|
||||
private:
|
||||
void (*stringConvert) (float value, char *string);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTextEdit : public CParamDisplay
|
||||
{
|
||||
public:
|
||||
CTextEdit (CRect &size, CControlListener *listener, int tag, const char *txt = 0,
|
||||
CBitmap *background = 0,
|
||||
int style = 0);
|
||||
~CTextEdit ();
|
||||
|
||||
virtual void setText (char *txt);
|
||||
virtual void getText (char *txt);
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setTextEditConvert (void (*stringConvert) (char *input, char *string));
|
||||
|
||||
virtual void takeFocus ();
|
||||
virtual void looseFocus ();
|
||||
|
||||
protected:
|
||||
void *platformControl;
|
||||
void *platformFont;
|
||||
char text[256];
|
||||
|
||||
private:
|
||||
void (*stringConvert) (char *input, char *string);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
#define MAX_ENTRY 128
|
||||
class COptionMenu : public CParamDisplay
|
||||
{
|
||||
public:
|
||||
COptionMenu (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *background = 0, CBitmap *bgWhenClick = 0,
|
||||
int style = 0);
|
||||
~COptionMenu ();
|
||||
|
||||
virtual bool addEntry (char *txt, int index = -1);
|
||||
virtual int getCurrent (char *txt = 0);
|
||||
virtual bool setCurrent (int index);
|
||||
virtual bool getEntry (int index, char *txt);
|
||||
virtual bool removeEntry (int index);
|
||||
virtual bool removeAllEntry ();
|
||||
virtual int getNbEntries () { return nbEntries; }
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void takeFocus ();
|
||||
virtual void looseFocus ();
|
||||
|
||||
#if MOTIF
|
||||
void setCurrentSelected (void *itemSelected);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void *platformControl;
|
||||
char *entry[MAX_ENTRY];
|
||||
|
||||
#if MOTIF
|
||||
void *itemWidget[MAX_ENTRY];
|
||||
#endif
|
||||
|
||||
int nbEntries;
|
||||
int currentIndex;
|
||||
CBitmap *bgWhenClick;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKnob : public CControl
|
||||
{
|
||||
public:
|
||||
CKnob (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *background,
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CKnob ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void valueToPoint (CPoint &point);
|
||||
virtual float valueFromPoint (CPoint &point);
|
||||
|
||||
virtual void setBackground (CBitmap* background);
|
||||
virtual CBitmap *getBackground () { return background; }
|
||||
|
||||
protected:
|
||||
int inset;
|
||||
CBitmap *background;
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAnimKnob : public CKnob
|
||||
{
|
||||
public:
|
||||
CAnimKnob (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CAnimKnob ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
protected:
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVerticalSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CVerticalSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
int iMaxPositions,
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CVerticalSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
int iMaxPositions;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHorizontalSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CHorizontalSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
int iMaxPositions,
|
||||
CBitmap *handle,
|
||||
CPoint &offset);
|
||||
virtual ~CHorizontalSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
int iMaxPositions;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CRockerSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CRockerSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CRockerSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMovieBitmap : public CControl
|
||||
{
|
||||
public:
|
||||
CMovieBitmap (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CMovieBitmap ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMovieButton : public CControl
|
||||
{
|
||||
public:
|
||||
CMovieButton (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CMovieButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
float buttonState;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// displays bitmaps within a (child-) window
|
||||
class CAutoAnimation : public CControl
|
||||
{
|
||||
public:
|
||||
CAutoAnimation (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps...
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CAutoAnimation ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void openWindow (void);
|
||||
virtual void closeWindow (void);
|
||||
|
||||
virtual void nextPixmap (void);
|
||||
virtual void previousPixmap (void);
|
||||
|
||||
bool isWindowOpened () { return windowOpened; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
|
||||
int subPixmaps;
|
||||
int heightOfOneImage;
|
||||
|
||||
bool windowOpened;
|
||||
int totalHeightOfBitmap;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vertical Slider
|
||||
class CVerticalSlider : public CControl
|
||||
{
|
||||
public:
|
||||
CVerticalSlider (CRect &size, CControlListener *listener, int tag,
|
||||
int iMinYPos, // min Y position in pixel
|
||||
int iMaxYPos, // max Y position in pixel
|
||||
CBitmap *handle, // bitmap slider
|
||||
CBitmap *background, // bitmap background
|
||||
CPoint &offset,
|
||||
int style = kBottom); // style (kBottom, kTop))
|
||||
|
||||
virtual ~CVerticalSlider ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setDrawTransparentHandle (bool val) { drawTransparentEnabled = val; }
|
||||
virtual void setOffsetHandle (CPoint &val) { offsetHandle = val; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CBitmap *background;
|
||||
|
||||
int widthOfSlider; // size of the handle-slider
|
||||
int heightOfSlider;
|
||||
|
||||
CPoint offset;
|
||||
CPoint offsetHandle;
|
||||
|
||||
int iMinYPos; // min Y position in pixel
|
||||
int iMaxYPos; // max Y position in pixel
|
||||
int style;
|
||||
|
||||
int actualYPos;
|
||||
bool drawTransparentEnabled;
|
||||
|
||||
int minTmp;
|
||||
int maxTmp;
|
||||
int widthControl;
|
||||
int heightControl;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Horizontal Slider
|
||||
class CHorizontalSlider : public CControl
|
||||
{
|
||||
public:
|
||||
CHorizontalSlider (CRect &size, CControlListener *listener, int tag,
|
||||
int iMinXPos, // min X position in pixel
|
||||
int iMaxXPos, // max X position in pixel
|
||||
CBitmap *handle, // bitmap slider
|
||||
CBitmap *background, // bitmap background
|
||||
CPoint &offset,
|
||||
int style = kRight); // style (kRight, kLeft));
|
||||
|
||||
virtual ~CHorizontalSlider ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setDrawTransparentHandle (bool val) { drawTransparentEnabled = val; }
|
||||
virtual void setOffsetHandle (CPoint &val) { offsetHandle = val; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CBitmap *background;
|
||||
|
||||
int widthOfSlider; // size of the handle-slider
|
||||
int heightOfSlider;
|
||||
|
||||
CPoint offset;
|
||||
CPoint offsetHandle;
|
||||
|
||||
int iMinXPos; // min X position in pixel
|
||||
int iMaxXPos; // max X position in pixel
|
||||
int style;
|
||||
|
||||
int actualXPos;
|
||||
bool drawTransparentEnabled;
|
||||
|
||||
int minTmp;
|
||||
int maxTmp;
|
||||
int widthControl;
|
||||
int heightControl;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// special display with custom numbers (0...9)
|
||||
class CSpecialDigit : public CControl
|
||||
{
|
||||
public:
|
||||
CSpecialDigit (CRect &size, CControlListener *listener, int tag, // tag identifier
|
||||
long dwPos, // actual value
|
||||
int iNumbers, // amount of numbers (max 7)
|
||||
int *xpos, // array of all XPOS
|
||||
int *ypos, // array of all YPOS
|
||||
int width, // width of ONE number
|
||||
int height, // height of ONE number
|
||||
CBitmap *handle); // bitmap numbers
|
||||
virtual ~CSpecialDigit ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
virtual float getNormValue (void);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
int iNumbers; // amount of numbers
|
||||
int xpos[7]; // array of all XPOS, max 7 possible
|
||||
int ypos[7]; // array of all YPOS, max 7 possible
|
||||
int width; // width of ONE number
|
||||
int height; // height of ONE number
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKickButton : public CControl
|
||||
{
|
||||
public:
|
||||
CKickButton (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CKickButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSplashScreen : public CControl
|
||||
{
|
||||
public:
|
||||
CSplashScreen (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *handle,
|
||||
CRect &toDisplay,
|
||||
CPoint &offset);
|
||||
virtual ~CSplashScreen ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CRect toDisplay;
|
||||
CRect keepSize;
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVuMeter : public CControl
|
||||
{
|
||||
public:
|
||||
CVuMeter (CRect& size, CBitmap *onBitmap, CBitmap *offBitmap,
|
||||
int nbLed, const int style = kVertical);
|
||||
virtual ~CVuMeter ();
|
||||
|
||||
virtual void setDecreaseStepValue (float value) { decreaseValue = value; }
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
|
||||
protected:
|
||||
CBitmap *onBitmap;
|
||||
CBitmap *offBitmap;
|
||||
int nbLed;
|
||||
int style;
|
||||
float decreaseValue;
|
||||
|
||||
CRect rectOn;
|
||||
CRect rectOff;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,621 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// User interface framework for VST plugins
|
||||
//
|
||||
// Version 1.0
|
||||
//
|
||||
// First version : Wolfgang Kundrus
|
||||
// Added Motif/Windows version : Yvan Grabit 01.98
|
||||
// Added Mac version : Charlie Steinberg 02.98
|
||||
// Added BeOS version : Georges-Edouard Berenger 05.99
|
||||
//
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __vstgui__
|
||||
#define __vstgui__
|
||||
|
||||
// define global defines
|
||||
#if WIN32
|
||||
#define WINDOWS 1
|
||||
#elif SGI | SUN
|
||||
#define MOTIF 1
|
||||
#elif __MWERKS__
|
||||
#define MAC 1
|
||||
#endif
|
||||
|
||||
#ifndef __AEffEditor__
|
||||
#include "AEffEditor.hpp"
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------
|
||||
#if WINDOWS
|
||||
#include <windows.h>
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif MOTIF
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#ifdef NOBOOL
|
||||
#ifndef bool
|
||||
typedef short bool;
|
||||
#endif
|
||||
#ifndef false
|
||||
static const bool false = 0;
|
||||
#endif
|
||||
#ifndef true
|
||||
static const bool true = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// definition of struct for XPixmap resources
|
||||
struct CResTableEntry {
|
||||
int id;
|
||||
char **xpm;
|
||||
};
|
||||
|
||||
typedef CResTableEntry CResTable[];
|
||||
extern CResTable xpmResources;
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif MAC
|
||||
#include <Quickdraw.h>
|
||||
class CCashedPict;
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif BEOS
|
||||
#include <View.h>
|
||||
class PlugView;
|
||||
class BBitmap;
|
||||
class BResources;
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------
|
||||
//----------------------------------------------------
|
||||
class CFrame;
|
||||
class CDrawContext;
|
||||
class COffscreenContext;
|
||||
class CControl;
|
||||
class CBitmap;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AEffGUIEditor Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class AEffGUIEditor : public AEffEditor
|
||||
{
|
||||
public :
|
||||
|
||||
AEffGUIEditor (AudioEffect *effect);
|
||||
|
||||
virtual ~AEffGUIEditor ();
|
||||
|
||||
virtual void setParameter (long index, float value) { postUpdate (); }
|
||||
virtual long getRect (ERect **rect);
|
||||
virtual long open (void *ptr);
|
||||
virtual void idle ();
|
||||
virtual void draw (ERect *rect);
|
||||
#if MAC
|
||||
virtual long mouse (long x, long y);
|
||||
#endif
|
||||
|
||||
// get the current time (in ms)
|
||||
long getTicks ();
|
||||
|
||||
// feedback to appli.
|
||||
void doIdleStuff ();
|
||||
|
||||
// get the effect attached to this editor
|
||||
AudioEffect *getEffect () { return effect; }
|
||||
|
||||
//---------------------------------------
|
||||
protected:
|
||||
ERect rect;
|
||||
CFrame *frame;
|
||||
|
||||
unsigned long lLastTicks;
|
||||
|
||||
private:
|
||||
short sInControlLoop;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CRect
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CRect
|
||||
{
|
||||
CRect (long left = 0, long top = 0, long right = 0, long bottom = 0)
|
||||
: left (left), top (top), right (right), bottom (bottom) {}
|
||||
CRect (const CRect& r)
|
||||
: left (r.left), top (r.top), right (r.right), bottom (r.bottom) {}
|
||||
CRect& operator () (long left, long top, long right, long bottom)
|
||||
{
|
||||
if (left < right)
|
||||
this->left = left, this->right = right;
|
||||
else
|
||||
this->left = right, this->right = left;
|
||||
if (top < bottom)
|
||||
this->top = top, this->bottom = bottom;
|
||||
else
|
||||
this->top = bottom, this->bottom = top;
|
||||
return *this;
|
||||
}
|
||||
|
||||
long left;
|
||||
long top;
|
||||
long right;
|
||||
long bottom;
|
||||
inline long width () { return right - left; }
|
||||
inline long height () { return bottom - top; }
|
||||
|
||||
void offset (long x, long y) { left += x; right += x;
|
||||
top += y; bottom += y; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CPoint
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CPoint
|
||||
{
|
||||
CPoint (long h = 0, long v = 0) : h (h), v (v) {}
|
||||
CPoint& operator () (long h, long v)
|
||||
{ this->h = h; this->v = v;
|
||||
return *this; }
|
||||
|
||||
bool isInside (CRect& r)
|
||||
{ return h >= r.left && h <= r.right && v >= r.top && v <= r.bottom; }
|
||||
|
||||
long h;
|
||||
long v;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CColor
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CColor
|
||||
{
|
||||
CColor& operator () (unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char unused)
|
||||
{
|
||||
this->red = red;
|
||||
this->green = green;
|
||||
this->blue = blue;
|
||||
this->unused = unused;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CColor& operator = (CColor newColor)
|
||||
{
|
||||
red = newColor.red;
|
||||
green = newColor.green;
|
||||
blue = newColor.blue;
|
||||
unused = newColor.unused;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator != (CColor newColor)
|
||||
{
|
||||
return (red != newColor.red ||
|
||||
green != newColor.green ||
|
||||
blue != newColor.blue);
|
||||
}
|
||||
|
||||
bool operator == (CColor newColor)
|
||||
{
|
||||
return (red == newColor.red &&
|
||||
green == newColor.green &&
|
||||
blue == newColor.blue);
|
||||
}
|
||||
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char unused;
|
||||
};
|
||||
|
||||
// define some basic colors
|
||||
static CColor kTransparentCColor = {255, 255, 255, 0};
|
||||
static CColor kBlackCColor = {0, 0, 0, 0};
|
||||
static CColor kWhiteCColor = {255, 255, 255, 0};
|
||||
static CColor kGreyCColor = {127, 127, 127, 0};
|
||||
static CColor kRedCColor = {255, 0, 0, 0};
|
||||
static CColor kGreenCColor = {0 , 255, 0, 0};
|
||||
static CColor kBlueCColor = {0 , 0, 255, 0};
|
||||
static CColor kYellowCColor = {255, 255, 0, 0};
|
||||
static CColor kCyanCColor = {255, 0, 255, 0};
|
||||
static CColor kMagentaCColor= {0 , 255, 255, 0};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------
|
||||
// Font type
|
||||
//-----------
|
||||
enum CFont
|
||||
{
|
||||
kSystemFont = 0,
|
||||
kNormalFontVeryBig,
|
||||
kNormalFontBig,
|
||||
kNormalFont,
|
||||
kNormalFontSmall,
|
||||
kNormalFontVerySmall,
|
||||
kSymbolFont,
|
||||
|
||||
kNumStandardFonts
|
||||
};
|
||||
|
||||
//-----------
|
||||
// Line style
|
||||
//-----------
|
||||
enum CLineStyle
|
||||
{
|
||||
kLineSolid = 0,
|
||||
kLineOnOffDash
|
||||
};
|
||||
|
||||
//----------------------------
|
||||
// Text alignment (Horizontal)
|
||||
//----------------------------
|
||||
enum CHoriTxtAlign
|
||||
{
|
||||
kLeftText = 0,
|
||||
kCenterText,
|
||||
kRightText
|
||||
};
|
||||
|
||||
//----------------------------
|
||||
// Buttons Type (+modifiers)
|
||||
//----------------------------
|
||||
enum CButton
|
||||
{
|
||||
kLButton = 1,
|
||||
kMButton = 2,
|
||||
kRButton = 4,
|
||||
kShift = 8,
|
||||
kControl = 16,
|
||||
kAlt = 32,
|
||||
kApple = 64
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CDrawContext Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDrawContext
|
||||
{
|
||||
public:
|
||||
CDrawContext (CFrame *frame, void *systemContext, void *window = 0);
|
||||
virtual ~CDrawContext ();
|
||||
|
||||
void moveTo (CPoint &point);
|
||||
void lineTo (CPoint &point);
|
||||
|
||||
void polyLine (CPoint *point, int numberOfPoints);
|
||||
void fillPolygon (CPoint *point, int numberOfPoints);
|
||||
|
||||
void drawRect (CRect &rect);
|
||||
void fillRect (CRect &rect);
|
||||
|
||||
void drawArc (CRect &rect, CPoint &point1, CPoint &point2);
|
||||
void fillArc (CRect &rect, CPoint &point1, CPoint &point2);
|
||||
|
||||
void drawEllipse (CRect &rect);
|
||||
void fillEllipse (CRect &rect);
|
||||
|
||||
void drawPoint (CPoint &point, CColor color);
|
||||
|
||||
void setLineStyle (CLineStyle style);
|
||||
CLineStyle getLineStyle () { return lineStyle; }
|
||||
|
||||
void setLineWidth (int width);
|
||||
int getLineWidth () { return frameWidth; }
|
||||
|
||||
void setFillColor (CColor color);
|
||||
CColor getFillColor () { return fillColor; }
|
||||
|
||||
void setFrameColor (CColor color);
|
||||
CColor getFrameColor () { return frameColor; }
|
||||
|
||||
void setFontColor (CColor color);
|
||||
CColor getFontColor () { return fontColor; }
|
||||
void setFont (CFont fontID, const int size = 0);
|
||||
|
||||
void drawString (const char *string, CRect &rect, const short opaque = false,
|
||||
const CHoriTxtAlign hAlign = kCenterText);
|
||||
|
||||
int getMouseButtons ();
|
||||
void getMouseLocation (CPoint &point);
|
||||
|
||||
#if MOTIF
|
||||
int getIndexColor (CColor color);
|
||||
Colormap getColormap ();
|
||||
Visual *getVisual ();
|
||||
unsigned int getDepth ();
|
||||
|
||||
static int nbNewColor;
|
||||
#endif
|
||||
|
||||
void *getWindow () { return window; }
|
||||
void setWindow (void *ptr) { window = ptr; }
|
||||
void getLoc (CPoint &where) { where = penLoc; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
|
||||
friend class CBitmap;
|
||||
friend class COffscreenContext;
|
||||
|
||||
void *getSystemContext () { return systemContext; }
|
||||
|
||||
void *systemContext;
|
||||
void *window;
|
||||
CFrame *frame;
|
||||
|
||||
int fontSize;
|
||||
CColor fontColor;
|
||||
CPoint penLoc;
|
||||
|
||||
int frameWidth;
|
||||
CColor frameColor;
|
||||
CColor fillColor;
|
||||
CLineStyle lineStyle;
|
||||
|
||||
#if WINDOWS
|
||||
void *brush;
|
||||
void *pen;
|
||||
void *font;
|
||||
void *oldbrush;
|
||||
void *oldpen;
|
||||
void *oldfont;
|
||||
int iPenStyle;
|
||||
|
||||
#elif MAC
|
||||
FontInfo fontInfoStruct;
|
||||
Pattern fillPattern;
|
||||
|
||||
#elif MOTIF
|
||||
Display *display;
|
||||
|
||||
XFontStruct *fontInfoStruct;
|
||||
CFont fontInfoId;
|
||||
|
||||
#elif BEOS
|
||||
BView* plugView;
|
||||
BFont font;
|
||||
void lineFromTo (CPoint& cstart, CPoint& cend);
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// COffscreenContext Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class COffscreenContext : public CDrawContext
|
||||
{
|
||||
public:
|
||||
COffscreenContext (CDrawContext *context, CBitmap *bitmap);
|
||||
COffscreenContext (CFrame *frame, long width, long height, const CColor backgroundColor = kBlackCColor);
|
||||
|
||||
virtual ~COffscreenContext ();
|
||||
|
||||
void transfert (CDrawContext *context, CRect destRect, CPoint srcOffset = CPoint (0, 0));
|
||||
inline int getWidth () { return width; }
|
||||
inline int getHeight () { return height; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
bool destroyPixmap;
|
||||
CBitmap *bitmap;
|
||||
|
||||
long height;
|
||||
long width;
|
||||
|
||||
CColor backgroundColor;
|
||||
|
||||
#if MOTIF
|
||||
Display *xdisplay;
|
||||
|
||||
#elif BEOS
|
||||
BBitmap *offscreenBitmap;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CBitmap Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBitmap
|
||||
{
|
||||
public:
|
||||
CBitmap (int resourceID);
|
||||
CBitmap (CFrame &frame, int width, int height);
|
||||
~CBitmap ();
|
||||
|
||||
void draw (CDrawContext*, CRect &rect, const CPoint &offset = CPoint (0, 0));
|
||||
void drawTransparent (CDrawContext *context, CRect &rect, const CPoint &offset = CPoint (0, 0));
|
||||
|
||||
inline int getWidth () { return width; }
|
||||
inline int getHeight () { return height; }
|
||||
|
||||
void forget ();
|
||||
void remember ();
|
||||
|
||||
void *getHandle () { return handle; }
|
||||
|
||||
#if BEOS
|
||||
static void closeResource ();
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
int resourceID;
|
||||
void *handle;
|
||||
void *mask;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int nbReference;
|
||||
|
||||
#if MOTIF
|
||||
void *createPixmapFromXpm (CDrawContext *context);
|
||||
|
||||
char **dataXpm;
|
||||
Display *xdisplay;
|
||||
|
||||
#elif MAC
|
||||
CCashedPict *pPict;
|
||||
|
||||
#elif BEOS
|
||||
static BResources *resourceFile;
|
||||
BBitmap *bbitmap;
|
||||
bool transparencySet;
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CView Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CView
|
||||
{
|
||||
public:
|
||||
CView (CRect &size);
|
||||
virtual ~CView ();
|
||||
|
||||
void redraw ();
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
virtual void update (CDrawContext *context);
|
||||
|
||||
virtual void looseFocus ();
|
||||
virtual void takeFocus ();
|
||||
|
||||
virtual void setTempOffscreen (COffscreenContext *tempOffscr);
|
||||
|
||||
int getHeight () { return size.height (); }
|
||||
int getWidth () { return size.width (); }
|
||||
|
||||
CFrame *getParent () { return parent; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
friend class CControl;
|
||||
friend class CFrame;
|
||||
CRect size;
|
||||
CFrame *parent;
|
||||
COffscreenContext *tempOffscreen;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CFrame Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFrame : public CView
|
||||
{
|
||||
public:
|
||||
CFrame (CRect &size, void *systemWindow, AEffGUIEditor *editor);
|
||||
CFrame (CRect &size, char *title, AEffGUIEditor *editor, const int style = 0);
|
||||
|
||||
~CFrame ();
|
||||
|
||||
bool open (CPoint *point = 0);
|
||||
bool close ();
|
||||
bool isOpen () { return openFlag; }
|
||||
|
||||
void draw (CDrawContext *context);
|
||||
void draw (CView *view = 0);
|
||||
void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
void update (CDrawContext *context);
|
||||
void idle ();
|
||||
void doIdleStuff () { if (editor) editor->doIdleStuff (); }
|
||||
|
||||
bool getPosition (int &x, int &y);
|
||||
bool setSize (int width, int height);
|
||||
bool getSize (CRect *size);
|
||||
|
||||
void setBackground (CBitmap *background);
|
||||
CBitmap *getBackground () { return background; }
|
||||
|
||||
virtual bool addView (CView *view);
|
||||
virtual bool removeView (CView *view);
|
||||
|
||||
int setModalView (CView *view);
|
||||
|
||||
#if WINDOWS
|
||||
void *getSystemWindow () { return hwnd;}
|
||||
#elif BEOS
|
||||
void *getSystemWindow () { return plugView;}
|
||||
#else
|
||||
void *getSystemWindow () { return systemWindow;}
|
||||
#endif
|
||||
|
||||
AEffGUIEditor *getEditor () { return editor; }
|
||||
|
||||
void setEditView (CView *view) { editView = view; }
|
||||
CView *getEditView () { return editView; }
|
||||
|
||||
#if MOTIF
|
||||
Colormap getColormap () { return colormap; }
|
||||
Visual *getVisual () { return visual; }
|
||||
unsigned int getDepth () { return depth; }
|
||||
Display *getDisplay () { return display; }
|
||||
Window getWindow () { return window; }
|
||||
void freeGc ();
|
||||
|
||||
Region region;
|
||||
|
||||
GC gc;
|
||||
GC getGC () { return gc; }
|
||||
#else
|
||||
void *getGC () { return 0; }
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
bool initFrame (void *systemWin);
|
||||
|
||||
AEffGUIEditor *editor;
|
||||
|
||||
void *systemWindow;
|
||||
CBitmap *background;
|
||||
int viewCount;
|
||||
int maxViews;
|
||||
CView **views;
|
||||
CView *modalView;
|
||||
CView *editView;
|
||||
|
||||
bool firstDraw;
|
||||
bool openFlag;
|
||||
|
||||
#if WINDOWS
|
||||
void *hwnd;
|
||||
friend LONG WINAPI WindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
#elif MOTIF
|
||||
Colormap colormap;
|
||||
Display *display;
|
||||
Visual *visual;
|
||||
Window window;
|
||||
unsigned int depth;
|
||||
|
||||
friend void _destroyCallback (Widget, XtPointer, XtPointer);
|
||||
|
||||
#elif BEOS
|
||||
PlugView *plugView;
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
private:
|
||||
bool addedWindow;
|
||||
void *vstWindow;
|
||||
};
|
||||
|
||||
|
||||
// include the control object
|
||||
#ifndef __vstcontrols__
|
||||
#include "vstcontrols.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-End--------------------------------------
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,898 +0,0 @@
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // useful macros
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // export function (make it accessable from main.cpp)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%macro export_func 1
|
||||
global _%1
|
||||
_%1:
|
||||
%endmacro
|
||||
;%define USE_SECTIONS
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // basic defines for the song/synth
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%define SAMPLE_RATE 44100
|
||||
%define MAX_INSTRUMENTS 9
|
||||
%define MAX_VOICES 1
|
||||
%define HLD 1 ; // can be adjusted to give crinkler some other possibilities
|
||||
%define BPM 100
|
||||
%define MAX_PATTERNS 62
|
||||
%define PATTERN_SIZE_SHIFT 4
|
||||
%define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
%define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
%define SAMPLES_PER_TICK (SAMPLE_RATE*4*60/(BPM*16))
|
||||
%define DEF_LFO_NORMALIZE 0.000038
|
||||
%define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // some defines for unit usage, which reduce synth code size
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;%define GO4K_USE_16BIT_OUTPUT ; // removing this will output to 32bit floating point buffer
|
||||
;%define GO4K_USE_GROOVE_PATTERN ; // removing this skips groove pattern code
|
||||
;%define GO4K_USE_ENVELOPE_RECORDINGS ; // removing this skips envelope recording code
|
||||
;%define GO4K_USE_NOTE_RECORDINGS ; // removing this skips note recording code
|
||||
%define GO4K_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units
|
||||
%define GO4K_CLIP_OUTPUT ; // removing this skips clipping code for the final output
|
||||
%define GO4K_USE_DST ; // removing this will skip DST unit
|
||||
%define GO4K_USE_DLL ; // removing this will skip DLL unit
|
||||
%define GO4K_USE_PAN ; // removing this will skip PAN unit
|
||||
%define GO4K_USE_GLOBAL_DLL ; // removing this will skip global dll processing
|
||||
%define GO4K_USE_FSTG ; // removing this will skip global store unit
|
||||
%define GO4K_USE_FLD ; // removing this will skip float load unit
|
||||
%define GO4K_USE_ENV_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_ENV_MOD_GM ; // removing this will skip env gain modulation code
|
||||
%define GO4K_USE_ENV_MOD_ADR ; // removing this will skip env attack/decay/release modulation code
|
||||
%define GO4K_USE_VCO_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code
|
||||
%define GO4K_USE_VCO_SHAPE ; // removing this skips waveshaping code
|
||||
%define GO4K_USE_VCO_GATE ; // removing this skips gate code
|
||||
%define GO4K_USE_VCO_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCO_MOD_PM ; // removing this skips phase modulation code
|
||||
%define GO4K_USE_VCO_MOD_TM ; // removing this skips transpose modulation code
|
||||
%define GO4K_USE_VCO_MOD_DM ; // removing this skips detune modulation code
|
||||
%define GO4K_USE_VCO_MOD_CM ; // removing this skips color modulation code
|
||||
%define GO4K_USE_VCO_MOD_GM ; // removing this skips gain modulation code
|
||||
%define GO4K_USE_VCO_MOD_SM ; // removing this skips shaping modulation code
|
||||
%define GO4K_USE_VCF_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCF_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCF_MOD_RM ; // removing this skips resonance modulation code
|
||||
%define GO4K_USE_VCF_HIGH ; // removing this skips code for high output
|
||||
%define GO4K_USE_VCF_BAND ; // removing this skips code for band output
|
||||
%define GO4K_USE_VCF_PEAK ; // removing this skips code for peak output
|
||||
%define GO4K_USE_DST_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_DST_SH ; // removing this skips sample and hold code
|
||||
%define GO4K_USE_DST_MOD_DM ; // removing this skips distortion modulation code
|
||||
%define GO4K_USE_DST_MOD_SH ; // removing this skips sample and hold modulation code
|
||||
%define GO4K_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong)
|
||||
%define GO4K_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code
|
||||
%define GO4K_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping
|
||||
%define GO4K_USE_DLL_DAMP ; // removing this will skip dll damping code
|
||||
%define GO4K_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code
|
||||
%define GO4K_USE_FOP_LOADNOTE ; // removing this will skip load note code
|
||||
%define GO4K_USE_FSTG_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_PAN_MOD ; // removing this will skip panning modulation code
|
||||
%define GO4K_USE_OUT_MOD_AM ; // removing this skips output aux send modulation code
|
||||
%define GO4K_USE_OUT_MOD_GM ; // removing this skips output gain modulation code
|
||||
%define GO4K_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code
|
||||
%define GO4K_USE_FLD_MOD_VM ; // removing this will skip float load modulation code
|
||||
%define GO4K_USE_DLL_MOD ; // define this to enable modulations for delay line
|
||||
%define GO4K_USE_DLL_MOD_PM ; // define this to enable pregain modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_FM ; // define this to enable feebback modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_IM ; // define this to enable dry modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_DM ; // define this to enable damping modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_SM ; // define this to enable lfo freq modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_AM ; // define this to enable lfo depth modulation for delay line
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // synth defines
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%define MAX_DELAY 65536
|
||||
%define MAX_WORKSPACE_SLOTS 8
|
||||
%define GO4K_BEGIN_CMDDEF(def_name)
|
||||
%define GO4K_END_CMDDEF db 0
|
||||
%define GO4K_BEGIN_PARAMDEF(def_name)
|
||||
%define GO4K_END_PARAMDEF
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ENV structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ENV_ID equ 1
|
||||
%macro GO4K_ENV 5
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
%endmacro
|
||||
%define ATTAC(val) val
|
||||
%define DECAY(val) val
|
||||
%define SUSTAIN(val) val
|
||||
%define RELEASE(val) val
|
||||
%define GAIN(val) val
|
||||
struc go4kENV_val
|
||||
;// unit paramters
|
||||
.attac resd 1
|
||||
.decay resd 1
|
||||
.sustain resd 1
|
||||
.release resd 1
|
||||
.gain resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kENV_wrk
|
||||
;// work variables
|
||||
.state resd 1
|
||||
.level resd 1
|
||||
;// modulation targets
|
||||
.gm resd 1
|
||||
.am resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%define ENV_STATE_ATTAC 0
|
||||
%define ENV_STATE_DECAY 1
|
||||
%define ENV_STATE_SUSTAIN 2
|
||||
%define ENV_STATE_RELEASE 3
|
||||
%define ENV_STATE_OFF 4
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCO structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCO_ID equ 2
|
||||
|
||||
%macro GO4K_VCO 8
|
||||
db %1
|
||||
db %2
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
db %3
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
db %4
|
||||
%endif
|
||||
db %5
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
db %6
|
||||
%else
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define TRANSPOSE(val) val
|
||||
%define DETUNE(val) val
|
||||
%define PHASE(val) val
|
||||
%define GATES(val) val
|
||||
%define COLOR(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
%define SINE 0x01
|
||||
%define TRISAW 0x02
|
||||
%define PULSE 0x04
|
||||
%define NOISE 0x08
|
||||
%define LFO 0x10
|
||||
%define GATE 0x20
|
||||
struc go4kVCO_val
|
||||
;// unit paramters
|
||||
.transpose resd 1
|
||||
.detune resd 1
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
.phaseofs resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
.gate resd 1
|
||||
%endif
|
||||
.color resd 1
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
.shape resd 1
|
||||
%endif
|
||||
.gain resd 1
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCO_wrk
|
||||
;// work variables
|
||||
.phase resd 1
|
||||
;// modulation targets
|
||||
.tm resd 1
|
||||
.dm resd 1
|
||||
.fm resd 1
|
||||
.pm resd 1
|
||||
.cm resd 1
|
||||
.sm resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCF structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCF_ID equ 3
|
||||
%macro GO4K_VCF 3
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%endmacro
|
||||
%define LOWPASS 0x1
|
||||
%define HIGHPASS 0x2
|
||||
%define BANDPASS 0x4
|
||||
%define BANDSTOP 0x3
|
||||
%define ALLPASS 0x7
|
||||
%define PEAK 0x8
|
||||
%define FREQUENCY(val) val
|
||||
%define RESONANCE(val) val
|
||||
%define VCFTYPE(val) val
|
||||
struc go4kVCF_val
|
||||
;// unit paramters
|
||||
.freq resd 1
|
||||
.res resd 1
|
||||
.type resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCF_wrk
|
||||
;// work variables
|
||||
.low resd 1
|
||||
.high resd 1
|
||||
.band resd 1
|
||||
.freq resd 1
|
||||
;// modulation targets
|
||||
.fm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DST_ID equ 4
|
||||
%macro GO4K_DST 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define DRIVE(val) val
|
||||
%define SNHFREQ(val) val
|
||||
struc go4kDST_val
|
||||
;// unit paramters
|
||||
.drive resd 1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
.snhfreq resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDST_wrk
|
||||
.out resd 1
|
||||
.snhphase resd 1
|
||||
;// modulation targets
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DLL structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DLL_ID equ 5
|
||||
%macro GO4K_DLL 8
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
db %4
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
db %5
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define PREGAIN(val) val
|
||||
%define DRY(val) val
|
||||
%define FEEDBACK(val) val
|
||||
%define DEPTH(val) val
|
||||
%define DAMP(val) val
|
||||
%define DELAY(val) val
|
||||
%define COUNT(val) val
|
||||
struc go4kDLL_val
|
||||
;// unit paramters
|
||||
.pregain resd 1
|
||||
.dry resd 1
|
||||
.feedback resd 1
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
.damp resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
.freq resd 1
|
||||
.depth
|
||||
%endif
|
||||
.delay resd 1
|
||||
.count resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk
|
||||
;// work variables
|
||||
.index resd 1
|
||||
.store resd 1
|
||||
.dcin resd 1
|
||||
.dcout resd 1
|
||||
.phase resd 1
|
||||
;// the delay buffer
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk2
|
||||
;// modulation targets
|
||||
.pm resd 1
|
||||
.fm resd 1
|
||||
.im resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.am resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FOP structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FOP_ID equ 6
|
||||
%macro GO4K_FOP 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OP(val) val
|
||||
%define FOP_POP 0x1
|
||||
%define FOP_ADDP 0x2
|
||||
%define FOP_MULP 0x3
|
||||
%define FOP_PUSH 0x4
|
||||
%define FOP_XCH 0x5
|
||||
%define FOP_ADD 0x6
|
||||
%define FOP_MUL 0x7
|
||||
%define FOP_ADDP2 0x8
|
||||
%define FOP_LOADNOTE 0x9
|
||||
struc go4kFOP_val
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFOP_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FST_ID equ 7
|
||||
%macro GO4K_FST 2
|
||||
db %1
|
||||
db %2
|
||||
%endmacro
|
||||
%define AMOUNT(val) val
|
||||
%define DEST(val) val
|
||||
struc go4kFST_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFST_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // PAN structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_PAN_ID equ 8
|
||||
%macro GO4K_PAN 1
|
||||
%ifdef GO4K_USE_PAN
|
||||
db %1
|
||||
%endif
|
||||
%endmacro
|
||||
%define PANNING(val) val
|
||||
struc go4kPAN_val
|
||||
%ifdef GO4K_USE_PAN
|
||||
.panning resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kPAN_wrk
|
||||
;// modulation targets
|
||||
.pm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // OUT structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_OUT_ID equ 9
|
||||
%macro GO4K_OUT 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define AUXSEND(val) val
|
||||
struc go4kOUT_val
|
||||
.gain resd 1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
.auxsend resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kOUT_wrk
|
||||
;// modulation targets
|
||||
.am resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ACC structs (this is for the synth def only)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ACC_ID equ 10
|
||||
%macro GO4K_ACC 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OUTPUT 0
|
||||
%define AUX 8
|
||||
%define ACCTYPE(val) val
|
||||
struc go4kACC_val
|
||||
.acctype resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kACC_wrk
|
||||
.size
|
||||
endstruc
|
||||
%ifdef GO4K_USE_FLD
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FLD structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FLD_ID equ 11
|
||||
%macro GO4K_FLD 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define VALUE(val) val
|
||||
struc go4kFLD_val
|
||||
.value resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFLD_wrk
|
||||
;// modulation targets
|
||||
.vm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
%ifdef GO4K_USE_FSTG
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FSTG structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FSTG_ID equ 12
|
||||
%macro GO4K_FSTG 2
|
||||
db %1
|
||||
dd %2
|
||||
%endmacro
|
||||
struc go4kFSTG_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFSTG_wrk
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Voice struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_instrument
|
||||
.release resd 1
|
||||
.note resd 1
|
||||
.workspace resd 256
|
||||
.dlloutl resd 1
|
||||
.dlloutr resd 1
|
||||
.outl resd 1
|
||||
.outr resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Synth struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_synth
|
||||
.instruments resb go4k_instrument.size * MAX_INSTRUMENTS * MAX_VOICES
|
||||
.global resb go4k_instrument.size * MAX_VOICES
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Data, reduced by 967 patterns
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc1 data align=1
|
||||
%else
|
||||
section .data align=1
|
||||
%endif
|
||||
go4k_patterns
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 81, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 84, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 88, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 52, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 57, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 60, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 64, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 72, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 64, HLD, 40, 52, 64, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 57, 0, 0, 57, 0, 0, 69, 0, 0, 69, 0, 0, 57, HLD, HLD, HLD,
|
||||
db 52, 64, 0, 57, 0, 69, 48, 0, 48, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 40, HLD, 40, 40, 40, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, 0, 0, 52, 0, 0, 40, 0, 52, 40, 0, 52, 0, 40, 0, 0,
|
||||
db 45, 0, 0, 57, 0, 0, 45, 0, 57, 45, 0, 57, 0, 45, 0, 0,
|
||||
db 48, 0, 0, 60, 0, 0, 48, 0, 60, 48, 0, 60, 0, 48, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 45, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 36, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 60, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 60, HLD, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 60, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
|
||||
db 91, 0, 0, 88, 0, 0, 76, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 88, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 84, 0, 0, 86, 0, 0, 88, 0, 0, 91, 0, 0, 84, 0, 0, 0,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
go4k_patterns_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Index List
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc2 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_pattern_lists
|
||||
Instrument0List db 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 1, 2, 3, 0, 4, 5, 6, 7, 8, 2, 9, 0, 0, 0,
|
||||
Instrument1List db 9, 7, 10, 7, 11, 7, 12, 7, 9, 7, 10, 7, 11, 7, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 13, 7, 14, 7, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 0, 0,
|
||||
Instrument2List db 15, 0, 16, 0, 17, 0, 18, 0, 19, 0, 16, 0, 17, 0, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 23, 15, 24, 16, 25, 17, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 0, 0, 0, 0,
|
||||
Instrument3List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0,
|
||||
Instrument4List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 29, 27, 29, 27, 29, 27, 29, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 0, 0, 0,
|
||||
Instrument5List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 0, 0,
|
||||
Instrument6List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 0, 0, 0, 0,
|
||||
Instrument7List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, 0, 37, 38, 36, 0, 39, 35, 36, 0, 37, 38, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument8List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 41, 0,
|
||||
go4k_pattern_lists_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Instrument Commands
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc3 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_instructions
|
||||
GO4K_BEGIN_CMDDEF(Instrument0)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument1)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument2)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument3)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument4)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument5)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument6)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument7)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument8)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FOP_ID
|
||||
GO4K_END_CMDDEF
|
||||
;// global commands
|
||||
GO4K_BEGIN_CMDDEF(Global)
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
go4k_synth_instructions_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Intrument Data
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc4 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_parameter_values
|
||||
GO4K_BEGIN_PARAMDEF(Instrument0)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
GO4K_FST AMOUNT(64),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(61),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(26),RESONANCE(128),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(104), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument1)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
GO4K_FST AMOUNT(64),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(112),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(80),DETUNE(112),PHASE(0),GATES(0),COLOR(64),SHAPE(16),GAIN(128),FLAGS(PULSE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(60),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(24),VCFTYPE(LOWPASS)
|
||||
GO4K_VCF FREQUENCY(48),RESONANCE(24),VCFTYPE(HIGHPASS)
|
||||
GO4K_DST DRIVE(64), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument2)
|
||||
GO4K_ENV ATTAC(32),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(64)
|
||||
GO4K_FST AMOUNT(120),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FST AMOUNT(68),DEST(2*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FST AMOUNT(60),DEST(3*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(18),RESONANCE(64),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(32),RESONANCE(48),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(88), SNHFREQ(128)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument3)
|
||||
GO4K_ENV ATTAC(0),DECAY(76),SUSTAIN(0),RELEASE(0),GAIN(32)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument4)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(96),RELEASE(64),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(70),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_DST DRIVE(32), SNHFREQ(128)
|
||||
GO4K_FST AMOUNT(80),DEST(6*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(46),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(128), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument5)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(128),RESONANCE(128),VCFTYPE(BANDPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument6)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(72),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(56),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_FST AMOUNT(108),DEST(6*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FST AMOUNT(72),DEST(7*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(32),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(80),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(64),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(104),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(22),RESONANCE(32),VCFTYPE(HIGHPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument7)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(96),RELEASE(32),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument8)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(128),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(48),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW|LFO)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_FSTG AMOUNT(72),DEST(2*go4k_instrument.size*MAX_VOICES+10*MAX_WORKSPACE_SLOTS*4+4*4+go4k_instrument.workspace)
|
||||
GO4K_FSTG AMOUNT(66),DEST(1*go4k_instrument.size*MAX_VOICES+10*MAX_WORKSPACE_SLOTS*4+4*4+go4k_instrument.workspace)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_END_PARAMDEF
|
||||
;// global parameters
|
||||
GO4K_BEGIN_PARAMDEF(Global)
|
||||
GO4K_ACC ACCTYPE(AUX)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(0),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(8),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_ACC ACCTYPE(OUTPUT)
|
||||
GO4K_FOP OP(FOP_ADDP2)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
go4k_synth_parameter_values_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Delay/Reverb Times
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc5 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL
|
||||
global _go4k_delay_times
|
||||
_go4k_delay_times
|
||||
dw 0
|
||||
dw 1116
|
||||
dw 1188
|
||||
dw 1276
|
||||
dw 1356
|
||||
dw 1422
|
||||
dw 1492
|
||||
dw 1556
|
||||
dw 1618
|
||||
dw 1140
|
||||
dw 1212
|
||||
dw 1300
|
||||
dw 1380
|
||||
dw 1446
|
||||
dw 1516
|
||||
dw 1580
|
||||
dw 1642
|
||||
times 100 dw 0
|
||||
%endif
|
||||
@ -1,2 +0,0 @@
|
||||
LIBRARY 4klang
|
||||
EXPORTS main
|
||||
@ -1,918 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// German (Germany) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BINARY
|
||||
//
|
||||
|
||||
IDR_COMP_RES BINARY "nasmw.bin"
|
||||
IDR_ASM_RES BINARY "4klang.bin"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_GO4KVSTIDIALOG DIALOGEX 0, 0, 594, 341
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Alcatraz - 4klang Synth Plugin - Version 3.0.1"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON "Load Patch Data",IDC_LOAD_PATCH,13,13,70,14
|
||||
PUSHBUTTON "Save Patch Data",IDC_SAVE_PATCH,85,13,70,14
|
||||
PUSHBUTTON "Reset Patch Data",IDC_RESET_PATCH,157,13,70,14
|
||||
PUSHBUTTON "Load Instrument",IDC_LOAD_INSTRUMENT,13,31,70,14
|
||||
PUSHBUTTON "Save Instrument",IDC_SAVE_INSTRUMENT,85,31,70,14
|
||||
PUSHBUTTON "Reset Instrument",IDC_RESET_INSTRUMENT,157,31,70,14
|
||||
LTEXT "Instrument Name",IDC_STATIC,242,33,56,8
|
||||
LTEXT "Instrument",IDC_STATIC,242,17,36,8
|
||||
EDITTEXT IDC_INSTRUMENT_NAME,301,30,84,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_INSTRUMENT,301,14,85,184,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "0",IDC_VOICECOUNT1,333,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT2,349,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT3,365,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT4,381,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT5,397,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT6,413,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT7,429,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT8,445,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT9,461,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT10,477,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT11,493,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT12,509,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT13,525,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT14,541,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT15,557,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "0",IDC_VOICECOUNT16,573,322,14,12,0,WS_EX_STATICEDGE
|
||||
LTEXT "Activated Voices",IDC_STATIC,278,324,54,8
|
||||
PUSHBUTTON "Record",IDC_RECORD_BUTTON,449,10,62,14
|
||||
PUSHBUTTON "Stop",IDC_STOP_BUTTON,449,24,62,14,WS_DISABLED
|
||||
CONTROL "Solo",IDC_SOLO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,398,24,29,10
|
||||
GROUPBOX "4k Export",IDC_STATIC,437,0,150,66
|
||||
COMBOBOX IDC_PATTERN_SIZE,479,38,33,94,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Current Unit",IDC_MODULE_SETTINGS,277,61,310,202
|
||||
CONTROL "",IDC_MAINTAB,"SysTabControl32",0x0,7,53,266,281
|
||||
GROUPBOX "Load/Save",IDC_STATIC,7,3,225,47
|
||||
PUSHBUTTON "PANIC!",IDC_PANIC,278,288,309,29
|
||||
GROUPBOX "Instrument Properties",IDC_STATIC,237,3,195,47
|
||||
COMBOBOX IDC_POLYPHONY,333,270,71,97,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Polyphony",IDC_STATIC,278,272,34,8
|
||||
LTEXT "Pattern",IDC_STATIC,450,41,25,8
|
||||
PUSHBUTTON "Reset",IDC_UNIT_RESET,303,72,50,14
|
||||
PUSHBUTTON "Copy",IDC_UNIT_COPY,355,72,50,14
|
||||
PUSHBUTTON "Paste",IDC_UNIT_PASTE,407,72,50,14
|
||||
PUSHBUTTON "Load",IDC_UNIT_LOAD,459,72,50,14
|
||||
PUSHBUTTON "Save",IDC_UNIT_SAVE,511,72,50,14
|
||||
CONTROL "Always on top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,527,267,64,20
|
||||
CONTROL "Record Notes",IDC_NOTEVALUES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,516,32,57,10
|
||||
CONTROL "Undenormalize",IDC_UNDENORMALIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,516,14,61,10
|
||||
CONTROL "Clip Output",IDC_CLIPOUTPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,516,5,52,10
|
||||
CONTROL "Record Envs",IDC_ENVLEVELS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,516,23,57,10
|
||||
CONTROL "16Bit Output",IDC_16BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,516,41,57,10
|
||||
CTEXT "Static",IDC_ISTACK_VALID,11,321,241,9
|
||||
CTEXT "Static",IDC_GSTACK_VALID,11,321,241,9
|
||||
COMBOBOX IDC_PATTERN_QUANT,479,51,33,94,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Quant.",IDC_STATIC,449,54,24,8
|
||||
COMBOBOX IDC_OBJFORMAT,515,51,66,72,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_VCO DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Oscillator",IDC_STATIC,0,0,300,170
|
||||
PUSHBUTTON "Sine",IDC_VCO_SINE,6,27,50,14,WS_DISABLED
|
||||
PUSHBUTTON "Tri/Saw",IDC_VCO_TRISAW,56,27,50,14
|
||||
PUSHBUTTON "Pulse",IDC_VCO_PULSE,106,27,50,14
|
||||
PUSHBUTTON "Noise",IDC_VCO_NOISE,156,27,50,14
|
||||
CONTROL "",IDC_VCO_GAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,127,200,15
|
||||
CONTROL "",IDC_VCO_TRANSPOSE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,47,200,15
|
||||
CONTROL "",IDC_VCO_DETUNE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,63,200,15
|
||||
CONTROL "",IDC_VCO_PHASE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,79,200,15
|
||||
CONTROL "",IDC_VCO_COLOR,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,95,200,15
|
||||
LTEXT "Transpose",IDC_STATIC,4,51,34,8
|
||||
LTEXT "Phase",IDC_STATIC,4,82,20,8
|
||||
LTEXT "Detune",IDC_STATIC,4,67,24,8
|
||||
LTEXT "Color",IDC_STATIC,4,98,18,8
|
||||
LTEXT "Gain",IDC_STATIC,4,130,15,8
|
||||
CONTROL "",IDC_VCO_SHAPE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,111,200,15
|
||||
LTEXT "Shape",IDC_STATIC,4,114,21,8
|
||||
CTEXT " ",IDC_VCO_TRANSPOSE_VAL,242,48,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCO_DETUNE_VAL,242,64,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCO_PHASE_VAL,242,80,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCO_COLOR_VAL,242,96,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCO_SHAPE_VAL,242,112,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCO_GAIN_VAL,242,128,48,12,SS_SUNKEN
|
||||
CONTROL "LFO",IDC_VCO_LFO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,262,29,29,10
|
||||
PUSHBUTTON "Gate",IDC_VCO_GATE,206,27,50,14
|
||||
CONTROL " ",IDC_VCO_GATE1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,43,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE2,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,55,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE3,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,67,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE4,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,79,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE5,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,91,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE6,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,103,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE7,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,115,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE8,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,127,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE9,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,139,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE10,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,151,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE11,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,163,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE12,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,175,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE13,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,187,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE14,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,199,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE15,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,211,147,8,10
|
||||
CONTROL " ",IDC_VCO_GATE16,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,223,147,8,10
|
||||
LTEXT "Gate",IDC_STATIC,4,147,16,8
|
||||
END
|
||||
|
||||
IDD_VCF DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Filter",IDC_STATIC,0,0,299,170
|
||||
PUSHBUTTON "Low",IDC_VCF_LOW,24,59,42,14,WS_DISABLED
|
||||
PUSHBUTTON "High",IDC_VCF_HIGH,66,59,41,14
|
||||
PUSHBUTTON "Band",IDC_VCF_BAND,108,59,41,14
|
||||
PUSHBUTTON "Notch",IDC_VCF_NOTCH,150,59,41,14
|
||||
PUSHBUTTON "Peak",IDC_VCF_PEAK,192,59,41,14
|
||||
PUSHBUTTON "All",IDC_VCF_ALL,234,59,41,14
|
||||
CONTROL "",IDC_VCF_FREQUENCY,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,79,200,15
|
||||
CONTROL "",IDC_VCF_RESONANCE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,95,200,15
|
||||
LTEXT "Frequency",IDC_STATIC,4,82,35,8
|
||||
LTEXT "Resonance",IDC_STATIC,4,99,36,8
|
||||
CTEXT " ",IDC_VCF_FREQUENCY_VAL,242,80,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_VCF_RESONANCE_VAL,242,96,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_ENV DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Envelope",IDC_STATIC,0,0,300,170
|
||||
CONTROL "",IDC_ENV_GAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,109,200,15
|
||||
CONTROL "",IDC_ENV_ATTACK,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,46,200,15
|
||||
CONTROL "",IDC_ENV_DECAY,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,61,200,15
|
||||
CONTROL "",IDC_ENV_SUSTAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,77,200,15
|
||||
CONTROL "",IDC_ENV_RELEASE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,93,200,15
|
||||
LTEXT "Attack",IDC_STATIC,4,49,22,8
|
||||
LTEXT "Sustain",IDC_STATIC,4,80,24,8
|
||||
LTEXT "Decay",IDC_STATIC,4,65,21,8
|
||||
LTEXT "Release",IDC_STATIC,4,96,26,8
|
||||
LTEXT "Gain",IDC_STATIC,4,112,15,8
|
||||
CTEXT " ",IDC_ENV_ATTACK_VAL,242,46,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_ENV_DECAY_VAL,242,62,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_ENV_SUSTAIN_VAL,242,78,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_ENV_RELEASE_VAL,242,94,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_ENV_GAIN_VAL,242,110,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_DLL DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Delay/Reverb",IDC_STATIC,0,0,300,170
|
||||
CONTROL "",IDC_DLL_DRY,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,73,200,15
|
||||
CONTROL "",IDC_DLL_PREGAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,42,200,15
|
||||
CONTROL "",IDC_DLL_FEEDBACK,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,57,200,15
|
||||
LTEXT "Pregain",IDC_STATIC,4,45,25,8
|
||||
LTEXT "Feedback",IDC_STATIC,4,61,32,8
|
||||
LTEXT "Dry",IDC_STATIC,4,76,12,8
|
||||
CTEXT " ",IDC_DLL_PREGAIN_VAL,242,42,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_DLL_FEEDBACK_VAL,242,58,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_DLL_DRY_VAL,242,74,48,12,SS_SUNKEN
|
||||
CONTROL "",IDC_DLL_DAMP,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,90,200,15
|
||||
LTEXT "Damp",IDC_STATIC,4,93,19,8
|
||||
CTEXT " ",IDC_DLL_DAMP_VAL,242,90,48,12,SS_SUNKEN
|
||||
PUSHBUTTON "Delay",IDC_DLL_DELAY,134,13,50,14
|
||||
PUSHBUTTON "Reverb",IDC_DLL_REVERB,184,13,50,14
|
||||
CONTROL "",IDC_DLL_DTIME,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,106,200,15
|
||||
LTEXT "Delay",IDC_STATIC,4,110,19,8
|
||||
PUSHBUTTON "BPM",IDC_DLL_BPMSYNC,47,15,40,10
|
||||
PUSHBUTTON "Note",IDC_DLL_NOTESYNC,87,15,40,10
|
||||
CTEXT " ",IDC_DLL_DTIME_VAL,242,106,48,12,SS_SUNKEN
|
||||
CONTROL "Left Reverb",IDC_DLL_LEFTREVERB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,241,16,54,10
|
||||
PUSHBUTTON "No Sync",IDC_DLL_NOSYNC,7,15,40,10
|
||||
CONTROL "",IDC_DLL_FREQUENCY,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,122,200,15
|
||||
LTEXT "Frequency",IDC_STATIC,4,127,35,8
|
||||
CTEXT " ",IDC_DLL_FREQUENCY_VAL,242,122,48,12,SS_SUNKEN
|
||||
CONTROL "",IDC_DLL_DEPTH,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,138,200,15
|
||||
LTEXT "Depth",IDC_STATIC,4,143,20,8
|
||||
CTEXT " ",IDC_DLL_DEPTH_VAL,242,138,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_DST DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Distortion",IDC_STATIC,0,0,299,170
|
||||
CONTROL "",IDC_DST_DRIVE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,69,200,15
|
||||
LTEXT "Drive",IDC_STATIC,4,73,18,8
|
||||
LTEXT "S&&H",IDC_STATIC,4,89,14,8
|
||||
CONTROL "",IDC_DST_SNH,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,85,200,15
|
||||
CTEXT " ",IDC_DST_DRIVE_VAL,242,70,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_DST_SNH_VAL,242,86,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_INSTRUMENT_STACK DIALOGEX 0, 0, 247, 320
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPCHILDREN | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT1,15,0,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP1,165,0,25,10,NOT WS_VISIBLE
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN1,191,0,25,10,NOT WS_VISIBLE
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT1,225,0,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT2,15,10,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP2,165,10,25,10,NOT WS_VISIBLE
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN2,191,10,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT2,225,10,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT3,15,20,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP3,165,20,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN3,191,20,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT3,225,20,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT4,15,30,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP4,165,30,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN4,191,30,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT4,225,30,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT5,15,40,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP5,165,40,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN5,191,40,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT5,225,40,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT6,15,50,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP6,165,50,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN6,191,50,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT6,225,50,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT7,15,60,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP7,165,60,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN7,191,60,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT7,225,60,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT8,15,70,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP8,165,70,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN8,191,70,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT8,225,70,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT9,15,80,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP9,165,80,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN9,191,80,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT9,225,80,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT10,15,90,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP10,165,90,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN10,191,90,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT10,225,90,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT11,15,100,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP11,165,100,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN11,191,100,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT11,225,100,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT12,15,110,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP12,165,110,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN12,191,110,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT12,225,110,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT13,15,120,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP13,165,120,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN13,191,120,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT13,225,120,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT14,15,130,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP14,165,130,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN14,191,130,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT14,225,130,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT15,15,140,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP15,165,140,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN15,191,140,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT15,225,140,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT16,15,150,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP16,165,150,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN16,191,150,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT16,225,150,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT17,15,160,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP17,165,160,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN17,191,160,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT17,225,160,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT18,15,170,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP18,165,170,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN18,191,170,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT18,225,170,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT19,15,180,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP19,165,180,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN19,191,180,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT19,225,180,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT20,15,190,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP20,165,190,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN20,191,190,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT20,225,190,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT21,15,200,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP21,165,200,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN21,191,200,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT21,225,200,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT22,15,210,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP22,165,210,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN22,191,210,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT22,225,210,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT23,15,220,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP23,165,220,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN23,191,220,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT23,225,220,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT24,15,230,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP24,165,230,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN24,191,230,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT24,225,230,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT25,15,240,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP25,165,240,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN25,191,240,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT25,225,240,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT26,15,250,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP26,165,250,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN26,191,250,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT26,225,250,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT27,15,260,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP27,165,260,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN27,191,260,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT27,225,260,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT28,15,270,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP28,165,270,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN28,191,270,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT28,225,270,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT29,15,280,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP29,165,280,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN29,191,280,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT29,225,280,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT30,15,290,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP30,165,290,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN30,191,290,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT30,225,290,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT31,15,300,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP31,165,300,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN31,191,300,25,10
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT31,225,300,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_ISTACK_UNIT32,15,310,83,10
|
||||
PUSHBUTTON "Up",IDC_ISTACK_UP32,165,310,25,10
|
||||
PUSHBUTTON "Down",IDC_ISTACK_DOWN32,191,310,25,10,NOT WS_VISIBLE
|
||||
CTEXT "1",IDC_ISTACK_SIGNALCOUNT32,225,310,16,10,SS_SUNKEN
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET1,106,0,25,10,NOT WS_VISIBLE
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET1,132,0,25,10,NOT WS_VISIBLE
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET2,106,10,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET2,132,10,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET3,106,20,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET3,132,20,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET4,106,30,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET4,132,30,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET5,106,40,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET5,132,40,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET6,106,50,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET6,132,50,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET7,106,60,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET7,132,60,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET8,106,70,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET8,132,70,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET9,106,80,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET9,132,80,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET10,106,90,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET10,132,90,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET11,106,100,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET11,132,100,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET12,106,110,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET12,132,110,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET13,106,120,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET13,132,120,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET14,106,130,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET14,132,130,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET15,106,140,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET15,132,140,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET16,106,150,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET16,132,150,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET17,106,160,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET17,132,160,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET18,106,170,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET18,132,170,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET19,106,180,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET19,132,180,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET20,106,190,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET20,132,190,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET21,106,200,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET21,132,200,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET22,106,210,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET22,132,210,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET23,106,220,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET23,132,220,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET24,106,230,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET24,132,230,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET25,106,240,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET25,132,240,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET26,106,250,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET26,132,250,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET27,106,260,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET27,132,260,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET28,106,270,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET28,132,270,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET29,106,280,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET29,132,280,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET30,106,290,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET30,132,290,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET31,106,300,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET31,132,300,25,10
|
||||
PUSHBUTTON "Set",IDC_ISTACK_SET32,106,310,25,10
|
||||
PUSHBUTTON "Clear",IDC_ISTACK_RESET32,132,310,25,10
|
||||
LTEXT "1:",IDC_STATIC,2,1,10,8
|
||||
LTEXT "2:",IDC_STATIC,2,11,10,8
|
||||
LTEXT "3:",IDC_STATIC,2,21,10,8
|
||||
LTEXT "4:",IDC_STATIC,2,31,10,8
|
||||
LTEXT "5:",IDC_STATIC,2,41,10,8
|
||||
LTEXT "6:",IDC_STATIC,2,51,10,8
|
||||
LTEXT "7:",IDC_STATIC,2,61,10,8
|
||||
LTEXT "8:",IDC_STATIC,2,71,10,8
|
||||
LTEXT "9:",IDC_STATIC,2,81,10,8
|
||||
LTEXT "10:",IDC_STATIC,2,91,10,8
|
||||
LTEXT "11:",IDC_STATIC,2,101,10,8
|
||||
LTEXT "12:",IDC_STATIC,2,111,10,8
|
||||
LTEXT "13:",IDC_STATIC,2,121,10,8
|
||||
LTEXT "14:",IDC_STATIC,2,131,10,8
|
||||
LTEXT "15:",IDC_STATIC,2,141,10,8
|
||||
LTEXT "16:",IDC_STATIC,2,151,10,8
|
||||
LTEXT "17:",IDC_STATIC,2,161,10,8
|
||||
LTEXT "18:",IDC_STATIC,2,171,10,8
|
||||
LTEXT "19:",IDC_STATIC,2,181,10,8
|
||||
LTEXT "20:",IDC_STATIC,2,191,10,8
|
||||
LTEXT "21:",IDC_STATIC,2,201,10,8
|
||||
LTEXT "22:",IDC_STATIC,2,211,10,8
|
||||
LTEXT "23:",IDC_STATIC,2,221,10,8
|
||||
LTEXT "24:",IDC_STATIC,2,231,10,8
|
||||
LTEXT "25:",IDC_STATIC,2,241,10,8
|
||||
LTEXT "26:",IDC_STATIC,2,251,10,8
|
||||
LTEXT "27:",IDC_STATIC,2,261,10,8
|
||||
LTEXT "28:",IDC_STATIC,2,271,10,8
|
||||
LTEXT "29:",IDC_STATIC,2,281,10,8
|
||||
LTEXT "30:",IDC_STATIC,2,291,10,8
|
||||
LTEXT "31:",IDC_STATIC,2,301,10,8
|
||||
LTEXT "32:",IDC_STATIC,2,311,10,8
|
||||
END
|
||||
|
||||
IDD_FOP DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Floating Point Operation",IDC_STATIC,0,0,299,170
|
||||
PUSHBUTTON "POP",IDC_FOP_POP,3,50,42,14
|
||||
PUSHBUTTON "PUSH",IDC_FOP_PUSH,3,33,42,14
|
||||
PUSHBUTTON "XCH",IDC_FOP_XCH,3,67,42,14
|
||||
PUSHBUTTON "+",IDC_FOP_ADD,3,84,42,14
|
||||
PUSHBUTTON "+/POP",IDC_FOP_ADDP,3,101,42,14
|
||||
PUSHBUTTON "*",IDC_FOP_MUL,3,118,42,14
|
||||
PUSHBUTTON "*/POP",IDC_FOP_MULP,3,135,42,14
|
||||
LTEXT "IN: a b c d -> OUT: a a b c d",IDC_STATIC,50,35,232,8
|
||||
LTEXT "IN: a b c d -> OUT: b c d",IDC_STATIC,50,52,196,8
|
||||
LTEXT "IN: a b c d -> OUT: b a c d",IDC_STATIC,50,69,214,8
|
||||
LTEXT "IN: a b c d -> OUT: a+b b c d",IDC_STATIC,50,86,216,8
|
||||
LTEXT "IN: a b c d -> OUT: a+b c d",IDC_STATIC,50,103,198,8
|
||||
LTEXT "IN: a b c d -> OUT: a*b b c d",IDC_STATIC,50,120,216,8
|
||||
LTEXT "IN: a b c d -> OUT: a*b c d",IDC_STATIC,50,137,198,8
|
||||
PUSHBUTTON "2+/POP",IDC_FOP_ADDP2,3,152,42,14
|
||||
LTEXT "IN: a b c d -> OUT: a+c b+d",IDC_STATIC,50,155,193,8
|
||||
GROUPBOX "",IDC_STATIC,0,27,299,22
|
||||
GROUPBOX "",IDC_STATIC,0,61,299,22
|
||||
GROUPBOX "",IDC_STATIC,0,95,299,22
|
||||
GROUPBOX "",IDC_STATIC,0,129,299,23
|
||||
GROUPBOX "",IDC_STATIC,0,147,299,21
|
||||
PUSHBUTTON "Load Note",IDC_FOP_LOADNOTE,3,16,42,14
|
||||
LTEXT "IN: a b c d -> OUT: note a b c d",IDC_STATIC,50,18,233,8
|
||||
GROUPBOX "",IDC_STATIC,0,10,299,22
|
||||
END
|
||||
|
||||
IDD_FST DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Store Signal",IDC_STATIC,0,0,299,170
|
||||
CONTROL "",IDC_FST_AMOUNT,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,36,101,200,15
|
||||
LTEXT "Amount",IDC_STATIC,3,104,26,8
|
||||
CTEXT " ",IDC_FST_AMOUNT_VAL,242,102,48,12,SS_SUNKEN
|
||||
COMBOBOX IDC_FST_DESTINATION_INSTRUMENT,43,53,249,177,CBS_DROPDOWN | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Stack",IDC_STATIC,5,55,18,8
|
||||
COMBOBOX IDC_FST_DESTINATION_UNIT,43,69,249,157,CBS_DROPDOWN | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Unit",IDC_STATIC,6,71,14,8
|
||||
COMBOBOX IDC_FST_DESTINATION_SLOT,43,85,249,110,CBS_DROPDOWN | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Slot",IDC_STATIC,5,87,13,8
|
||||
END
|
||||
|
||||
IDD_NONE DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "",-1,0,0,299,170
|
||||
LTEXT "Nothing selected",-1,123,80,54,8
|
||||
END
|
||||
|
||||
IDD_OUT DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Instrument Output",IDC_STATIC,0,0,299,170
|
||||
CONTROL "",IDC_OUT_GAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,37,70,200,15
|
||||
LTEXT "Gain",IDC_STATIC,6,73,15,8
|
||||
LTEXT "AUX Send",IDC_STATIC,6,89,32,8
|
||||
CONTROL "",IDC_OUT_AUXSEND,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,37,85,200,15
|
||||
CTEXT " ",IDC_OUT_GAIN_VAL,242,70,48,12,SS_SUNKEN
|
||||
CTEXT " ",IDC_OUT_AUXSEND_VAL,242,86,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_GLOBAL_STACK DIALOGEX 0, 0, 247, 320
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT1,15,0,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP1,165,0,25,10,NOT WS_VISIBLE
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN1,191,0,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT1,225,0,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT2,15,10,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP2,165,10,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN2,191,10,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT2,225,10,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT3,15,20,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP3,165,20,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN3,191,20,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT3,225,20,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT4,15,30,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP4,165,30,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN4,191,30,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT4,225,30,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT5,15,40,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP5,165,40,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN5,191,40,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT5,225,40,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT6,15,50,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP6,165,50,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN6,191,50,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT6,225,50,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT7,15,60,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP7,165,60,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN7,191,60,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT7,225,60,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT8,15,70,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP8,165,70,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN8,191,70,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT8,225,70,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT9,15,80,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP9,165,80,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN9,191,80,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT9,225,80,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT10,15,90,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP10,165,90,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN10,191,90,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT10,225,90,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT11,15,100,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP11,165,100,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN11,191,100,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT11,225,100,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT12,15,110,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP12,165,110,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN12,191,110,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT12,225,110,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT13,15,120,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP13,165,120,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN13,191,120,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT13,225,120,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT14,15,130,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP14,165,130,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN14,191,130,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT14,225,130,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT15,15,140,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP15,165,140,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN15,191,140,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT15,225,140,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT16,15,150,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP16,165,150,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN16,191,150,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT16,225,150,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT17,15,160,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP17,165,160,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN17,191,160,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT17,225,160,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT18,15,170,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP18,165,170,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN18,191,170,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT18,225,170,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT19,15,180,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP19,165,180,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN19,191,180,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT19,225,180,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT20,15,190,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP20,165,190,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN20,191,190,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT20,225,190,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT21,15,200,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP21,165,200,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN21,191,200,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT21,225,200,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT22,15,210,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP22,165,210,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN22,191,210,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT22,225,210,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT23,15,220,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP23,165,220,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN23,191,220,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT23,225,220,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT24,15,230,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP24,165,230,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN24,191,230,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT24,225,230,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT25,15,240,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP25,165,240,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN25,191,240,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT25,225,240,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT26,15,250,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP26,165,250,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN26,191,250,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT26,225,250,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT27,15,260,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP27,165,260,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN27,191,260,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT27,225,260,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT28,15,270,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP28,165,270,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN28,191,270,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT28,225,270,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT29,15,280,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP29,165,280,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN29,191,280,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT29,225,280,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT30,15,290,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP30,165,290,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN30,191,290,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT30,225,290,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT31,15,300,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP31,165,300,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN31,191,300,25,10
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT31,225,300,16,10,SS_SUNKEN
|
||||
PUSHBUTTON " ",IDC_GSTACK_UNIT32,15,310,83,10
|
||||
PUSHBUTTON "Up",IDC_GSTACK_UP32,165,310,25,10
|
||||
PUSHBUTTON "Down",IDC_GSTACK_DOWN32,191,310,25,10,NOT WS_VISIBLE
|
||||
CTEXT "1",IDC_GSTACK_SIGNALCOUNT32,225,310,16,10,SS_SUNKEN
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET1,106,0,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET1,132,0,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET2,106,10,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET2,132,10,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET3,106,20,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET3,132,20,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET4,106,30,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET4,132,30,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET5,106,40,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET5,132,40,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET6,106,50,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET6,132,50,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET7,106,60,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET7,132,60,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET8,106,70,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET8,132,70,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET9,106,80,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET9,132,80,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET10,106,90,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET10,132,90,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET11,106,100,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET11,132,100,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET12,106,110,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET12,132,110,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET13,106,120,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET13,132,120,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET14,106,130,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET14,132,130,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET15,106,140,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET15,132,140,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET16,106,150,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET16,132,150,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET17,106,160,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET17,132,160,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET18,106,170,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET18,132,170,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET19,106,180,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET19,132,180,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET20,106,190,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET20,132,190,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET21,106,200,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET21,132,200,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET22,106,210,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET22,132,210,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET23,106,220,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET23,132,220,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET24,106,230,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET24,132,230,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET25,106,240,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET25,132,240,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET26,106,250,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET26,132,250,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET27,106,260,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET27,132,260,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET28,106,270,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET28,132,270,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET29,106,280,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET29,132,280,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET30,106,290,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET30,132,290,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET31,106,300,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET31,132,300,25,10
|
||||
PUSHBUTTON "Set",IDC_GSTACK_SET32,106,310,25,10
|
||||
PUSHBUTTON "Clear",IDC_GSTACK_RESET32,132,310,25,10
|
||||
LTEXT "1:",IDC_STATIC,2,1,10,8
|
||||
LTEXT "2:",IDC_STATIC,2,11,10,8
|
||||
LTEXT "3:",IDC_STATIC,2,21,10,8
|
||||
LTEXT "4:",IDC_STATIC,2,31,10,8
|
||||
LTEXT "5:",IDC_STATIC,2,41,10,8
|
||||
LTEXT "6:",IDC_STATIC,2,51,10,8
|
||||
LTEXT "7:",IDC_STATIC,2,61,10,8
|
||||
LTEXT "8:",IDC_STATIC,2,71,10,8
|
||||
LTEXT "9:",IDC_STATIC,2,81,10,8
|
||||
LTEXT "10:",IDC_STATIC,2,91,10,8
|
||||
LTEXT "11:",IDC_STATIC,2,101,10,8
|
||||
LTEXT "12:",IDC_STATIC,2,111,10,8
|
||||
LTEXT "13:",IDC_STATIC,2,121,10,8
|
||||
LTEXT "14:",IDC_STATIC,2,131,10,8
|
||||
LTEXT "15:",IDC_STATIC,2,141,10,8
|
||||
LTEXT "16:",IDC_STATIC,2,151,10,8
|
||||
LTEXT "17:",IDC_STATIC,2,161,10,8
|
||||
LTEXT "18:",IDC_STATIC,2,171,10,8
|
||||
LTEXT "19:",IDC_STATIC,2,181,10,8
|
||||
LTEXT "20:",IDC_STATIC,2,191,10,8
|
||||
LTEXT "21:",IDC_STATIC,2,201,10,8
|
||||
LTEXT "22:",IDC_STATIC,2,211,10,8
|
||||
LTEXT "23:",IDC_STATIC,2,221,10,8
|
||||
LTEXT "24:",IDC_STATIC,2,231,10,8
|
||||
LTEXT "25:",IDC_STATIC,2,241,10,8
|
||||
LTEXT "26:",IDC_STATIC,2,251,10,8
|
||||
LTEXT "27:",IDC_STATIC,2,261,10,8
|
||||
LTEXT "28:",IDC_STATIC,2,271,10,8
|
||||
LTEXT "29:",IDC_STATIC,2,281,10,8
|
||||
LTEXT "30:",IDC_STATIC,2,291,10,8
|
||||
LTEXT "31:",IDC_STATIC,2,301,10,8
|
||||
LTEXT "32:",IDC_STATIC,2,311,10,8
|
||||
END
|
||||
|
||||
IDD_PAN DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Panning",-1,0,0,299,170
|
||||
CONTROL "",IDC_PAN_PANNING,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,77,200,15
|
||||
LTEXT "Panning",-1,6,80,26,8
|
||||
CTEXT " ",IDC_PAN_PANNING_VAL,242,77,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_SET_DIALOG DIALOGEX 0, 0, 186, 44
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Set"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,21,50,14
|
||||
COMBOBOX IDC_SET_UNIT,7,23,92,121,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Select Unit",IDC_STATIC,7,7,36,8
|
||||
END
|
||||
|
||||
IDD_ACC DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Accumulate Signals",-1,0,0,299,170
|
||||
PUSHBUTTON "Output",IDC_ACC_OUT,99,77,50,14,WS_DISABLED
|
||||
PUSHBUTTON "AUX",IDC_ACC_AUX,149,77,50,14
|
||||
END
|
||||
|
||||
IDD_FLD DIALOGEX 0, 0, 300, 170
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Load Signal",-1,0,0,299,170
|
||||
CONTROL "",IDC_FLD_VALUE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,38,77,200,15
|
||||
LTEXT "Value",-1,6,80,26,8
|
||||
CTEXT " ",IDC_FLD_VALUE_VAL,242,77,48,12,SS_SUNKEN
|
||||
END
|
||||
|
||||
IDD_SCROLLWINDOW DIALOGEX 0, 0, 263, 258
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_SYSMENU
|
||||
EXSTYLE WS_EX_CLIENTEDGE
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_GO4KVSTIDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 587
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 334
|
||||
END
|
||||
|
||||
IDD_SET_DIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 35
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog Info
|
||||
//
|
||||
|
||||
IDD_GO4KVSTIDIALOG DLGINIT
|
||||
BEGIN
|
||||
IDC_PATTERN_SIZE, 0x403, 12, 0
|
||||
0x6538, 0x2072, 0x6150, 0x7474, 0x7265, 0x006e,
|
||||
IDC_PATTERN_SIZE, 0x403, 13, 0
|
||||
0x3631, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
IDC_PATTERN_SIZE, 0x403, 13, 0
|
||||
0x3233, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
IDC_PATTERN_SIZE, 0x403, 13, 0
|
||||
0x3436, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
IDC_PATTERN_QUANT, 0x403, 12, 0
|
||||
0x6538, 0x2072, 0x6150, 0x7474, 0x7265, 0x006e,
|
||||
IDC_PATTERN_QUANT, 0x403, 13, 0
|
||||
0x3631, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
IDC_PATTERN_QUANT, 0x403, 13, 0
|
||||
0x3233, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
IDC_PATTERN_QUANT, 0x403, 13, 0
|
||||
0x3436, 0x7265, 0x5020, 0x7461, 0x6574, 0x6e72, "\000"
|
||||
0
|
||||
END
|
||||
|
||||
#endif // German (Germany) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4klang", "Go4kVSTi.vcproj", "{107757EA-2FE1-4C5E-964F-DE7E482E253F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{107757EA-2FE1-4C5E-964F-DE7E482E253F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{107757EA-2FE1-4C5E-964F-DE7E482E253F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{107757EA-2FE1-4C5E-964F-DE7E482E253F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{107757EA-2FE1-4C5E-964F-DE7E482E253F}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@ -1,361 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="4klang"
|
||||
ProjectGUID="{107757EA-2FE1-4C5E-964F-DE7E482E253F}"
|
||||
RootNamespace="Go4kVSTi"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/vstxsynth.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UseUnicodeResponseFiles="false"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\source\common"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;WINDOWS=1;_CRT_SECURE_NO_DEPRECATE"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
StructMemberAlignment="1"
|
||||
BufferSecurityCheck="true"
|
||||
FloatingPointModel="2"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Debug/Go4kVSTi.pch"
|
||||
AssemblerOutput="0"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName).dll"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
ModuleDefinitionFile=".\Go4kVSTi.def"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/Go4kVSTi.pdb"
|
||||
SubSystem="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary=".\Debug/Go4kVSTi.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/vstxsynth.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UseUnicodeResponseFiles="false"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\source\common"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINDOWS=1;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="true"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="1"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="2"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Release/Go4kVSTi.pch"
|
||||
AssemblerOutput="0"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="0"
|
||||
CallingConvention="0"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName).dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile=".\Go4kVSTi.def"
|
||||
ProgramDatabaseFile=".\Release/Go4kVSTi.pdb"
|
||||
SubSystem="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary=".\Release/Go4kVSTi.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\source\common\AudioEffect.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\common\audioeffectx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTi.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Go4kVSTi.rc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTiCore.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
CallingConvention="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTiGUI.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
CallingConvention="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTimain.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTiproc.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\source\common\AEffect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\common\aeffectx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\common\AEffEditor.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\common\AudioEffect.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\common\audioeffectx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTi.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTiCore.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\GoSynth\Go4kVSTiGUI.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="resource.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\4klang.asm"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="d:\code\nasm\nasmw -fwin32 -o"$(IntDir)\4klang.obj" 4klang.asm
"
|
||||
Outputs="$(IntDir)\4klang.obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="d:\code\nasm\nasmw -fwin32 -o"$(IntDir)\4klang.obj" 4klang.asm
"
|
||||
Outputs="$(IntDir)\4klang.obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\4klang.bin"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\4klang.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\nasmw.bin"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
SimpleCrypt.exe 4klang.asm 4klang.bin
|
||||
SimpleCrypt.exe nasmw.exe nasmw.bin
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,594 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Go4kVSTi.rc
|
||||
//
|
||||
#define IDD_NONE 100
|
||||
#define IDD_ENV 101
|
||||
#define IDD_VCO 102
|
||||
#define IDD_VCF 103
|
||||
#define IDD_DST 104
|
||||
#define IDD_DLL 105
|
||||
#define IDD_FOP 106
|
||||
#define IDD_FST 107
|
||||
#define IDD_PAN 108
|
||||
#define IDD_OUT 109
|
||||
#define IDD_ACC 110
|
||||
#define IDD_FLD 111
|
||||
#define IDD_GO4KVSTIDIALOG 115
|
||||
#define IDD_INSTRUMENT_STACK 120
|
||||
#define IDD_GLOBAL_STACK 121
|
||||
#define IDD_SET_DIALOG 122
|
||||
#define IDD_SCROLLWINDOW 123
|
||||
#define IDR_COMP_RES 130
|
||||
#define IDR_ASM_RES 131
|
||||
#define IDC_SET_UNIT 1000
|
||||
#define IDC_MAINTAB 1001
|
||||
#define IDC_LOAD_PATCH 1002
|
||||
#define IDC_SAVE_PATCH 1003
|
||||
#define IDC_RESET_PATCH 1004
|
||||
#define IDC_LOAD_INSTRUMENT 1005
|
||||
#define IDC_SAVE_INSTRUMENT 1006
|
||||
#define IDC_RESET_INSTRUMENT 1007
|
||||
#define IDC_INSTRUMENT_NAME 1008
|
||||
#define IDC_INSTRUMENT 1009
|
||||
#define IDC_SOLO 1010
|
||||
#define IDC_RECORD_BUTTON 1011
|
||||
#define IDC_STOP_BUTTON 1012
|
||||
#define IDC_PATTERN_SIZE 1013
|
||||
#define IDC_PANIC 1014
|
||||
#define IDC_MODULE_SETTINGS 1015
|
||||
#define IDC_POLYPHONY 1016
|
||||
#define IDC_ENVLEVELS 1017
|
||||
#define IDC_NOTEVALUES 1018
|
||||
#define IDC_OBJFORMAT 1019
|
||||
#define IDC_VOICECOUNT1 1020
|
||||
#define IDC_VOICECOUNT2 1021
|
||||
#define IDC_VOICECOUNT3 1022
|
||||
#define IDC_VOICECOUNT4 1023
|
||||
#define IDC_VOICECOUNT5 1024
|
||||
#define IDC_VOICECOUNT6 1025
|
||||
#define IDC_VOICECOUNT7 1026
|
||||
#define IDC_VOICECOUNT8 1027
|
||||
#define IDC_VOICECOUNT9 1028
|
||||
#define IDC_VOICECOUNT10 1029
|
||||
#define IDC_VOICECOUNT11 1030
|
||||
#define IDC_VOICECOUNT12 1031
|
||||
#define IDC_VOICECOUNT13 1032
|
||||
#define IDC_VOICECOUNT14 1033
|
||||
#define IDC_VOICECOUNT15 1034
|
||||
#define IDC_VOICECOUNT16 1035
|
||||
#define IDC_UNDENORMALIZE 1036
|
||||
#define IDC_CLIPOUTPUT 1037
|
||||
#define IDC_16BIT 1038
|
||||
#define IDC_ALWAYSONTOP 1039
|
||||
#define IDC_ISTACK_VALID 1040
|
||||
#define IDC_GSTACK_VALID 1041
|
||||
#define IDC_PATTERN_QUANT 1042
|
||||
#define IDC_UNIT_RESET 1050
|
||||
#define IDC_UNIT_COPY 1051
|
||||
#define IDC_UNIT_PASTE 1052
|
||||
#define IDC_UNIT_LOAD 1053
|
||||
#define IDC_UNIT_SAVE 1054
|
||||
#define IDC_ENV_ATTACK 1100
|
||||
#define IDC_ENV_ATTACK_VAL 1101
|
||||
#define IDC_ENV_ATTACK_QUANT 1102
|
||||
#define IDC_ENV_DECAY 1103
|
||||
#define IDC_ENV_DECAY_VAL 1104
|
||||
#define IDC_ENV_DECAY_QUANT 1105
|
||||
#define IDC_ENV_SUSTAIN 1106
|
||||
#define IDC_ENV_SUSTAIN_VAL 1107
|
||||
#define IDC_ENV_SUSTAIN_QUANT 1108
|
||||
#define IDC_ENV_RELEASE_VAL 1110
|
||||
#define IDC_ENV_RELEASE_QUANT 1111
|
||||
#define IDC_ENV_GAIN 1112
|
||||
#define IDC_ENV_GAIN_VAL 1113
|
||||
#define IDC_ENV_GAIN_QUANT 1114
|
||||
#define IDC_ENV_RELEASE 1119
|
||||
#define IDC_VCO_SINE 1150
|
||||
#define IDC_VCO_TRISAW 1151
|
||||
#define IDC_VCO_PULSE 1152
|
||||
#define IDC_VCO_NOISE 1153
|
||||
#define IDC_VCO_GATE 1154
|
||||
#define IDC_VCO_TRANSPOSE 1160
|
||||
#define IDC_VCO_TRANSPOSE_VAL 1161
|
||||
#define IDC_VCO_TRANSPOSE_QUANT 1162
|
||||
#define IDC_VCO_DETUNE 1163
|
||||
#define IDC_VCO_DETUNE_VAL 1164
|
||||
#define IDC_VCO_DETUNE_QUANT 1165
|
||||
#define IDC_VCO_PHASE 1166
|
||||
#define IDC_VCO_PHASE_VAL 1167
|
||||
#define IDC_VCO_PHASE_QUANT 1168
|
||||
#define IDC_VCO_COLOR 1169
|
||||
#define IDC_VCO_COLOR_VAL 1170
|
||||
#define IDC_VCO_COLOR_QUANT 1171
|
||||
#define IDC_VCO_SHAPE 1172
|
||||
#define IDC_VCO_SHAPE_VAL 1173
|
||||
#define IDC_VCO_GAIN_VAL 1174
|
||||
#define IDC_VCO_GAIN_QUANT 1175
|
||||
#define IDC_VCO_LFO 1176
|
||||
#define IDC_VCO_SHAPE_QUANT 1177
|
||||
#define IDC_VCO_GAIN 1178
|
||||
#define IDC_VCO_GATE1 1180
|
||||
#define IDC_VCO_GATE2 1181
|
||||
#define IDC_VCO_GATE3 1182
|
||||
#define IDC_VCO_GATE4 1183
|
||||
#define IDC_VCO_GATE5 1184
|
||||
#define IDC_VCO_GATE6 1185
|
||||
#define IDC_VCO_GATE7 1186
|
||||
#define IDC_VCO_GATE8 1187
|
||||
#define IDC_VCO_GATE9 1188
|
||||
#define IDC_VCO_GATE10 1189
|
||||
#define IDC_VCO_GATE11 1190
|
||||
#define IDC_VCO_GATE12 1191
|
||||
#define IDC_VCO_GATE13 1192
|
||||
#define IDC_VCO_GATE14 1193
|
||||
#define IDC_VCO_GATE15 1194
|
||||
#define IDC_VCO_GATE16 1195
|
||||
#define IDC_VCF_OFF 1200
|
||||
#define IDC_VCF_LOW 1201
|
||||
#define IDC_VCF_HIGH 1202
|
||||
#define IDC_VCF_BAND 1203
|
||||
#define IDC_VCF_NOTCH 1204
|
||||
#define IDC_VCF_PEAK 1205
|
||||
#define IDC_VCF_ALL 1206
|
||||
#define IDC_VCF_FREQUENCY 1207
|
||||
#define IDC_VCF_FREQUENCY_VAL 1208
|
||||
#define IDC_VCF_FREQUENCY_QUANT 1209
|
||||
#define IDC_VCF_RESONANCE 1210
|
||||
#define IDC_VCF_RESONANCE_VAL 1211
|
||||
#define IDC_VCF_RESONANCE_QUANT 1212
|
||||
#define IDC_DST_DRIVE 1250
|
||||
#define IDC_DST_DRIVE_VAL 1251
|
||||
#define IDC_DST_DRIVE_QUANT 1252
|
||||
#define IDC_DST_SNH 1253
|
||||
#define IDC_DST_SNH_VAL 1254
|
||||
#define IDC_DST_SNH_QUANT 1255
|
||||
#define IDC_DLL_OFF 1300
|
||||
#define IDC_DLL_DELAY 1301
|
||||
#define IDC_DLL_REVERB 1302
|
||||
#define IDC_DLL_PREGAIN 1303
|
||||
#define IDC_DLL_PREGAIN_VAL 1304
|
||||
#define IDC_DLL_PREGAIN_QUANT 1305
|
||||
#define IDC_DLL_FEEDBACK 1306
|
||||
#define IDC_DLL_FEEDBACK_VAL 1307
|
||||
#define IDC_DLL_FEEDBACK_QUANT 1308
|
||||
#define IDC_DLL_DRY 1309
|
||||
#define IDC_DLL_DRY_VAL 1310
|
||||
#define IDC_DLL_DRY_QUANT 1311
|
||||
#define IDC_DLL_DAMP 1312
|
||||
#define IDC_DLL_DAMP_VAL 1313
|
||||
#define IDC_DLL_DAMP_QUANT 1314
|
||||
#define IDC_DLL_DTIME 1315
|
||||
#define IDC_DLL_DTIME_VAL 1316
|
||||
#define IDC_DLL_NOSYNC 1317
|
||||
#define IDC_DLL_BPMSYNC 1318
|
||||
#define IDC_DLL_NOTESYNC 1319
|
||||
#define IDC_DLL_LEFTREVERB 1320
|
||||
#define IDC_DLL_FREQUENCY 1321
|
||||
#define IDC_DLL_FREQUENCY_VAL 1322
|
||||
#define IDC_DLL_DEPTH 1323
|
||||
#define IDC_DLL_DEPTH_VAL 1324
|
||||
#define IDC_FOP_POP 1351
|
||||
#define IDC_FOP_ADDP 1352
|
||||
#define IDC_FOP_MULP 1353
|
||||
#define IDC_FOP_PUSH 1354
|
||||
#define IDC_FOP_XCH 1355
|
||||
#define IDC_FOP_ADD 1356
|
||||
#define IDC_FOP_MUL 1357
|
||||
#define IDC_FOP_ADDP2 1358
|
||||
#define IDC_FOP_LOADNOTE 1359
|
||||
#define IDC_FST_AMOUNT 1400
|
||||
#define IDC_FST_AMOUNT_VAL 1401
|
||||
#define IDC_FST_AMOUNT_QUANT 1402
|
||||
#define IDC_FST_DESTINATION_INSTRUMENT 1403
|
||||
#define IDC_FST_DESTINATION_UNIT 1404
|
||||
#define IDC_FST_DESTINATION_SLOT 1405
|
||||
#define IDC_PAN_PANNING 1450
|
||||
#define IDC_PAN_PANNING_VAL 1451
|
||||
#define IDC_PAN_PANNING_QUANT 1452
|
||||
#define IDC_OUT_GAIN 1500
|
||||
#define IDC_OUT_GAIN_VAL 1501
|
||||
#define IDC_OUT_GAIN_QUANT 1502
|
||||
#define IDC_OUT_AUXSEND 1503
|
||||
#define IDC_OUT_AUXSEND_QUANT 1504
|
||||
#define IDC_OUT_AUXSEND_VAL 1505
|
||||
#define IDC_ACC_OUT 1550
|
||||
#define IDC_ACC_AUX 1551
|
||||
#define IDC_FLD_VALUE 1552
|
||||
#define IDC_FLD_VALUE_VAL 1553
|
||||
#define IDC_FLD_VALUE_QUANT 1554
|
||||
#define IDC_ISTACK_UNIT1 1600
|
||||
#define IDC_ISTACK_UP1 1601
|
||||
#define IDC_ISTACK_DOWN1 1602
|
||||
#define IDC_ISTACK_SIGNALCOUNT1 1603
|
||||
#define IDC_ISTACK_SET1 1604
|
||||
#define IDC_ISTACK_RESET1 1605
|
||||
#define IDC_ISTACK_UNIT2 1606
|
||||
#define IDC_ISTACK_UP2 1607
|
||||
#define IDC_ISTACK_DOWN2 1608
|
||||
#define IDC_ISTACK_SIGNALCOUNT2 1609
|
||||
#define IDC_ISTACK_SET2 1610
|
||||
#define IDC_ISTACK_RESET2 1611
|
||||
#define IDC_ISTACK_UNIT3 1612
|
||||
#define IDC_ISTACK_UP3 1613
|
||||
#define IDC_ISTACK_DOWN3 1614
|
||||
#define IDC_ISTACK_SIGNALCOUNT3 1615
|
||||
#define IDC_ISTACK_SET3 1616
|
||||
#define IDC_ISTACK_RESET3 1617
|
||||
#define IDC_ISTACK_UNIT4 1618
|
||||
#define IDC_ISTACK_UP4 1619
|
||||
#define IDC_ISTACK_DOWN4 1620
|
||||
#define IDC_ISTACK_SIGNALCOUNT4 1621
|
||||
#define IDC_ISTACK_SET4 1622
|
||||
#define IDC_ISTACK_RESET4 1623
|
||||
#define IDC_ISTACK_UNIT5 1624
|
||||
#define IDC_ISTACK_UP5 1625
|
||||
#define IDC_ISTACK_DOWN5 1626
|
||||
#define IDC_ISTACK_SIGNALCOUNT5 1627
|
||||
#define IDC_ISTACK_SET5 1628
|
||||
#define IDC_ISTACK_RESET5 1629
|
||||
#define IDC_ISTACK_UNIT6 1630
|
||||
#define IDC_ISTACK_UP6 1631
|
||||
#define IDC_ISTACK_DOWN6 1632
|
||||
#define IDC_ISTACK_SIGNALCOUNT6 1633
|
||||
#define IDC_ISTACK_SET6 1634
|
||||
#define IDC_ISTACK_RESET6 1635
|
||||
#define IDC_ISTACK_UNIT7 1636
|
||||
#define IDC_ISTACK_UP7 1637
|
||||
#define IDC_ISTACK_DOWN7 1638
|
||||
#define IDC_ISTACK_SIGNALCOUNT7 1639
|
||||
#define IDC_ISTACK_SET7 1640
|
||||
#define IDC_ISTACK_RESET7 1641
|
||||
#define IDC_ISTACK_UNIT8 1642
|
||||
#define IDC_ISTACK_UP8 1643
|
||||
#define IDC_ISTACK_DOWN8 1644
|
||||
#define IDC_ISTACK_SIGNALCOUNT8 1645
|
||||
#define IDC_ISTACK_SET8 1646
|
||||
#define IDC_ISTACK_RESET8 1647
|
||||
#define IDC_ISTACK_UNIT9 1648
|
||||
#define IDC_ISTACK_UP9 1649
|
||||
#define IDC_ISTACK_DOWN9 1650
|
||||
#define IDC_ISTACK_SIGNALCOUNT9 1651
|
||||
#define IDC_ISTACK_SET9 1652
|
||||
#define IDC_ISTACK_RESET9 1653
|
||||
#define IDC_ISTACK_UNIT10 1654
|
||||
#define IDC_ISTACK_UP10 1655
|
||||
#define IDC_ISTACK_DOWN10 1656
|
||||
#define IDC_ISTACK_SIGNALCOUNT10 1657
|
||||
#define IDC_ISTACK_SET10 1658
|
||||
#define IDC_ISTACK_RESET10 1659
|
||||
#define IDC_ISTACK_UNIT11 1660
|
||||
#define IDC_ISTACK_UP11 1661
|
||||
#define IDC_ISTACK_DOWN11 1662
|
||||
#define IDC_ISTACK_SIGNALCOUNT11 1663
|
||||
#define IDC_ISTACK_SET11 1664
|
||||
#define IDC_ISTACK_RESET11 1665
|
||||
#define IDC_ISTACK_UNIT12 1666
|
||||
#define IDC_ISTACK_UP12 1667
|
||||
#define IDC_ISTACK_DOWN12 1668
|
||||
#define IDC_ISTACK_SIGNALCOUNT12 1669
|
||||
#define IDC_ISTACK_SET12 1670
|
||||
#define IDC_ISTACK_RESET12 1671
|
||||
#define IDC_ISTACK_UNIT13 1672
|
||||
#define IDC_ISTACK_UP13 1673
|
||||
#define IDC_ISTACK_DOWN13 1674
|
||||
#define IDC_ISTACK_SIGNALCOUNT13 1675
|
||||
#define IDC_ISTACK_SET13 1676
|
||||
#define IDC_ISTACK_RESET13 1677
|
||||
#define IDC_ISTACK_UNIT14 1678
|
||||
#define IDC_ISTACK_UP14 1679
|
||||
#define IDC_ISTACK_DOWN14 1680
|
||||
#define IDC_ISTACK_SIGNALCOUNT14 1681
|
||||
#define IDC_ISTACK_SET14 1682
|
||||
#define IDC_ISTACK_RESET14 1683
|
||||
#define IDC_ISTACK_UNIT15 1684
|
||||
#define IDC_ISTACK_UP15 1685
|
||||
#define IDC_ISTACK_DOWN15 1686
|
||||
#define IDC_ISTACK_SIGNALCOUNT15 1687
|
||||
#define IDC_ISTACK_SET15 1688
|
||||
#define IDC_ISTACK_RESET15 1689
|
||||
#define IDC_ISTACK_UNIT16 1690
|
||||
#define IDC_ISTACK_UP16 1691
|
||||
#define IDC_ISTACK_DOWN16 1692
|
||||
#define IDC_ISTACK_SIGNALCOUNT16 1693
|
||||
#define IDC_ISTACK_SET16 1694
|
||||
#define IDC_ISTACK_RESET16 1695
|
||||
#define IDC_ISTACK_UNIT17 1696
|
||||
#define IDC_ISTACK_UP17 1697
|
||||
#define IDC_ISTACK_DOWN17 1698
|
||||
#define IDC_ISTACK_SIGNALCOUNT17 1699
|
||||
#define IDC_ISTACK_SET17 1700
|
||||
#define IDC_ISTACK_RESET17 1701
|
||||
#define IDC_ISTACK_UNIT18 1702
|
||||
#define IDC_ISTACK_UP18 1703
|
||||
#define IDC_ISTACK_DOWN18 1704
|
||||
#define IDC_ISTACK_SIGNALCOUNT18 1705
|
||||
#define IDC_ISTACK_SET18 1706
|
||||
#define IDC_ISTACK_RESET18 1707
|
||||
#define IDC_ISTACK_UNIT19 1708
|
||||
#define IDC_ISTACK_UP19 1709
|
||||
#define IDC_ISTACK_DOWN19 1710
|
||||
#define IDC_ISTACK_SIGNALCOUNT19 1711
|
||||
#define IDC_ISTACK_SET19 1712
|
||||
#define IDC_ISTACK_RESET19 1713
|
||||
#define IDC_ISTACK_UNIT20 1714
|
||||
#define IDC_ISTACK_UP20 1715
|
||||
#define IDC_ISTACK_DOWN20 1716
|
||||
#define IDC_ISTACK_SIGNALCOUNT20 1717
|
||||
#define IDC_ISTACK_SET20 1718
|
||||
#define IDC_ISTACK_RESET20 1719
|
||||
#define IDC_ISTACK_UNIT21 1720
|
||||
#define IDC_ISTACK_UP21 1721
|
||||
#define IDC_ISTACK_DOWN21 1722
|
||||
#define IDC_ISTACK_SIGNALCOUNT21 1723
|
||||
#define IDC_ISTACK_SET21 1724
|
||||
#define IDC_ISTACK_RESET21 1725
|
||||
#define IDC_ISTACK_UNIT22 1726
|
||||
#define IDC_ISTACK_UP22 1727
|
||||
#define IDC_ISTACK_DOWN22 1728
|
||||
#define IDC_ISTACK_SIGNALCOUNT22 1729
|
||||
#define IDC_ISTACK_SET22 1730
|
||||
#define IDC_ISTACK_RESET22 1731
|
||||
#define IDC_ISTACK_UNIT23 1732
|
||||
#define IDC_ISTACK_UP23 1733
|
||||
#define IDC_ISTACK_DOWN23 1734
|
||||
#define IDC_ISTACK_SIGNALCOUNT23 1735
|
||||
#define IDC_ISTACK_SET23 1736
|
||||
#define IDC_ISTACK_RESET23 1737
|
||||
#define IDC_ISTACK_UNIT24 1738
|
||||
#define IDC_ISTACK_UP24 1739
|
||||
#define IDC_ISTACK_DOWN24 1740
|
||||
#define IDC_ISTACK_SIGNALCOUNT24 1741
|
||||
#define IDC_ISTACK_SET24 1742
|
||||
#define IDC_ISTACK_RESET24 1743
|
||||
#define IDC_ISTACK_UNIT25 1744
|
||||
#define IDC_ISTACK_UP25 1745
|
||||
#define IDC_ISTACK_DOWN25 1746
|
||||
#define IDC_ISTACK_SIGNALCOUNT25 1747
|
||||
#define IDC_ISTACK_SET25 1748
|
||||
#define IDC_ISTACK_RESET25 1749
|
||||
#define IDC_ISTACK_UNIT26 1750
|
||||
#define IDC_ISTACK_UP26 1751
|
||||
#define IDC_ISTACK_DOWN26 1752
|
||||
#define IDC_ISTACK_SIGNALCOUNT26 1753
|
||||
#define IDC_ISTACK_SET26 1754
|
||||
#define IDC_ISTACK_RESET26 1755
|
||||
#define IDC_ISTACK_UNIT27 1756
|
||||
#define IDC_ISTACK_UP27 1757
|
||||
#define IDC_ISTACK_DOWN27 1758
|
||||
#define IDC_ISTACK_SIGNALCOUNT27 1759
|
||||
#define IDC_ISTACK_SET27 1760
|
||||
#define IDC_ISTACK_RESET27 1761
|
||||
#define IDC_ISTACK_UNIT28 1762
|
||||
#define IDC_ISTACK_UP28 1763
|
||||
#define IDC_ISTACK_DOWN28 1764
|
||||
#define IDC_ISTACK_SIGNALCOUNT28 1765
|
||||
#define IDC_ISTACK_SET28 1766
|
||||
#define IDC_ISTACK_RESET28 1767
|
||||
#define IDC_ISTACK_UNIT29 1768
|
||||
#define IDC_ISTACK_UP29 1769
|
||||
#define IDC_ISTACK_DOWN29 1770
|
||||
#define IDC_ISTACK_SIGNALCOUNT29 1771
|
||||
#define IDC_ISTACK_SET29 1772
|
||||
#define IDC_ISTACK_RESET29 1773
|
||||
#define IDC_ISTACK_UNIT30 1774
|
||||
#define IDC_ISTACK_UP30 1775
|
||||
#define IDC_ISTACK_DOWN30 1776
|
||||
#define IDC_ISTACK_SIGNALCOUNT30 1777
|
||||
#define IDC_ISTACK_SET30 1778
|
||||
#define IDC_ISTACK_RESET30 1779
|
||||
#define IDC_ISTACK_UNIT31 1780
|
||||
#define IDC_ISTACK_UP31 1781
|
||||
#define IDC_ISTACK_DOWN31 1782
|
||||
#define IDC_ISTACK_SIGNALCOUNT31 1783
|
||||
#define IDC_ISTACK_SET31 1784
|
||||
#define IDC_ISTACK_RESET31 1785
|
||||
#define IDC_ISTACK_UNIT32 1786
|
||||
#define IDC_ISTACK_UP32 1787
|
||||
#define IDC_ISTACK_DOWN32 1788
|
||||
#define IDC_ISTACK_SIGNALCOUNT32 1789
|
||||
#define IDC_ISTACK_SET32 1790
|
||||
#define IDC_ISTACK_RESET32 1791
|
||||
#define IDC_GSTACK_UNIT1 3600
|
||||
#define IDC_GSTACK_UP1 3601
|
||||
#define IDC_GSTACK_DOWN1 3602
|
||||
#define IDC_GSTACK_SIGNALCOUNT1 3603
|
||||
#define IDC_GSTACK_SET1 3604
|
||||
#define IDC_GSTACK_RESET1 3605
|
||||
#define IDC_GSTACK_UNIT2 3606
|
||||
#define IDC_GSTACK_UP2 3607
|
||||
#define IDC_GSTACK_DOWN2 3608
|
||||
#define IDC_GSTACK_SIGNALCOUNT2 3609
|
||||
#define IDC_GSTACK_SET2 3610
|
||||
#define IDC_GSTACK_RESET2 3611
|
||||
#define IDC_GSTACK_UNIT3 3612
|
||||
#define IDC_GSTACK_UP3 3613
|
||||
#define IDC_GSTACK_DOWN3 3614
|
||||
#define IDC_GSTACK_SIGNALCOUNT3 3615
|
||||
#define IDC_GSTACK_SET3 3616
|
||||
#define IDC_GSTACK_RESET3 3617
|
||||
#define IDC_GSTACK_UNIT4 3618
|
||||
#define IDC_GSTACK_UP4 3619
|
||||
#define IDC_GSTACK_DOWN4 3620
|
||||
#define IDC_GSTACK_SIGNALCOUNT4 3621
|
||||
#define IDC_GSTACK_SET4 3622
|
||||
#define IDC_GSTACK_RESET4 3623
|
||||
#define IDC_GSTACK_UNIT5 3624
|
||||
#define IDC_GSTACK_UP5 3625
|
||||
#define IDC_GSTACK_DOWN5 3626
|
||||
#define IDC_GSTACK_SIGNALCOUNT5 3627
|
||||
#define IDC_GSTACK_SET5 3628
|
||||
#define IDC_GSTACK_RESET5 3629
|
||||
#define IDC_GSTACK_UNIT6 3630
|
||||
#define IDC_GSTACK_UP6 3631
|
||||
#define IDC_GSTACK_DOWN6 3632
|
||||
#define IDC_GSTACK_SIGNALCOUNT6 3633
|
||||
#define IDC_GSTACK_SET6 3634
|
||||
#define IDC_GSTACK_RESET6 3635
|
||||
#define IDC_GSTACK_UNIT7 3636
|
||||
#define IDC_GSTACK_UP7 3637
|
||||
#define IDC_GSTACK_DOWN7 3638
|
||||
#define IDC_GSTACK_SIGNALCOUNT7 3639
|
||||
#define IDC_GSTACK_SET7 3640
|
||||
#define IDC_GSTACK_RESET7 3641
|
||||
#define IDC_GSTACK_UNIT8 3642
|
||||
#define IDC_GSTACK_UP8 3643
|
||||
#define IDC_GSTACK_DOWN8 3644
|
||||
#define IDC_GSTACK_SIGNALCOUNT8 3645
|
||||
#define IDC_GSTACK_SET8 3646
|
||||
#define IDC_GSTACK_RESET8 3647
|
||||
#define IDC_GSTACK_UNIT9 3648
|
||||
#define IDC_GSTACK_UP9 3649
|
||||
#define IDC_GSTACK_DOWN9 3650
|
||||
#define IDC_GSTACK_SIGNALCOUNT9 3651
|
||||
#define IDC_GSTACK_SET9 3652
|
||||
#define IDC_GSTACK_RESET9 3653
|
||||
#define IDC_GSTACK_UNIT10 3654
|
||||
#define IDC_GSTACK_UP10 3655
|
||||
#define IDC_GSTACK_DOWN10 3656
|
||||
#define IDC_GSTACK_SIGNALCOUNT10 3657
|
||||
#define IDC_GSTACK_SET10 3658
|
||||
#define IDC_GSTACK_RESET10 3659
|
||||
#define IDC_GSTACK_UNIT11 3660
|
||||
#define IDC_GSTACK_UP11 3661
|
||||
#define IDC_GSTACK_DOWN11 3662
|
||||
#define IDC_GSTACK_SIGNALCOUNT11 3663
|
||||
#define IDC_GSTACK_SET11 3664
|
||||
#define IDC_GSTACK_RESET11 3665
|
||||
#define IDC_GSTACK_UNIT12 3666
|
||||
#define IDC_GSTACK_UP12 3667
|
||||
#define IDC_GSTACK_DOWN12 3668
|
||||
#define IDC_GSTACK_SIGNALCOUNT12 3669
|
||||
#define IDC_GSTACK_SET12 3670
|
||||
#define IDC_GSTACK_RESET12 3671
|
||||
#define IDC_GSTACK_UNIT13 3672
|
||||
#define IDC_GSTACK_UP13 3673
|
||||
#define IDC_GSTACK_DOWN13 3674
|
||||
#define IDC_GSTACK_SIGNALCOUNT13 3675
|
||||
#define IDC_GSTACK_SET13 3676
|
||||
#define IDC_GSTACK_RESET13 3677
|
||||
#define IDC_GSTACK_UNIT14 3678
|
||||
#define IDC_GSTACK_UP14 3679
|
||||
#define IDC_GSTACK_DOWN14 3680
|
||||
#define IDC_GSTACK_SIGNALCOUNT14 3681
|
||||
#define IDC_GSTACK_SET14 3682
|
||||
#define IDC_GSTACK_RESET14 3683
|
||||
#define IDC_GSTACK_UNIT15 3684
|
||||
#define IDC_GSTACK_UP15 3685
|
||||
#define IDC_GSTACK_DOWN15 3686
|
||||
#define IDC_GSTACK_SIGNALCOUNT15 3687
|
||||
#define IDC_GSTACK_SET15 3688
|
||||
#define IDC_GSTACK_RESET15 3689
|
||||
#define IDC_GSTACK_UNIT16 3690
|
||||
#define IDC_GSTACK_UP16 3691
|
||||
#define IDC_GSTACK_DOWN16 3692
|
||||
#define IDC_GSTACK_SIGNALCOUNT16 3693
|
||||
#define IDC_GSTACK_SET16 3694
|
||||
#define IDC_GSTACK_RESET16 3695
|
||||
#define IDC_GSTACK_UNIT17 3696
|
||||
#define IDC_GSTACK_UP17 3697
|
||||
#define IDC_GSTACK_DOWN17 3698
|
||||
#define IDC_GSTACK_SIGNALCOUNT17 3699
|
||||
#define IDC_GSTACK_SET17 3700
|
||||
#define IDC_GSTACK_RESET17 3701
|
||||
#define IDC_GSTACK_UNIT18 3702
|
||||
#define IDC_GSTACK_UP18 3703
|
||||
#define IDC_GSTACK_DOWN18 3704
|
||||
#define IDC_GSTACK_SIGNALCOUNT18 3705
|
||||
#define IDC_GSTACK_SET18 3706
|
||||
#define IDC_GSTACK_RESET18 3707
|
||||
#define IDC_GSTACK_UNIT19 3708
|
||||
#define IDC_GSTACK_UP19 3709
|
||||
#define IDC_GSTACK_DOWN19 3710
|
||||
#define IDC_GSTACK_SIGNALCOUNT19 3711
|
||||
#define IDC_GSTACK_SET19 3712
|
||||
#define IDC_GSTACK_RESET19 3713
|
||||
#define IDC_GSTACK_UNIT20 3714
|
||||
#define IDC_GSTACK_UP20 3715
|
||||
#define IDC_GSTACK_DOWN20 3716
|
||||
#define IDC_GSTACK_SIGNALCOUNT20 3717
|
||||
#define IDC_GSTACK_SET20 3718
|
||||
#define IDC_GSTACK_RESET20 3719
|
||||
#define IDC_GSTACK_UNIT21 3720
|
||||
#define IDC_GSTACK_UP21 3721
|
||||
#define IDC_GSTACK_DOWN21 3722
|
||||
#define IDC_GSTACK_SIGNALCOUNT21 3723
|
||||
#define IDC_GSTACK_SET21 3724
|
||||
#define IDC_GSTACK_RESET21 3725
|
||||
#define IDC_GSTACK_UNIT22 3726
|
||||
#define IDC_GSTACK_UP22 3727
|
||||
#define IDC_GSTACK_DOWN22 3728
|
||||
#define IDC_GSTACK_SIGNALCOUNT22 3729
|
||||
#define IDC_GSTACK_SET22 3730
|
||||
#define IDC_GSTACK_RESET22 3731
|
||||
#define IDC_GSTACK_UNIT23 3732
|
||||
#define IDC_GSTACK_UP23 3733
|
||||
#define IDC_GSTACK_DOWN23 3734
|
||||
#define IDC_GSTACK_SIGNALCOUNT23 3735
|
||||
#define IDC_GSTACK_SET23 3736
|
||||
#define IDC_GSTACK_RESET23 3737
|
||||
#define IDC_GSTACK_UNIT24 3738
|
||||
#define IDC_GSTACK_UP24 3739
|
||||
#define IDC_GSTACK_DOWN24 3740
|
||||
#define IDC_GSTACK_SIGNALCOUNT24 3741
|
||||
#define IDC_GSTACK_SET24 3742
|
||||
#define IDC_GSTACK_RESET24 3743
|
||||
#define IDC_GSTACK_UNIT25 3744
|
||||
#define IDC_GSTACK_UP25 3745
|
||||
#define IDC_GSTACK_DOWN25 3746
|
||||
#define IDC_GSTACK_SIGNALCOUNT25 3747
|
||||
#define IDC_GSTACK_SET25 3748
|
||||
#define IDC_GSTACK_RESET25 3749
|
||||
#define IDC_GSTACK_UNIT26 3750
|
||||
#define IDC_GSTACK_UP26 3751
|
||||
#define IDC_GSTACK_DOWN26 3752
|
||||
#define IDC_GSTACK_SIGNALCOUNT26 3753
|
||||
#define IDC_GSTACK_SET26 3754
|
||||
#define IDC_GSTACK_RESET26 3755
|
||||
#define IDC_GSTACK_UNIT27 3756
|
||||
#define IDC_GSTACK_UP27 3757
|
||||
#define IDC_GSTACK_DOWN27 3758
|
||||
#define IDC_GSTACK_SIGNALCOUNT27 3759
|
||||
#define IDC_GSTACK_SET27 3760
|
||||
#define IDC_GSTACK_RESET27 3761
|
||||
#define IDC_GSTACK_UNIT28 3762
|
||||
#define IDC_GSTACK_UP28 3763
|
||||
#define IDC_GSTACK_DOWN28 3764
|
||||
#define IDC_GSTACK_SIGNALCOUNT28 3765
|
||||
#define IDC_GSTACK_SET28 3766
|
||||
#define IDC_GSTACK_RESET28 3767
|
||||
#define IDC_GSTACK_UNIT29 3768
|
||||
#define IDC_GSTACK_UP29 3769
|
||||
#define IDC_GSTACK_DOWN29 3770
|
||||
#define IDC_GSTACK_SIGNALCOUNT29 3771
|
||||
#define IDC_GSTACK_SET29 3772
|
||||
#define IDC_GSTACK_RESET29 3773
|
||||
#define IDC_GSTACK_UNIT30 3774
|
||||
#define IDC_GSTACK_UP30 3775
|
||||
#define IDC_GSTACK_DOWN30 3776
|
||||
#define IDC_GSTACK_SIGNALCOUNT30 3777
|
||||
#define IDC_GSTACK_SET30 3778
|
||||
#define IDC_GSTACK_RESET30 3779
|
||||
#define IDC_GSTACK_UNIT31 3780
|
||||
#define IDC_GSTACK_UP31 3781
|
||||
#define IDC_GSTACK_DOWN31 3782
|
||||
#define IDC_GSTACK_SIGNALCOUNT31 3783
|
||||
#define IDC_GSTACK_SET31 3784
|
||||
#define IDC_GSTACK_RESET31 3785
|
||||
#define IDC_GSTACK_UNIT32 3786
|
||||
#define IDC_GSTACK_UP32 3787
|
||||
#define IDC_GSTACK_DOWN32 3788
|
||||
#define IDC_GSTACK_SIGNALCOUNT32 3789
|
||||
#define IDC_GSTACK_SET32 3790
|
||||
#define IDC_GSTACK_RESET32 3791
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 124
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 5000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@ -1 +0,0 @@
|
||||
cmd.exe
|
||||
223
CHANGELOG.md
Normal file
223
CHANGELOG.md
Normal file
@ -0,0 +1,223 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Include version info in the binaries, as given be `git describe`. This version
|
||||
info is shown as a label in the tracker and can be checked with `-v` flag in
|
||||
the command line tools.
|
||||
|
||||
### Fixed
|
||||
- Crashes with sample-based oscillators in the 32-bit library, as the pointer to
|
||||
sample-table (edi) got accidentally overwritten by detune
|
||||
- Sample-based oscillators could hard crash if a x87 stack overflow happened
|
||||
when calculating the current position in the sample ([#149][i149])
|
||||
- Numeric updown widget calculated dp-to-px conversion incorrectly, resulting in
|
||||
wrong scaling ([#150][i150])
|
||||
- Empty patch should not crash the native synth ([#148][i148])
|
||||
|
||||
## [0.4.1]
|
||||
### Added
|
||||
- Clicking the parameter slider also selects that parameter ([#112][i112])
|
||||
- The vertical and horizontal split bars indicate with a cursor that they can be
|
||||
resized ([#145][i145])
|
||||
|
||||
### Fixed
|
||||
- When adding a unit on the last row of the unit list, the editor for entering
|
||||
the type of the unit by text did gain focus.
|
||||
- When inputting a note to the note editor, advance the cursor by step
|
||||
([#144][i144])
|
||||
- When loading an instrument, make sure the total number of voices does not go
|
||||
over the maximum number allowed by vm, and make sure a loaded instrument has
|
||||
at least 1 voice
|
||||
- Potential ID collisions when clearing unit or pasteing instruments
|
||||
- Assign new IDs to loaded instruments, and fix ID collisions in case they
|
||||
somehow still appear ([#146][i146])
|
||||
- In x86 templates, do not optimize away phase modulations when unisons are used
|
||||
even if all phase inputs are zeros, as unisons use the phase modulation
|
||||
mechanism to offset the different oscillators
|
||||
- Do not include delay times in the delay time table if the delay unit is
|
||||
disabled ([#139][i139])
|
||||
- Moved the error and warning popups slightly up so they don't block the unit
|
||||
control buttons ([#142][i142])
|
||||
|
||||
### Changed
|
||||
- Do not automatically wrap around the song when playing as it was usually
|
||||
unwanted behaviour. There is already the looping mechanism if the user really
|
||||
wants to loop the song forever.
|
||||
|
||||
## [0.4.0]
|
||||
### Added
|
||||
- User can drop preset instruments into `os.UserConfigDir()/sointu/presets/` and
|
||||
they appear in the list of presets next time sointu is started.
|
||||
([#125][i125])
|
||||
- Ability to loop certain section of the song when playing. The loop can be set
|
||||
by using the toggle button in the song panel, or by hitting Ctrl+L.
|
||||
([#128][i128])
|
||||
- Disable units temporarily. The disabled units are shown in gray and are not
|
||||
compiled into the patch and are considered for all purposes non-existent.
|
||||
Hitting Ctrl-D disables/re-enables the selected unit(s). The yaml file has
|
||||
field `disabled: true` for the unit. ([#116][i116])
|
||||
- Passing a file name on command line immediately tries loading that file ([#122][i122])
|
||||
- Massive rewrite of the GUI, in particular allowing better copying, pasting and
|
||||
scrolling of table-based data (order list and note data).
|
||||
- Dbgain unit, which allows defining the gain in decibels (-40 dB to +40dB)
|
||||
- `+` and `-` keys add/subtract values in order editor and pattern editor
|
||||
([#65][i65])
|
||||
- The function `su_power` is exported so people can reuse it in the main code;
|
||||
however, as it assumes the parameter passed in st0 on the x87 stack and
|
||||
similarly returns it value in st0 on the x87 stack, to my knowledge there is
|
||||
no calling convention that would correspond this behaviour, so you need to
|
||||
define a header for it yourself and take care of putting the float value on
|
||||
x87 stack.
|
||||
|
||||
### Fixed
|
||||
- Loading a preset did not update the IDs of the newly loaded instrument,
|
||||
causing ID collisions and sends target wrong units.
|
||||
- The x87 native filter unit was denormalizing and eating up a lot of CPU ([#68][i68])
|
||||
- Modulating delaytime in wasm could crash, because delay time was converted to
|
||||
int with i32.trunc_f32_u. Using i32.trunc_f32_s fixed this.
|
||||
- When recording notes from VSTI, no track was created for instruments that had
|
||||
no notes triggered, resulting in misalignment of the tracks from instruments.
|
||||
- 32-bit su_load_gmdls clobbered ebx, even though __stdcall demands it to be not
|
||||
touched ([#130][i130])
|
||||
- Spaces are allowed in instrument names ([#120][i120])
|
||||
- Fixed the dropdown for targeting sends making it impossible to choose certain
|
||||
ops. This was done just by reducing the default height of popup menus so they
|
||||
fit on screen ([#121][i121])
|
||||
- Warn user about sample rate being other than 44100 Hz, as this lead to weird
|
||||
behaviour. Sointu assumes the samplerate always to be 44100 Hz. ([#129][i129])
|
||||
|
||||
### Changed
|
||||
- The scroll wheel behavior for unit integer parameters was flipped: scrolling
|
||||
up now increases the value, while scrolling down decreases the value. It was
|
||||
vice versa. ([#112][i112])
|
||||
|
||||
## [0.3.0]
|
||||
### Added
|
||||
- Scroll bars to menus, shown when a menu is too long to fit.
|
||||
- Save the GUI state periodically to a recovery file and load it on
|
||||
startup of the app, if present. The recovery files are located in the
|
||||
app config directory (e.g. AppData/Roaming/Sointu on Windows).
|
||||
- Save the VSTI GUI state to the DAW project file, through GetChunk /
|
||||
SetChunk mechanisms.
|
||||
- Instrument presets. The presets are embedded in the executable and
|
||||
there's a button to open a menu to load one of the presets.
|
||||
- Frequency modulation target for oscillator, as it was in 4klang
|
||||
- Reverb preset settings for a delay unit, with stereo, left and right
|
||||
options
|
||||
|
||||
### Fixed
|
||||
- Crash when running more than one sointu VSTI plugins in parallel
|
||||
- The scroll bars move in sync with the cursor.
|
||||
- The stereo version of delay in the go virtual machine (executables / plugins
|
||||
not ending with -native) applied the left delay taps on the right channel, and
|
||||
the right delay taps on the left channel.
|
||||
- The sointu-vsti-native plugin has different plugin ID and plugin name
|
||||
to not confuse it with the non-native one
|
||||
- The VSTI waits for the gioui actually have quit when closing the
|
||||
plugin
|
||||
|
||||
### Changed
|
||||
- BREAKING CHANGE: The meaning of default modulation mode ("auto") has
|
||||
been changed for cross-instrument modulations: it now means "all"
|
||||
voices, instead of first voice (which was redundant, as it was same as
|
||||
defining voice = 0). This means that for cross-instrument modulations,
|
||||
one "all vocies" send gets actually compiled into multiple sends, one
|
||||
for each targeted voice. For intra-instrument modulations, the meaning
|
||||
stays the same, but the label was changed to "self", to highlight that
|
||||
this means the voice modulates only itself and not other voices.
|
||||
|
||||
## [0.2.0]
|
||||
### Added
|
||||
- Saving and loading instruments
|
||||
- Comment field to instruments
|
||||
- Ability to reorder tracks
|
||||
- Add menu command to delete all unused data from song file
|
||||
- Ability to search a unit by typing its name
|
||||
- Ability to run sointu as a vsti plugin, inside vsti host
|
||||
- Ability to lock delay relative to beat duration
|
||||
- Ability to import 4klang patches (.4kp) and instruments (.4ki)
|
||||
- The repository has example instruments, including all patches and
|
||||
instruments from 4klang
|
||||
- The compiler templates are embedded in the sointu-compile, so no
|
||||
installation is needed beyond copying sointu-compile to PATH
|
||||
- Ability to select multiple units and cut, copy & paste them
|
||||
- Mousewheel adjusts unit parameters
|
||||
- Tooltips to many buttons
|
||||
- Support for gm.dls samples in the go-written virtual machine
|
||||
- x86 and C written examples how to play a sointu song on various
|
||||
platforms. On Windows, the examples can optionally be linked with
|
||||
Crinkler to get Crinkler reports.
|
||||
|
||||
### Fixed
|
||||
- Unnamed instruments with multiple voices caused crashes
|
||||
- In the native version, exceeding the 64 delaylines caused crashes
|
||||
- wat2wasm nowadays uses funcref instead of anyfunc
|
||||
- In the WebAssembly core, $WRK was messed after stereo oscillators,
|
||||
making modulations not work
|
||||
- The Webassembly implementation of mono version of the "out" unit
|
||||
|
||||
### Changed
|
||||
- The release flag in the voice is now a sustain flag i.e. the logic has
|
||||
been inverted. This was done so that when the synth is initialized
|
||||
with zeros, all voices start with sustain = 0 i.e. in released state.
|
||||
- The crush resolution is now in bits instead of linear range; this is a
|
||||
breaking change and changes the meaning of the resolution values. But
|
||||
now there are more usable values in the resolution.
|
||||
|
||||
## [0.1.0]
|
||||
### Added
|
||||
- An instrument (set of opcodes & accompanying values) can have any
|
||||
number of voices.
|
||||
- A track can trigger any number of voices, releasing the previous when
|
||||
new one is triggered.
|
||||
- Pattern length does not have to be a power of 2.
|
||||
- Only the necessary opcodes and functions of the synth are compiled in the final executable.
|
||||
- Harmonized support for stereo signals: every opcode supports stereo
|
||||
variant.
|
||||
- New opcodes: crush, gain, inverse gain, clip, speed (bpm modulation),
|
||||
compressor.
|
||||
- Support for sample-based oscillators (samples loaded from gm.dls).
|
||||
- Unison oscillators: multiple copies of the oscillator running with
|
||||
different detuning and added up to together.
|
||||
- Support for 32 and 64 bit builds.
|
||||
- Support different platforms: Windows, Linux and Mac (Intel).
|
||||
- Experimental support for compiling songs into WebAssembly.
|
||||
- Switch to CMake for builds.
|
||||
- Regression tests for every VM instruction, using CTests.
|
||||
- Compiling as a static library & an API to call Sointu
|
||||
- Running all tests (win/linux/mac/wasm) in the cloud, using Github
|
||||
workflows
|
||||
- Tools written in Go-lang:
|
||||
- a tracker for composing songs as .yml
|
||||
- a command line utility to convert .yml songs to .asm
|
||||
- a command line utility to play the songs on command line
|
||||
|
||||
[Unreleased]: https://github.com/vsariola/sointu/compare/v0.4.1...HEAD
|
||||
[0.4.1]: https://github.com/vsariola/sointu/compare/v0.4.0...v0.4.1
|
||||
[0.4.0]: https://github.com/vsariola/sointu/compare/v0.3.0...v0.4.0
|
||||
[0.3.0]: https://github.com/vsariola/sointu/compare/v0.2.0...v0.3.0
|
||||
[0.2.0]: https://github.com/vsariola/sointu/compare/v0.1.0...v0.2.0
|
||||
[0.1.0]: https://github.com/vsariola/sointu/compare/4klang-3.11...v0.1.0
|
||||
[i65]: https://github.com/vsariola/sointu/issues/65
|
||||
[i68]: https://github.com/vsariola/sointu/issues/68
|
||||
[i112]: https://github.com/vsariola/sointu/issues/112
|
||||
[i116]: https://github.com/vsariola/sointu/issues/116
|
||||
[i120]: https://github.com/vsariola/sointu/issues/120
|
||||
[i121]: https://github.com/vsariola/sointu/issues/121
|
||||
[i122]: https://github.com/vsariola/sointu/issues/122
|
||||
[i125]: https://github.com/vsariola/sointu/issues/125
|
||||
[i128]: https://github.com/vsariola/sointu/issues/128
|
||||
[i129]: https://github.com/vsariola/sointu/issues/129
|
||||
[i130]: https://github.com/vsariola/sointu/issues/130
|
||||
[i139]: https://github.com/vsariola/sointu/issues/139
|
||||
[i142]: https://github.com/vsariola/sointu/issues/142
|
||||
[i144]: https://github.com/vsariola/sointu/issues/144
|
||||
[i145]: https://github.com/vsariola/sointu/issues/145
|
||||
[i146]: https://github.com/vsariola/sointu/issues/146
|
||||
[i148]: https://github.com/vsariola/sointu/issues/148
|
||||
[i149]: https://github.com/vsariola/sointu/issues/149
|
||||
[i150]: https://github.com/vsariola/sointu/issues/150
|
||||
118
CMakeLists.txt
Normal file
118
CMakeLists.txt
Normal file
@ -0,0 +1,118 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# This policy is needed so that we can set the MSVC_RUNTIME to statically linked
|
||||
# i.e. set_property(TARGET 4klang PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
|
||||
project(sointu
|
||||
VERSION 0.0.0
|
||||
DESCRIPTION "A modular synthesizer for 4k/8k/64k intros"
|
||||
LANGUAGES C CXX)
|
||||
|
||||
# Only do these if this is the main project, and not if it is included through add_subdirectory
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
# Let's ensure -std=c++xx instead of -std=g++xx
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Let's nicely support folders in IDE's
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Note this needs to be done in the main CMakeLists
|
||||
# since it calls enable_testing, which must be in the
|
||||
# main CMakeLists.
|
||||
include(CTest)
|
||||
endif()
|
||||
|
||||
IF(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie")
|
||||
# https://stackoverflow.com/questions/69803659/what-is-the-proper-way-to-build-for-macos-x86-64-using-cmake-on-apple-m1-arm
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
find_program(GO NAMES go)
|
||||
if(NOT GO)
|
||||
message(FATAL_ERROR "go not found. Get it from: https://golang.org")
|
||||
else()
|
||||
message("go found at: ${GO}")
|
||||
endif()
|
||||
|
||||
find_program(NODE NAMES node)
|
||||
if(NOT NODE)
|
||||
message( WARNING "node not found, cannot run WebAssembly tests. Get it from: https://nodejs.org/" )
|
||||
else()
|
||||
message("node found at: ${NODE}")
|
||||
endif()
|
||||
|
||||
find_program(WAT2WASM NAMES wat2wasm)
|
||||
if(NOT WAT2WASM )
|
||||
message( WARNING "wat2wasm not found, cannot build wasm tests. Get it from: https://github.com/WebAssembly/wabt)" )
|
||||
else()
|
||||
message("wat2wasm found at: ${WAT2WASM}")
|
||||
endif()
|
||||
|
||||
enable_language(ASM_NASM)
|
||||
|
||||
# The normal NASM compile object does not include <DEFINES>
|
||||
# By putting them there, we can pass the same compile definitions to C and ASM
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> <DEFINES> <FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
|
||||
|
||||
if(WIN32)
|
||||
set(compilecmd ${CMAKE_CURRENT_BINARY_DIR}/sointu-compile.exe)
|
||||
else()
|
||||
set(compilecmd ${CMAKE_CURRENT_BINARY_DIR}/sointu-compile)
|
||||
endif()
|
||||
|
||||
# the tests include the entire ASM but we still want to rebuild when they change
|
||||
file(GLOB x86templates "${PROJECT_SOURCE_DIR}/vm/compiler/templates/amd64-386/*.asm")
|
||||
file(GLOB wasmtemplates "${PROJECT_SOURCE_DIR}/vm/compiler/templates/wasm/*.wat")
|
||||
file(GLOB sointusrc "${PROJECT_SOURCE_DIR}/*.go")
|
||||
file(GLOB compilersrc "${PROJECT_SOURCE_DIR}/compiler/*.go")
|
||||
file(GLOB compilecmdsrc "${PROJECT_SOURCE_DIR}/cmd/sointu-compile/*.go")
|
||||
|
||||
if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(arch "amd64")
|
||||
elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(arch "amd64")
|
||||
else()
|
||||
set(arch "386")
|
||||
endif()
|
||||
|
||||
# Sointu as static library
|
||||
set(STATICLIB sointu)
|
||||
set(sointuasm sointu.asm)
|
||||
|
||||
|
||||
# Build sointu-cli only once because go run has everytime quite a bit of delay when
|
||||
# starting
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
"${compilecmd}"
|
||||
COMMAND
|
||||
${GO} build -o "${compilecmd}" ${PROJECT_SOURCE_DIR}/cmd/sointu-compile/main.go
|
||||
DEPENDS ${x86templates} ${wasmtemplates} ${sointusrc} ${compilersrc} ${compilecmdsrc}
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
sointu-compiler
|
||||
DEPENDS ${compilecmd}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${sointuasm}
|
||||
COMMAND ${compilecmd} -arch=${arch} -a -o ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${compilecmd}
|
||||
)
|
||||
|
||||
add_library(${STATICLIB} ${sointuasm})
|
||||
set_target_properties(${STATICLIB} PROPERTIES LINKER_LANGUAGE C)
|
||||
target_include_directories(${STATICLIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Examples are now available.
|
||||
add_subdirectory(examples)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Emergency override 4KLANG_CMAKE_BUILD_TESTING provided as well
|
||||
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SOINTU_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
52
CMakeSettings.json
Normal file
52
CMakeSettings.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x86-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ],
|
||||
"variables": []
|
||||
},
|
||||
{
|
||||
"name": "x86-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ],
|
||||
"variables": []
|
||||
},
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
},
|
||||
{
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
}
|
||||
]
|
||||
}
|
||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Dominik Ries
|
||||
(c) 2020 Veikko Sariola
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
542
README.md
542
README.md
@ -1,2 +1,540 @@
|
||||
# 4klang
|
||||
Official 4klang repository
|
||||
# Sointu
|
||||

|
||||

|
||||
|
||||
A cross-architecture and cross-platform modular software synthesizer for small
|
||||
intros, forked from [4klang](https://github.com/hzdgopher/4klang). Targetable
|
||||
architectures include 386, amd64, and WebAssembly; targetable platforms include
|
||||
Windows, Mac, Linux (and related) + browser.
|
||||
|
||||
User manual will be in the [Wiki](https://github.com/vsariola/sointu/wiki).
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
You can either 1) download the prebuilt release binaries from the
|
||||
[releases](https://github.com/vsariola/sointu/releases); or 2) download the
|
||||
latest build from the master branch from the
|
||||
[actions](https://github.com/vsariola/sointu/actions) (find workflow "Binaries"
|
||||
and scroll down for .zip files containing the artifacts). Then just run one of
|
||||
the executables or, in the case of the VST plugins library files, copy them
|
||||
wherever you keep you VST2 plugins.
|
||||
|
||||
The pre 1.0 version tags are mostly for reference: no backwards
|
||||
compatibility will be guaranteed while upgrading to a newer version.
|
||||
Backwards compatibility will be attempted from 1.0 onwards.
|
||||
|
||||
**Uninstallation**: Sointu stores recovery data in OS-specific folders
|
||||
e.g. `AppData/Roaming/Sointu` on Windows. For clean uninstall, delete
|
||||
also this folder. See [here](https://pkg.go.dev/os#UserConfigDir) where
|
||||
to find those folders on other platforms.
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
Sointu is work-in-progress. It is a fork and an evolution of
|
||||
[4klang](https://github.com/hzdgopher/4klang), a modular software synthesizer
|
||||
intended to easily produce music for 4k intros — small executables with a
|
||||
maximum filesize of 4096 bytes containing realtime audio and visuals. Like
|
||||
4klang, the sound is produced by a virtual machine that executes small bytecode
|
||||
to produce the audio; however, by now the internal virtual machine has been
|
||||
heavily rewritten and extended. It is actually extended so much that you will
|
||||
never fit all the features at the same time in a 4k intro, but a fairly capable
|
||||
synthesis engine can already be fitted in 600 bytes (386, compressed), with
|
||||
another few hundred bytes for the patch and pattern data.
|
||||
|
||||
Sointu consists of two core elements:
|
||||
- A cross-platform synth-tracker that runs as either VSTi or stand-alone
|
||||
app for composing music, written in [go](https://golang.org/). The app
|
||||
is still heavily work in progress. The app exports the projects as
|
||||
.yml files.
|
||||
- A compiler, likewise written in go, which can be invoked from the command line
|
||||
to compile these .yml files into .asm or .wat code. For x86/amd64, the
|
||||
resulting .asm can be then compiled by [nasm](https://www.nasm.us/). For
|
||||
browsers, the resulting .wat can be compiled by
|
||||
[wat2wasm](https://github.com/WebAssembly/wabt).
|
||||
|
||||
This is how the current prototype app looks like:
|
||||
|
||||

|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Various aspects of the project have different tool dependencies, which are
|
||||
listed below.
|
||||
|
||||
### Sointu-track
|
||||
|
||||
This is the stand-alone version of the synth-tracker. Sointu-track uses
|
||||
the [gioui](https://gioui.org/) for the GUI and [oto](https://github.com/hajimehoshi/oto)
|
||||
for the audio, so the portability is currently limited by these.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [go](https://golang.org/)
|
||||
- If you want to use the faster x86 assembly written synthesizer:
|
||||
- Follow the instructions to build the [x86 native virtual machine](#native-virtual-machine)
|
||||
before building the tracker.
|
||||
- cgo compatible compiler e.g. [gcc](https://gcc.gnu.org/). On
|
||||
windows, you best bet is [MinGW](http://www.mingw.org/). We use the [tdm-gcc](https://jmeubank.github.io/tdm-gcc/).
|
||||
The compiler can be in PATH or you can use the environment variable
|
||||
`CC` to help go find the compiler.
|
||||
- Setting environment variable `CGO_ENABLED=1` is a good idea,
|
||||
because if it is not set and go fails to find the compiler, go just
|
||||
excludes all files with `import "C"` from the build, resulting in
|
||||
lots of errors about missing types.
|
||||
|
||||
#### Running
|
||||
|
||||
```
|
||||
go run cmd/sointu-track/main.go
|
||||
```
|
||||
|
||||
#### Building an executable
|
||||
|
||||
```
|
||||
go build -o sointu-track.exe cmd/sointu-track/main.go
|
||||
```
|
||||
|
||||
On other platforms than Windows, replace `-o sointu-track.exe` with
|
||||
`-o sointu-track`.
|
||||
|
||||
If you want to use the [x86 native virtual machine](#native-virtual-machine),
|
||||
add `-tags=native` to all the commands e.g.
|
||||
|
||||
```
|
||||
go build -o sointu-track.exe -tags=native cmd/sointu-track/main.go
|
||||
```
|
||||
|
||||
### Sointu-vsti
|
||||
|
||||
This is the VST instrument plugin version of the tracker, compiled into
|
||||
a dynamically linked library and ran inside a VST host.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [go](https://golang.org/)
|
||||
- cgo compatible compiler e.g. [gcc](https://gcc.gnu.org/). On windows,
|
||||
you best bet is [MinGW](http://www.mingw.org/). We use the [tdm-gcc](https://jmeubank.github.io/tdm-gcc/).
|
||||
The compiler can be in PATH or you can use the environment variable
|
||||
`CC` to help go find the compiler.
|
||||
- Setting environment variable `CGO_ENABLED=1` is a good idea, because
|
||||
if it is not set and go fails to find the compiler, go just excludes
|
||||
all files with `import "C"` from the build, resulting in lots of
|
||||
errors about missing types.
|
||||
- If you want to use the faster x86 assembly written synthesizer:
|
||||
- Follow the instructions to build the [x86 native virtual machine](#native-virtual-machine)
|
||||
before building the plugin itself
|
||||
|
||||
#### Building
|
||||
|
||||
```
|
||||
go build -buildmode=c-shared -tags=plugin -o sointu-vsti.dll .\cmd\sointu-vsti\
|
||||
```
|
||||
|
||||
On other platforms than Windows, replace `-o sointu-vsti.dll` appropriately e.g.
|
||||
`-o sointu-vsti.so`; so far, the VST instrument has been built & tested on
|
||||
Windows and Linux.
|
||||
|
||||
Notice the `-tags=plugin` build tag definition. This is required by the [vst2
|
||||
library](https://github.com/pipelined/vst2); otherwise, you will get a lot of
|
||||
build errors.
|
||||
|
||||
Add `-tags=native,plugin` to use the [x86 native virtual
|
||||
machine](#native-virtual-machine) instead of the virtual machine written in Go.
|
||||
|
||||
### Sointu-compile
|
||||
|
||||
The command line interface to it is [sointu-compile](cmd/sointu-compile/main.go)
|
||||
and the actual code resides in the [compiler](vm/compiler/) package, which is an
|
||||
ordinary [go](https://golang.org/) package with no other tool dependencies.
|
||||
|
||||
#### Running
|
||||
|
||||
```
|
||||
go run cmd/sointu-compile/main.go
|
||||
```
|
||||
|
||||
#### Building an executable
|
||||
|
||||
```
|
||||
go build -o sointu-compile.exe cmd/sointu-compile/main.go
|
||||
```
|
||||
|
||||
On other platforms than Windows, replace `-o sointu-compile.exe` with
|
||||
`-o sointu-compile`.
|
||||
|
||||
#### Usage
|
||||
|
||||
The compiler can then be used to compile a .yml song into .asm and .h files. For
|
||||
example:
|
||||
|
||||
```
|
||||
sointu-compile -o . -arch=386 tests/test_chords.yml
|
||||
nasm -f win32 test_chords.asm
|
||||
```
|
||||
|
||||
WebAssembly example:
|
||||
|
||||
```
|
||||
sointu-compile -o . -arch=wasm tests/test_chords.yml
|
||||
wat2wasm --enable-bulk-memory test_chords.wat
|
||||
```
|
||||
|
||||
If you are looking for an easy way to compile an executable from a Sointu song
|
||||
(e.g. for a executable music compo), take a look at [NR4's Python-based
|
||||
tool](https://github.com/LeStahL/sointu-executable-msx) for it.
|
||||
|
||||
#### Examples
|
||||
|
||||
The folder `examples/code` contains usage examples for Sointu with winmm and
|
||||
dsound playback under Windows and asound playback under Unix. Source code is
|
||||
available in C and x86 assembly (win32, elf32 and elf64 versions).
|
||||
|
||||
To build the examples, use `ninja examples`.
|
||||
|
||||
If you want to target smaller executable sizes, using a compressing linker like
|
||||
[Crinkler](https://github.com/runestubbe/Crinkler) on Windows is recommended.
|
||||
|
||||
The linux examples use ALSA and need libasound2-dev (or libasound2-dev:386)
|
||||
installed. The 386 version also needs pipewire-alsa:386 installed, which is not
|
||||
there by default.
|
||||
|
||||
### Native virtual machine
|
||||
|
||||
The native bridge allows Go to call the sointu compiled x86 native virtual
|
||||
machine, through cgo, instead of using the Go written bytecode interpreter. It's
|
||||
likely slightly faster than the interpreter. Before you can actually run it, you
|
||||
need to build the bridge using CMake (thus, ***this will not work with go
|
||||
get***).
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [CMake](https://cmake.org)
|
||||
- [nasm](https://www.nasm.us/)
|
||||
- *cgo compatible compiler* e.g. [gcc](https://gcc.gnu.org/). On windows, you
|
||||
best bet is [MinGW](http://www.mingw.org/). We use the
|
||||
[tdm-gcc](https://jmeubank.github.io/tdm-gcc/)
|
||||
|
||||
The last point is because the command line player and the tracker use
|
||||
[cgo](https://golang.org/cmd/cgo/) to interface with the synth core, which is
|
||||
compiled into a library. The cgo bridge resides in the package
|
||||
[bridge](vm/compiler/bridge/).
|
||||
|
||||
#### Building
|
||||
|
||||
Assuming you are using [ninja](https://ninja-build.org/):
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -GNinja
|
||||
ninja sointu
|
||||
```
|
||||
|
||||
> :warning: *you must build the library inside a directory called 'build' at the
|
||||
> root of the project*. This is because the path where cgo looks for the library
|
||||
> is hard coded to point to build/ in the go files.
|
||||
|
||||
Running `ninja sointu` only builds the static library that Go needs. This is a
|
||||
lot faster than building all the CTests.
|
||||
|
||||
You and now run all the Go tests, even the ones that test the native bridge.
|
||||
From the project root folder, run:
|
||||
|
||||
```
|
||||
go test ./...
|
||||
```
|
||||
|
||||
Play a song from the command line:
|
||||
```
|
||||
go run -tags=native cmd/sointu-play/main.go tests/test_chords.yml
|
||||
```
|
||||
|
||||
> :warning: Unlike the x86/amd64 VM compiled by Sointu, the Go written VM
|
||||
> bytecode interpreter uses a software stack. Thus, unlike x87 FPU stack, it is
|
||||
> not limited to 8 items. If you intent to compile the patch to x86/amd64
|
||||
> targets, make sure not to use too much stack. Keeping at most 5 signals in the
|
||||
> stack is presumably fine (reserving 3 for the temporary variables of the
|
||||
> opcodes). In future, the app should give warnings if the user is about to
|
||||
> exceed the capabilities of a target platform.
|
||||
|
||||
> :warning: **If you are using Yasm instead of Nasm, and you are using MinGW**:
|
||||
> Yasm 1.3.0 (currently still the latest stable release) and GNU linker do not
|
||||
> play nicely along, trashing the BSS layout. The linker had placed our synth
|
||||
> object overlapping with DLL call addresses; very funny stuff to debug. See
|
||||
> [here](https://tortall.lighthouseapp.com/projects/78676/tickets/274-bss-problem-with-windows-win64)
|
||||
> and the fix
|
||||
> [here](https://github.com/yasm/yasm/commit/1910e914792399137dec0b047c59965207245df5).
|
||||
> Since Nasm is nowadays under BSD license, there is absolutely no reason to use
|
||||
> Yasm. However, if you do, use a newer nightly build of Yasm that includes the
|
||||
> fix.
|
||||
|
||||
### Tests
|
||||
|
||||
There are [regression tests](tests/) that are built as executables,
|
||||
testing that they work the same way when you would link them in an
|
||||
intro.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- [go](https://golang.org/)
|
||||
- [CMake](https://cmake.org) with CTest
|
||||
- [nasm](https://www.nasm.us/)
|
||||
- Your favorite CMake compatible c-compiler & build tool. Results have been
|
||||
obtained using Visual Studio 2019, gcc&make on linux, MinGW&mingw32-make, and
|
||||
ninja&AppleClang.
|
||||
|
||||
#### Building and running
|
||||
|
||||
Assuming you are using [ninja](https://ninja-build.org/):
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -GNinja
|
||||
ninja
|
||||
ninja test
|
||||
```
|
||||
|
||||
Note that this builds 64-bit binaries on 64-bit Windows. To build 32-bit
|
||||
binaries on 64-bit Windows, replace in above:
|
||||
|
||||
```
|
||||
cmake .. -DCMAKE_C_FLAGS="-m32" -DCMAKE_ASM_NASM_OBJECT_FORMAT="win32" -GNinja
|
||||
```
|
||||
|
||||
Another example: on Visual Studio 2019 Community, just open the folder, choose
|
||||
either Debug or Release and either x86 or x64 build, and hit build all.
|
||||
|
||||
### WebAssembly tests
|
||||
|
||||
These are automatically invoked by CTest if [node](https://nodejs.org) and
|
||||
[wat2wasm](https://github.com/WebAssembly/wabt) are found in the path.
|
||||
|
||||
New features since fork
|
||||
-----------------------
|
||||
|
||||
- **New units**. For example: bit-crusher, gain, inverse gain, clip, modulate
|
||||
bpm (proper triplets!), compressor (can be used for side-chaining).
|
||||
- **Compiler**. Written in go. The input is a .yml file and the output is an
|
||||
.asm. It works by inputting the song data to the excellent go
|
||||
`text/template` package, effectively working as a preprocessor. This allows
|
||||
quite powerful combination: we can handcraft the assembly code to keep the
|
||||
entropy as low as possible, yet we can call arbitrary go functions as
|
||||
"macros". The templates are [here](templates/) and the compiler lives
|
||||
[here](vm/compiler/).
|
||||
- **Tracker**. Written in go. Can run either as a stand-alone app or a vsti
|
||||
plugin.
|
||||
- **Supports 32 and 64 bit builds**. The 64-bit version is done with minimal
|
||||
changes to get it work, using template macros to change the lines between
|
||||
32-bit and 64-bit modes. Mostly, it's as easy as writing {{.AX}} instead of
|
||||
eax; the macro {{.AX}} compiles to eax in 32-bit and rax in 64-bit.
|
||||
- **Supports compiling into WebAssembly**. This is a complete reimplementation
|
||||
of the core, written in WebAssembly text format (.wat).
|
||||
- **Supports Windows, Linux and MacOS**. On all three 64-bit platforms, all
|
||||
tests are passing. Additionally, all tests are passing on windows 32.
|
||||
- **Per instrument polyphonism**. An instrument has the possibility to have
|
||||
any number of voices, meaning that multiple voices can reuse the same
|
||||
opcodes. So, you can have a single instrument with three voices, and three
|
||||
tracks that use this instrument, to make chords. See
|
||||
[here](tests/test_chords.yml) for an example and
|
||||
[here](templates/amd64-386/patch.asm) for the implementation. The maximum
|
||||
total number of voices is 32: you can have 32 monophonic instruments or any
|
||||
combination of polyphonic instruments adding up to 32.
|
||||
- **Any number of voices per track**. A single track can trigger more than one
|
||||
voice. At every note, a new voice from the assigned voices is triggered and
|
||||
the previous released. Combined with the previous, you can have a single
|
||||
track trigger 3 voices and all these three voices use the same instrument,
|
||||
useful to do polyphonic arpeggios (see [here](tests/test_polyphony.yml)).
|
||||
Not only that, a track can even trigger voices of different instruments,
|
||||
alternating between these two; maybe useful for example as an easy way to
|
||||
alternate between an open and a closed hihat.
|
||||
- **Easily extensible**. Instead of %ifdef hell, the primary extension
|
||||
mechanism is through new opcodes for the virtual machine. Only the opcodes
|
||||
actually used in a song are compiled into the virtual machine. The goal is
|
||||
to try to write the code so that if two similar opcodes are used, the common
|
||||
code in both is reused by moving it to a function. Macro and linker magic
|
||||
ensure that also helper functions are only compiled in if they are actually
|
||||
used.
|
||||
- **Songs are YAML files**. These markup files are simple data files,
|
||||
describing the tracks, patterns and patch structure (see
|
||||
[here](tests/test_oscillat_trisaw.yml) for an example). The sointu-compile
|
||||
then reads these files and compiles them into .asm code. This has the nice
|
||||
implication that, in future, there will be no need for a binary format to
|
||||
save patches, nor should you need to commit .o or .asm to repo: just put the
|
||||
.yml in the repo and automate the .yml -> .asm -> .o steps using
|
||||
sointu-compile & nasm.
|
||||
- **Harmonized support for stereo signals**. Every opcode supports a stereo
|
||||
variant: the stereo bit is hidden in the least significant bit of the
|
||||
command stream and passed in carry to the opcode. This has several nice
|
||||
advantages: 1) the opcodes that don't need any parameters do not need an
|
||||
entire byte in the value stream to define whether it is stereo; 2) stereo
|
||||
variants of opcodes can be implemented rather efficiently; in some cases,
|
||||
the extra cost of stereo variant is only 5 bytes (uncompressed). 3) Since
|
||||
stereo opcodes usually follow stereo opcodes (and mono opcodes follow mono
|
||||
opcodes), the stereo bits of the command bytes will be highly correlated and
|
||||
if crinkler or any other modeling compressor is doing its job, that should
|
||||
make them highly predictable i.e. highly compressable.
|
||||
- **Test-driven development**. Given that 4klang was already a mature project,
|
||||
the first thing actually implemented was a set of regression tests to avoid
|
||||
breaking everything beyond any hope of repair. Done, using go test (runs the
|
||||
.yml regression tests through the library) and CTest (compiles each .yml
|
||||
into executable and ensures that when run like this, the test case produces
|
||||
identical output). The tests are also ran in the cloud using github actions.
|
||||
- **Arbitrary signal routing**. SEND (used to be called FST in 4klang) opcode
|
||||
normally sends the signal as a modulation to another opcode. But with the
|
||||
new RECEIVE opcode, you just receive the plain signal there. So you can
|
||||
connect signals in an arbitrary way. Actually, 4klang could already do this
|
||||
but in a very awkward way: it had FLD (load value) opcode that could be
|
||||
modulated; FLD 0 with modulation basically achieved what RECEIVE does,
|
||||
except that RECEIVE can also handle stereo signals. Additionally, we have
|
||||
OUTAUX, AUX and IN opcodes, which route the signals through global main or
|
||||
aux ports, more closer to how 4klang does. But this time we have 8 mono
|
||||
ports / 4 stereo ports, so even this method of routing is unlikely to run
|
||||
out of ports in small intros.
|
||||
- **Pattern length does not have to be a power of 2**.
|
||||
- **Sample-based oscillators, with samples imported from gm.dls**. The
|
||||
gm.dls is available from system folder only on Windows, but the
|
||||
non-native tracker looks for it also in the current folder, so
|
||||
should you somehow magically get hold of gm.dls on Linux or Mac, you
|
||||
can drop it in the same folder with the tracker. See [this example](tests/test_oscillat_sample.yml),
|
||||
and this go generate [program](cmd/sointu-generate/main.go) parses
|
||||
the gm.dls file and dumps the sample offsets from it.
|
||||
- **Unison oscillators**. Multiple copies of the oscillator running slightly
|
||||
detuned and added up to together. Great for trance leads (supersaw). Unison
|
||||
of up to 4, or 8 if you make stereo unison oscillator and add up both left
|
||||
and right channels. See [this example](tests/test_oscillat_unison.yml).
|
||||
- **Compiling as a library**. The API is very rudimentary, a single function
|
||||
render, and between calls, the user is responsible for manipulating the
|
||||
synth state in a similar way as the actual player does (e.g. triggering/
|
||||
releasing voices etc.)
|
||||
- **Calling Sointu as a library from Go language**. The Go API is slighty more
|
||||
sane than the low-level library API, offering more Go-like experience.
|
||||
- **A bytecode interpreter written in pure go**. It's slightly slower than the
|
||||
hand-written assembly code by sointu compiler, but with this, the tracker is
|
||||
ultraportable and does not need cgo calls.
|
||||
|
||||
Future goals
|
||||
------------
|
||||
|
||||
- **Find a more general solution for skipping opcodes / early outs**. It might
|
||||
be a new opcode "skip" that skips from the opcode to the next out in case
|
||||
the signal entering skip and the signal leaving out are both close to zero.
|
||||
Need to investigate the best way to implement this.
|
||||
- **Even more opcodes**. Some potentially useful additions could be:
|
||||
- Equalizer / more flexible filters
|
||||
- Very slow filters (~ DC-offset removal). Can be implemented using a single
|
||||
bit flag in the existing filter
|
||||
- Arbitrary envelopes; for easier automation.
|
||||
- **MIDI support for the tracker**.
|
||||
- **Find a solution for denormalized signals**. Denormalized floating point
|
||||
numbers (floating point numbers that are very very small) can result in 100x
|
||||
CPU slow down. We got hit by this already: the damp filters in delay units
|
||||
were denormalizing, resulting in the synth being unusable in real time. Need
|
||||
to investigate a) where denormalization can happen; b) how to prevent it:
|
||||
add & substract value; c) make this optional to the user. For quick
|
||||
explanation about the potential massive CPU hit, see
|
||||
https://stackoverflow.com/questions/36781881/why-denormalized-floats-are-so-much-slower-than-other-floats-from-hardware-arch
|
||||
|
||||
Long-shot ideas
|
||||
-----------
|
||||
- **Hack deeper into audio sources from the OS**. Speech synthesis, I'm eyeing
|
||||
at you.
|
||||
|
||||
Design philosophy
|
||||
-----------------
|
||||
|
||||
- Make sure the assembly code is readable after compiling: it should have
|
||||
liberally comments *in the outputted .asm file*. This allows humans to study
|
||||
the outputted code and figure out more easily if there's still way to
|
||||
squeeze out instructions from the code.
|
||||
- Instead of prematurely adding %ifdef toggles to optimize away unused
|
||||
features, start with the most advanced featureset and see if you can
|
||||
implement it in a generalized way. For example, all the modulations are now
|
||||
added into the values when they are converted from integers, in a
|
||||
standardized way. This got rid of most of the %ifdefs in 4klang. Also, with
|
||||
no %ifdefs cluttering the view, many opportunities to shave away
|
||||
instructions became apparent. Also, by making the most advanced synth
|
||||
cheaply available to the scene, we promote better music in future 4ks :)
|
||||
- Size first, speed second. Speed will only considered if the situation
|
||||
becomes untolerable.
|
||||
- Benchmark optimizations. Compression results are sometimes slightly
|
||||
nonintuitive so alternative implementations should always be benchmarked
|
||||
e.g. by compiling and linking a real-world song with
|
||||
[Leviathan](https://github.com/armak/Leviathan-2.0) and observing how the
|
||||
optimizations affect the byte size.
|
||||
|
||||
Background and history
|
||||
----------------------
|
||||
|
||||
[4klang](https://github.com/hzdgopher/4klang) development was started in 2007 by
|
||||
Dominik Ries (gopher) and Paul Kraus (pOWL) of Alcatraz. The
|
||||
[write-up](http://zine.bitfellas.org/article.php?zine=14&id=35) will still be
|
||||
helpful for anyone looking to understand how 4klang and Sointu use the FPU stack
|
||||
to manipulate the signals. Since then, 4klang has been used in countless of
|
||||
scene productions and people use it even today.
|
||||
|
||||
However, 4klang seems not to be actively developed anymore and polyphonism was
|
||||
implemented only in a rather limited way (you could have exactly 2 voices per
|
||||
instrument if you enable it). Also, reading through the code, I spotted several
|
||||
avenues to squeeze away more bytes. These observations triggered project Sointu.
|
||||
That, and I just wanted to learn x86 assembly, and needed a real-world project
|
||||
to work on.
|
||||
|
||||
What's with the name
|
||||
--------------------
|
||||
|
||||
"Sointu" means a chord, in Finnish; a reference to the polyphonic capabilities
|
||||
of the synth. I assume we have all learned by now what "klang" means in German,
|
||||
so I thought it would fun to learn some Finnish for a change. And
|
||||
[there's](https://www.pouet.net/prod.php?which=53398)
|
||||
[enough](https://www.pouet.net/prod.php?which=75814)
|
||||
[klangs](https://www.pouet.net/prod.php?which=85351) already.
|
||||
|
||||
Prods using Sointu
|
||||
------------------
|
||||
|
||||
- [Adam](https://github.com/vsariola/adam) by brainlez Coders! My first
|
||||
test-driving of Sointu. The repository has some ideas how to integrate
|
||||
Sointu to the build chain.
|
||||
- [Roadtrip](https://www.pouet.net/prod.php?which=94105) by LJ & Virgill
|
||||
- [|](https://www.pouet.net/prod.php?which=94721) by epoqe. Likely the first
|
||||
Linux 4k intro using sointu.
|
||||
- [Physics Girl St.](https://www.pouet.net/prod.php?which=94890) by Team210
|
||||
- [Delusions of mediocrity](https://www.pouet.net/prod.php?which=95222) by
|
||||
mrange & Virgill
|
||||
- [Xorverse](https://www.pouet.net/prod.php?which=95221) by Alcatraz
|
||||
- [l'enveloppe](https://www.pouet.net/prod.php?which=95215) by Team210 & epoqe
|
||||
- [Phosphorescent Purple Pixel Peaks](https://www.pouet.net/prod.php?which=96198) by mrange & Virgill
|
||||
- [21](https://demozoo.org/music/338597/) by NR4 / Team210
|
||||
- [Tausendeins](https://www.pouet.net/prod.php?which=96192) by epoqe & Team210
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Pull requests / suggestions / issues welcome, through Github! Or just DM
|
||||
me on Discord (see contact information below).
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
Veikko Sariola - pestis_bc on Demoscene discord - firstname.lastname@gmail.com
|
||||
|
||||
Project Link: [https://github.com/vsariola/sointu](https://github.com/vsariola/sointu)
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
The original 4klang: Dominik Ries ([gopher/Alcatraz](https://github.com/hzdgopher/4klang))
|
||||
& Paul Kraus (pOWL/Alcatraz) :heart:
|
||||
|
||||
Sointu: Veikko Sariola (pestis/bC!), [Apollo/bC!](https://github.com/moitias),
|
||||
[NR4/Team210](https://github.com/LeStahL/), [PoroCYon](https://github.com/PoroCYon/4klang),
|
||||
[kendfss](https://github.com/kendfss), [anticore](https://github.com/anticore)
|
||||
|
||||
250
audio.go
Normal file
250
audio.go
Normal file
@ -0,0 +1,250 @@
|
||||
package sointu
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type (
|
||||
// AudioBuffer is a buffer of stereo audio samples of variable length, each
|
||||
// sample represented by [2]float32. [0] is left channel, [1] is right
|
||||
AudioBuffer [][2]float32
|
||||
|
||||
// AudioOutput represents something where we can send audio e.g. audio output.
|
||||
// WriteAudio should block if not ready to accept audio e.g. buffer full.
|
||||
AudioOutput interface {
|
||||
WriteAudio(buffer AudioBuffer) error
|
||||
Close() error
|
||||
}
|
||||
|
||||
// AudioContext represents the low-level audio drivers. There should be at most
|
||||
// one AudioContext at a time. The interface is implemented at least by
|
||||
// oto.OtoContext, but in future we could also mock it.
|
||||
//
|
||||
// AudioContext is used to create one or more AudioOutputs with Output(); each
|
||||
// can be used to output separate sound & closed when done.
|
||||
AudioContext interface {
|
||||
Output() AudioOutput
|
||||
Close() error
|
||||
}
|
||||
|
||||
// Synth represents a state of a synthesizer, compiled from a Patch.
|
||||
Synth interface {
|
||||
// Render tries to fill a stereo signal buffer with sound from the
|
||||
// synthesizer, until either the buffer is full or a given number of
|
||||
// timesteps is advanced. Normally, 1 sample = 1 unit of time, but speed
|
||||
// modulations may change this. It returns the number of samples filled (in
|
||||
// stereo samples i.e. number of elements of AudioBuffer filled), the
|
||||
// number of sync outputs written, the number of time steps time advanced,
|
||||
// and a possible error.
|
||||
Render(buffer AudioBuffer, maxtime int) (sample int, time int, err error)
|
||||
|
||||
// Update recompiles a patch, but should maintain as much as possible of its
|
||||
// state as reasonable. For example, filters should keep their state and
|
||||
// delaylines should keep their content. Every change in the Patch triggers
|
||||
// an Update and if the Patch would be started fresh every time, it would
|
||||
// lead to very choppy audio.
|
||||
Update(patch Patch, bpm int) error
|
||||
|
||||
// Trigger triggers a note for a given voice. Called between synth.Renders.
|
||||
Trigger(voice int, note byte)
|
||||
|
||||
// Release releases the currently playing note for a given voice. Called
|
||||
// between synth.Renders.
|
||||
Release(voice int)
|
||||
}
|
||||
|
||||
// Synther compiles a given Patch into a Synth, throwing errors if the
|
||||
// Patch is malformed.
|
||||
Synther interface {
|
||||
Synth(patch Patch, bpm int) (Synth, error)
|
||||
}
|
||||
)
|
||||
|
||||
// Play plays the Song by first compiling the patch with the given Synther,
|
||||
// returning the stereo audio buffer as a result (and possible errors).
|
||||
func Play(synther Synther, song Song, progress func(float32)) (AudioBuffer, error) {
|
||||
err := song.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
synth, err := synther.Synth(song.Patch, song.BPM)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sointu.Play failed: %v", err)
|
||||
}
|
||||
curVoices := make([]int, len(song.Score.Tracks))
|
||||
for i := range curVoices {
|
||||
curVoices[i] = song.Score.FirstVoiceForTrack(i)
|
||||
}
|
||||
initialCapacity := song.Score.LengthInRows() * song.SamplesPerRow()
|
||||
buffer := make(AudioBuffer, 0, initialCapacity)
|
||||
rowbuffer := make(AudioBuffer, song.SamplesPerRow())
|
||||
for row := 0; row < song.Score.LengthInRows(); row++ {
|
||||
patternRow := row % song.Score.RowsPerPattern
|
||||
pattern := row / song.Score.RowsPerPattern
|
||||
for t := range song.Score.Tracks {
|
||||
order := song.Score.Tracks[t].Order
|
||||
if pattern < 0 || pattern >= len(order) {
|
||||
continue
|
||||
}
|
||||
patternIndex := song.Score.Tracks[t].Order[pattern]
|
||||
patterns := song.Score.Tracks[t].Patterns
|
||||
if patternIndex < 0 || int(patternIndex) >= len(patterns) {
|
||||
continue
|
||||
}
|
||||
pattern := patterns[patternIndex]
|
||||
if patternRow < 0 || patternRow >= len(pattern) {
|
||||
continue
|
||||
}
|
||||
note := pattern[patternRow]
|
||||
if note > 0 && note <= 1 { // anything but hold causes an action.
|
||||
continue
|
||||
}
|
||||
synth.Release(curVoices[t])
|
||||
if note > 1 {
|
||||
curVoices[t]++
|
||||
first := song.Score.FirstVoiceForTrack(t)
|
||||
if curVoices[t] >= first+song.Score.Tracks[t].NumVoices {
|
||||
curVoices[t] = first
|
||||
}
|
||||
synth.Trigger(curVoices[t], note)
|
||||
}
|
||||
}
|
||||
tries := 0
|
||||
for rowtime := 0; rowtime < song.SamplesPerRow(); {
|
||||
samples, time, err := synth.Render(rowbuffer, song.SamplesPerRow()-rowtime)
|
||||
if err != nil {
|
||||
return buffer, fmt.Errorf("render failed: %v", err)
|
||||
}
|
||||
rowtime += time
|
||||
buffer = append(buffer, rowbuffer[:samples]...)
|
||||
if tries > 100 {
|
||||
return nil, fmt.Errorf("Song speed modulation likely so slow that row never advances; error at pattern %v, row %v", pattern, patternRow)
|
||||
}
|
||||
}
|
||||
if progress != nil {
|
||||
progress(float32(row+1) / float32(song.Score.LengthInRows()))
|
||||
}
|
||||
}
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
// Fill fills the AudioBuffer using a Synth, disregarding all syncs and time
|
||||
// limits. Note that this will change the state of the Synth.
|
||||
func (buffer AudioBuffer) Fill(synth Synth) error {
|
||||
s, _, err := synth.Render(buffer, math.MaxInt32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("synth.Render failed: %v", err)
|
||||
}
|
||||
if s != len(buffer) {
|
||||
return errors.New("in AudioBuffer.Fill, synth.Render should have filled the whole buffer but did not")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wav converts an AudioBuffer into a valid WAV-file, returned as a []byte
|
||||
// array.
|
||||
//
|
||||
// If pcm16 is set to true, the samples in the WAV-file will be 16-bit signed
|
||||
// integers; otherwise the samples will be 32-bit floats
|
||||
func (buffer AudioBuffer) Wav(pcm16 bool) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
wavHeader(len(buffer)*2, pcm16, buf)
|
||||
err := buffer.rawToBuffer(pcm16, buf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Wav failed: %v", err)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Raw converts an AudioBuffer into a raw audio file, returned as a []byte
|
||||
// array.
|
||||
//
|
||||
// If pcm16 is set to true, the samples will be 16-bit signed integers;
|
||||
// otherwise the samples will be 32-bit floats
|
||||
func (buffer AudioBuffer) Raw(pcm16 bool) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := buffer.rawToBuffer(pcm16, buf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Raw failed: %v", err)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (data AudioBuffer) rawToBuffer(pcm16 bool, buf *bytes.Buffer) error {
|
||||
var err error
|
||||
if pcm16 {
|
||||
int16data := make([][2]int16, len(data))
|
||||
for i, v := range data {
|
||||
int16data[i][0] = int16(clamp(int(v[0]*math.MaxInt16), math.MinInt16, math.MaxInt16))
|
||||
int16data[i][1] = int16(clamp(int(v[1]*math.MaxInt16), math.MinInt16, math.MaxInt16))
|
||||
}
|
||||
err = binary.Write(buf, binary.LittleEndian, int16data)
|
||||
} else {
|
||||
err = binary.Write(buf, binary.LittleEndian, data)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not binary write data to binary buffer: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// wavHeader writes a wave header for either float32 or int16 .wav file into the
|
||||
// bytes.buffer. It needs to know the length of the buffer and assumes stereo
|
||||
// sound, so the length in stereo samples (L + R) is bufferlength / 2. If pcm16
|
||||
// = true, then the header is for int16 audio; pcm16 = false means the header is
|
||||
// for float32 audio. Assumes 44100 Hz sample rate.
|
||||
func wavHeader(bufferLength int, pcm16 bool, buf *bytes.Buffer) {
|
||||
// Refer to: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
|
||||
numChannels := 2
|
||||
sampleRate := 44100
|
||||
var bytesPerSample, chunkSize, fmtChunkSize, waveFormat int
|
||||
var factChunk bool
|
||||
if pcm16 {
|
||||
bytesPerSample = 2
|
||||
chunkSize = 36 + bytesPerSample*bufferLength
|
||||
fmtChunkSize = 16
|
||||
waveFormat = 1 // PCM
|
||||
factChunk = false
|
||||
} else {
|
||||
bytesPerSample = 4
|
||||
chunkSize = 50 + bytesPerSample*bufferLength
|
||||
fmtChunkSize = 18
|
||||
waveFormat = 3 // IEEE float
|
||||
factChunk = true
|
||||
}
|
||||
buf.Write([]byte("RIFF"))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(chunkSize))
|
||||
buf.Write([]byte("WAVE"))
|
||||
buf.Write([]byte("fmt "))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(fmtChunkSize))
|
||||
binary.Write(buf, binary.LittleEndian, uint16(waveFormat))
|
||||
binary.Write(buf, binary.LittleEndian, uint16(numChannels))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(sampleRate))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(sampleRate*numChannels*bytesPerSample)) // avgBytesPerSec
|
||||
binary.Write(buf, binary.LittleEndian, uint16(numChannels*bytesPerSample)) // blockAlign
|
||||
binary.Write(buf, binary.LittleEndian, uint16(8*bytesPerSample)) // bits per sample
|
||||
if fmtChunkSize > 16 {
|
||||
binary.Write(buf, binary.LittleEndian, uint16(0)) // size of extension
|
||||
}
|
||||
if factChunk {
|
||||
buf.Write([]byte("fact"))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(4)) // fact chunk size
|
||||
binary.Write(buf, binary.LittleEndian, uint32(bufferLength)) // sample length
|
||||
}
|
||||
buf.Write([]byte("data"))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(bytesPerSample*bufferLength))
|
||||
}
|
||||
|
||||
func clamp(value, min, max int) int {
|
||||
if value < min {
|
||||
return min
|
||||
}
|
||||
if value > max {
|
||||
return max
|
||||
}
|
||||
return value
|
||||
}
|
||||
7
cmd/main_synther_native.go
Normal file
7
cmd/main_synther_native.go
Normal file
@ -0,0 +1,7 @@
|
||||
//go:build native
|
||||
|
||||
package cmd
|
||||
|
||||
import "github.com/vsariola/sointu/vm/compiler/bridge"
|
||||
|
||||
var MainSynther = bridge.NativeSynther{}
|
||||
7
cmd/main_synther_not_native.go
Normal file
7
cmd/main_synther_not_native.go
Normal file
@ -0,0 +1,7 @@
|
||||
//go:build !native
|
||||
|
||||
package cmd
|
||||
|
||||
import "github.com/vsariola/sointu/vm"
|
||||
|
||||
var MainSynther = vm.GoSynther{}
|
||||
233
cmd/sointu-compile/main.go
Normal file
233
cmd/sointu-compile/main.go
Normal file
@ -0,0 +1,233 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/version"
|
||||
"github.com/vsariola/sointu/vm/compiler"
|
||||
)
|
||||
|
||||
func filterExtensions(input map[string]string, extensions []string) map[string]string {
|
||||
ret := map[string]string{}
|
||||
for _, ext := range extensions {
|
||||
extWithDot := "." + ext
|
||||
if inputVal, ok := input[extWithDot]; ok {
|
||||
ret[extWithDot] = inputVal
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func main() {
|
||||
safe := flag.Bool("n", false, "Never overwrite files; if file already exists and would be overwritten, give an error.")
|
||||
list := flag.Bool("l", false, "Do not write files; just list files that would change instead.")
|
||||
stdout := flag.Bool("s", false, "Do not write files; write to standard output instead.")
|
||||
help := flag.Bool("h", false, "Show help.")
|
||||
rowsync := flag.Bool("r", false, "Write the current fractional row as sync #0")
|
||||
library := flag.Bool("a", false, "Compile Sointu into a library. Input files are not needed.")
|
||||
jsonOut := flag.Bool("j", false, "Output the song as .json file instead of compiling.")
|
||||
yamlOut := flag.Bool("y", false, "Output the song as .yml file instead of compiling.")
|
||||
tmplDir := flag.String("t", "", "When compiling, use the templates in this directory instead of the standard templates.")
|
||||
outPath := flag.String("o", "", "Directory or filename where to write compiled code. Extension is ignored. Directory and its parents are created if needed. By default, everything is placed in the same directory where the original song file is.")
|
||||
extensionsOut := flag.String("e", "", "Output only the compiled files with these comma separated extensions. For example: h,asm")
|
||||
targetArch := flag.String("arch", runtime.GOARCH, "Target architecture. Defaults to OS architecture. Possible values: 386, amd64, wasm")
|
||||
output16bit := flag.Bool("i", false, "Compiled song should output 16-bit integers, instead of floats.")
|
||||
targetOs := flag.String("os", runtime.GOOS, "Target OS. Defaults to current OS. Possible values: windows, darwin, linux. Anything else is assumed linuxy. Ignored when targeting wasm.")
|
||||
versionFlag := flag.Bool("v", false, "Print version.")
|
||||
flag.Usage = printUsage
|
||||
flag.Parse()
|
||||
if *versionFlag {
|
||||
fmt.Println(version.VersionOrHash)
|
||||
os.Exit(0)
|
||||
}
|
||||
if (flag.NArg() == 0 && !*library) || *help {
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
compile := !*jsonOut && !*yamlOut // if the user gives nothing to output, then the default behaviour is to compile the file
|
||||
var comp *compiler.Compiler
|
||||
if compile || *library {
|
||||
var err error
|
||||
if *tmplDir != "" {
|
||||
comp, err = compiler.NewFromTemplates(*targetOs, *targetArch, *output16bit, *rowsync, *tmplDir)
|
||||
} else {
|
||||
comp, err = compiler.New(*targetOs, *targetArch, *output16bit, *rowsync)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, `error creating compiler: %v`, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
output := func(filename string, extension string, contents []byte) error {
|
||||
if *stdout {
|
||||
fmt.Print(string(contents))
|
||||
return nil
|
||||
}
|
||||
_, name := filepath.Split(filename)
|
||||
var dir string
|
||||
if *outPath != "" {
|
||||
// check if it's an already existing directory and the user just forgot trailing slash
|
||||
if info, err := os.Stat(*outPath); err == nil && info.IsDir() {
|
||||
dir = *outPath
|
||||
} else {
|
||||
outdir, outname := filepath.Split(*outPath)
|
||||
if outdir != "" {
|
||||
dir = outdir
|
||||
}
|
||||
if outname != "" {
|
||||
name = outname
|
||||
}
|
||||
}
|
||||
}
|
||||
if dir == "" {
|
||||
var err error
|
||||
dir, err = os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get working directory, specify the output directory explicitly: %v", err)
|
||||
}
|
||||
}
|
||||
name = strings.TrimSuffix(name, filepath.Ext(name)) + extension
|
||||
f := filepath.Join(dir, name)
|
||||
original, err := ioutil.ReadFile(f)
|
||||
if err == nil {
|
||||
if bytes.Compare(original, contents) == 0 {
|
||||
return nil // no need to update
|
||||
}
|
||||
if !*list && *safe {
|
||||
return fmt.Errorf("file %v would be overwritten by compiler", f)
|
||||
}
|
||||
}
|
||||
if *list {
|
||||
fmt.Println(f)
|
||||
} else {
|
||||
if dir != "" {
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("could not create output directory %v: %v", dir, err)
|
||||
}
|
||||
}
|
||||
err := ioutil.WriteFile(f, contents, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not write file %v: %v", f, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
process := func(filename string) error {
|
||||
inputBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read file %v: %v", filename, err)
|
||||
}
|
||||
var song sointu.Song
|
||||
if errJSON := json.Unmarshal(inputBytes, &song); errJSON != nil {
|
||||
if errYaml := yaml.Unmarshal(inputBytes, &song); errYaml != nil {
|
||||
return fmt.Errorf("song could not be unmarshaled as a .json (%v) or .yml (%v)", errJSON, errYaml)
|
||||
}
|
||||
}
|
||||
if song.RowsPerBeat == 0 {
|
||||
song.RowsPerBeat = 4
|
||||
}
|
||||
if song.Score.Length == 0 {
|
||||
song.Score.Length = len(song.Score.Tracks[0].Patterns)
|
||||
}
|
||||
var compiledPlayer map[string]string
|
||||
if compile {
|
||||
var err error
|
||||
compiledPlayer, err = comp.Song(&song)
|
||||
if err != nil {
|
||||
return fmt.Errorf("compiling player failed: %v", err)
|
||||
}
|
||||
if len(*extensionsOut) > 0 {
|
||||
compiledPlayer = filterExtensions(compiledPlayer, strings.Split(*extensionsOut, ","))
|
||||
}
|
||||
for extension, code := range compiledPlayer {
|
||||
if err := output(filename, extension, []byte(code)); err != nil {
|
||||
return fmt.Errorf("error outputting %v file: %v", extension, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if *jsonOut {
|
||||
jsonSong, err := json.Marshal(song)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not marshal the song as json file: %v", err)
|
||||
}
|
||||
if err := output(filename, ".json", jsonSong); err != nil {
|
||||
return fmt.Errorf("error outputting json file: %v", err)
|
||||
}
|
||||
}
|
||||
if *yamlOut {
|
||||
yamlSong, err := yaml.Marshal(song)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not marshal the song as yaml file: %v", err)
|
||||
}
|
||||
if err := output(filename, ".yml", yamlSong); err != nil {
|
||||
return fmt.Errorf("error outputting yaml file: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
retval := 0
|
||||
if *library {
|
||||
compiledLibrary, err := comp.Library()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "compiling library failed: %v\n", err)
|
||||
retval = 1
|
||||
} else {
|
||||
if len(*extensionsOut) > 0 {
|
||||
compiledLibrary = filterExtensions(compiledLibrary, strings.Split(*extensionsOut, ","))
|
||||
}
|
||||
for extension, code := range compiledLibrary {
|
||||
if err := output("sointu", extension, []byte(code)); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error outputting %v file: %v", extension, err)
|
||||
retval = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, param := range flag.Args() {
|
||||
if info, err := os.Stat(param); err == nil && info.IsDir() {
|
||||
jsonfiles, err := filepath.Glob(filepath.Join(param, "*.json"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not glob the path %v for json files: %v\n", param, err)
|
||||
retval = 1
|
||||
continue
|
||||
}
|
||||
ymlfiles, err := filepath.Glob(filepath.Join(param, "*.yml"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not glob the path %v for yml files: %v\n", param, err)
|
||||
retval = 1
|
||||
continue
|
||||
}
|
||||
files := append(ymlfiles, jsonfiles...)
|
||||
for _, file := range files {
|
||||
err := process(file)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not process file %v: %v\n", file, err)
|
||||
retval = 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := process(param)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not process file %v: %v\n", param, err)
|
||||
retval = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
os.Exit(retval)
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Fprintf(os.Stderr, "Sointu compiler. Input .yml or .json songs, outputs compiled songs (e.g. .asm and .h files).\nUsage: %s [flags] [path ...]\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
164
cmd/sointu-play/main.go
Normal file
164
cmd/sointu-play/main.go
Normal file
@ -0,0 +1,164 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/oto"
|
||||
"github.com/vsariola/sointu/version"
|
||||
"github.com/vsariola/sointu/vm/compiler/bridge"
|
||||
)
|
||||
|
||||
func main() {
|
||||
stdout := flag.Bool("s", false, "Do not write files; write to standard output instead.")
|
||||
help := flag.Bool("h", false, "Show help.")
|
||||
directory := flag.String("o", "", "Directory where to output all files. The directory and its parents are created if needed. By default, everything is placed in the same directory where the original song file is.")
|
||||
play := flag.Bool("p", false, "Play the input songs (default behaviour when no other output is defined).")
|
||||
//start := flag.Float64("start", 0, "Start playing from part; given in the units defined by parameter `unit`.")
|
||||
//stop := flag.Float64("stop", -1, "Stop playing at part; given in the units defined by parameter `unit`. Negative values indicate render until end.")
|
||||
//units := flag.String("unit", "pattern", "Units for parameters start and stop. Possible values: second, sample, pattern, beat. Warning: beat and pattern do not take SPEED modulations into account.")
|
||||
rawOut := flag.Bool("r", false, "Output the rendered song as .raw file. By default, saves stereo float32 buffer to disk.")
|
||||
wavOut := flag.Bool("w", false, "Output the rendered song as .wav file. By default, saves stereo float32 buffer to disk.")
|
||||
pcm := flag.Bool("c", false, "Convert audio to 16-bit signed PCM when outputting.")
|
||||
versionFlag := flag.Bool("v", false, "Print version.")
|
||||
flag.Usage = printUsage
|
||||
flag.Parse()
|
||||
if *versionFlag {
|
||||
fmt.Println(version.VersionOrHash)
|
||||
os.Exit(0)
|
||||
}
|
||||
if flag.NArg() == 0 || *help {
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
if !*rawOut && !*wavOut {
|
||||
*play = true // if the user gives nothing to output, then the default behaviour is just to play the file
|
||||
}
|
||||
var audioContext sointu.AudioContext
|
||||
if *play {
|
||||
var err error
|
||||
audioContext, err = oto.NewContext()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not acquire oto AudioContext: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer audioContext.Close()
|
||||
}
|
||||
process := func(filename string) error {
|
||||
output := func(extension string, contents []byte) error {
|
||||
if *stdout {
|
||||
fmt.Print(contents)
|
||||
return nil
|
||||
}
|
||||
_, name := filepath.Split(filename)
|
||||
var dir string
|
||||
if *directory != "" {
|
||||
dir = *directory
|
||||
}
|
||||
if dir == "" {
|
||||
var err error
|
||||
dir, err = os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get working directory, specify the output directory explicitly: %v", err)
|
||||
}
|
||||
}
|
||||
name = strings.TrimSuffix(name, filepath.Ext(name)) + extension
|
||||
f := filepath.Join(dir, name)
|
||||
if dir != "" {
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("could not create output directory %v: %v", dir, err)
|
||||
}
|
||||
}
|
||||
err := ioutil.WriteFile(f, contents, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not write file %v: %v", f, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
inputBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read file %v: %v", filename, err)
|
||||
}
|
||||
var song sointu.Song
|
||||
if errJSON := json.Unmarshal(inputBytes, &song); errJSON != nil {
|
||||
if errYaml := yaml.Unmarshal(inputBytes, &song); errYaml != nil {
|
||||
return fmt.Errorf("the song could not be parsed as .json (%v) or .yml (%v)", errJSON, errYaml)
|
||||
}
|
||||
}
|
||||
buffer, err := sointu.Play(bridge.NativeSynther{}, song, nil) // render the song to calculate its length
|
||||
if err != nil {
|
||||
return fmt.Errorf("sointu.Play failed: %v", err)
|
||||
}
|
||||
if *play {
|
||||
output := audioContext.Output()
|
||||
defer output.Close()
|
||||
if err := output.WriteAudio(buffer); err != nil {
|
||||
return fmt.Errorf("error playing: %v", err)
|
||||
}
|
||||
}
|
||||
if *rawOut {
|
||||
raw, err := buffer.Raw(*pcm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not generate .raw file: %v", err)
|
||||
}
|
||||
if err := output(".raw", raw); err != nil {
|
||||
return fmt.Errorf("error outputting .raw file: %v", err)
|
||||
}
|
||||
}
|
||||
if *wavOut {
|
||||
wav, err := buffer.Wav(*pcm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not generate .wav file: %v", err)
|
||||
}
|
||||
if err := output(".wav", wav); err != nil {
|
||||
return fmt.Errorf("error outputting .wav file: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
retval := 0
|
||||
for _, param := range flag.Args() {
|
||||
if info, err := os.Stat(param); err == nil && info.IsDir() {
|
||||
jsonfiles, err := filepath.Glob(filepath.Join(param, "*.json"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not glob the path %v for json files: %v\n", param, err)
|
||||
retval = 1
|
||||
continue
|
||||
}
|
||||
ymlfiles, err := filepath.Glob(filepath.Join(param, "*.yml"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not glob the path %v for yml files: %v\n", param, err)
|
||||
retval = 1
|
||||
continue
|
||||
}
|
||||
files := append(ymlfiles, jsonfiles...)
|
||||
for _, file := range files {
|
||||
err := process(file)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not process file %v: %v\n", file, err)
|
||||
retval = 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := process(param)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not process file %v: %v\n", param, err)
|
||||
retval = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
os.Exit(retval)
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Fprintf(os.Stderr, "Sointu command line utility for playing .asm/.json song files.\nUsage: %s [flags] [path ...]\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
104
cmd/sointu-track/main.go
Normal file
104
cmd/sointu-track/main.go
Normal file
@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
|
||||
"gioui.org/app"
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/cmd"
|
||||
"github.com/vsariola/sointu/oto"
|
||||
"github.com/vsariola/sointu/tracker"
|
||||
"github.com/vsariola/sointu/tracker/gioui"
|
||||
)
|
||||
|
||||
type NullContext struct {
|
||||
}
|
||||
|
||||
func (NullContext) NextEvent() (event tracker.MIDINoteEvent, ok bool) {
|
||||
return tracker.MIDINoteEvent{}, false
|
||||
}
|
||||
|
||||
func (NullContext) BPM() (bpm float64, ok bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (NullContext) Params() (ret tracker.ExtValueArray, ok bool) {
|
||||
return tracker.ExtValueArray{}, false
|
||||
}
|
||||
|
||||
func (NullContext) SetParams(params tracker.ExtParamArray) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
||||
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
var f *os.File
|
||||
if *cpuprofile != "" {
|
||||
var err error
|
||||
f, err = os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create CPU profile: ", err)
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
}
|
||||
}
|
||||
audioContext, err := oto.NewContext()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer audioContext.Close()
|
||||
recoveryFile := ""
|
||||
if configDir, err := os.UserConfigDir(); err == nil {
|
||||
recoveryFile = filepath.Join(configDir, "Sointu", "sointu-track-recovery")
|
||||
}
|
||||
model, player := tracker.NewModelPlayer(cmd.MainSynther, recoveryFile)
|
||||
if a := flag.Args(); len(a) > 0 {
|
||||
f, err := os.Open(a[0])
|
||||
if err == nil {
|
||||
model.ReadSong(f)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
tracker := gioui.NewTracker(model)
|
||||
output := audioContext.Output()
|
||||
defer output.Close()
|
||||
go func() {
|
||||
buf := make(sointu.AudioBuffer, 1024)
|
||||
ctx := NullContext{}
|
||||
for {
|
||||
player.Process(buf, ctx)
|
||||
output.WriteAudio(buf)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
tracker.Main()
|
||||
if *cpuprofile != "" {
|
||||
pprof.StopCPUProfile()
|
||||
f.Close()
|
||||
}
|
||||
if *memprofile != "" {
|
||||
f, err := os.Create(*memprofile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create memory profile: ", err)
|
||||
}
|
||||
defer f.Close() // error handling omitted for example
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
log.Fatal("could not write memory profile: ", err)
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
app.Main()
|
||||
}
|
||||
186
cmd/sointu-vsti/main.go
Normal file
186
cmd/sointu-vsti/main.go
Normal file
@ -0,0 +1,186 @@
|
||||
//go:build plugin
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/cmd"
|
||||
"github.com/vsariola/sointu/tracker"
|
||||
"github.com/vsariola/sointu/tracker/gioui"
|
||||
"pipelined.dev/audio/vst2"
|
||||
)
|
||||
|
||||
type VSTIProcessContext struct {
|
||||
events []vst2.MIDIEvent
|
||||
eventIndex int
|
||||
host vst2.Host
|
||||
parameters []*vst2.Parameter
|
||||
}
|
||||
|
||||
func (c *VSTIProcessContext) NextEvent() (event tracker.MIDINoteEvent, ok bool) {
|
||||
for c.eventIndex < len(c.events) {
|
||||
ev := c.events[c.eventIndex]
|
||||
c.eventIndex++
|
||||
switch {
|
||||
case ev.Data[0] >= 0x80 && ev.Data[0] < 0x90:
|
||||
channel := ev.Data[0] - 0x80
|
||||
note := ev.Data[1]
|
||||
return tracker.MIDINoteEvent{Frame: int(ev.DeltaFrames), On: false, Channel: int(channel), Note: note}, true
|
||||
case ev.Data[0] >= 0x90 && ev.Data[0] < 0xA0:
|
||||
channel := ev.Data[0] - 0x90
|
||||
note := ev.Data[1]
|
||||
return tracker.MIDINoteEvent{Frame: int(ev.DeltaFrames), On: true, Channel: int(channel), Note: note}, true
|
||||
default:
|
||||
// ignore all other MIDI messages
|
||||
}
|
||||
}
|
||||
return tracker.MIDINoteEvent{}, false
|
||||
}
|
||||
|
||||
func (c *VSTIProcessContext) BPM() (bpm float64, ok bool) {
|
||||
timeInfo := c.host.GetTimeInfo(vst2.TempoValid)
|
||||
if timeInfo == nil || timeInfo.Flags&vst2.TempoValid == 0 || timeInfo.Tempo == 0 {
|
||||
return 0, false
|
||||
}
|
||||
return timeInfo.Tempo, true
|
||||
}
|
||||
|
||||
func (c *VSTIProcessContext) Params() (ret tracker.ExtValueArray, ok bool) {
|
||||
for i, p := range c.parameters {
|
||||
ret[i] = p.Value
|
||||
}
|
||||
return ret, true
|
||||
}
|
||||
|
||||
func (c *VSTIProcessContext) SetParams(a tracker.ExtParamArray) bool {
|
||||
changed := false
|
||||
for i, p := range c.parameters {
|
||||
i := i
|
||||
name := a[i].Param.Name
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("P%d", i)
|
||||
}
|
||||
if p.Value != a[i].Val || p.Name != name {
|
||||
p.Value = a[i].Val
|
||||
p.Name = name
|
||||
p.GetValueFunc = func(value float32) float32 {
|
||||
return float32(a[i].Param.MinValue) + value*float32(a[i].Param.MaxValue-a[i].Param.MinValue)
|
||||
}
|
||||
p.GetValueLabelFunc = func(v float32) string {
|
||||
if f := a[i].Param.DisplayFunc; f != nil {
|
||||
s, u := a[i].Param.DisplayFunc(int(v + .5))
|
||||
c.parameters[i].Unit = u
|
||||
return s
|
||||
}
|
||||
c.parameters[i].Unit = ""
|
||||
return strconv.Itoa(int(v + .5))
|
||||
}
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
c.host.UpdateDisplay()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
var (
|
||||
version = int32(100)
|
||||
)
|
||||
vst2.PluginAllocator = func(h vst2.Host) (vst2.Plugin, vst2.Dispatcher) {
|
||||
recoveryFile := ""
|
||||
if configDir, err := os.UserConfigDir(); err == nil {
|
||||
randBytes := make([]byte, 16)
|
||||
rand.Read(randBytes)
|
||||
recoveryFile = filepath.Join(configDir, "sointu", "sointu-vsti-recovery-"+hex.EncodeToString(randBytes))
|
||||
}
|
||||
model, player := tracker.NewModelPlayer(cmd.MainSynther, recoveryFile)
|
||||
t := gioui.NewTracker(model)
|
||||
tracker.Bool{BoolData: (*tracker.InstrEnlarged)(model)}.Set(true)
|
||||
if s := h.GetSampleRate(); math.Abs(float64(h.GetSampleRate()-44100.0)) > 1e-6 {
|
||||
model.Alerts().AddAlert(tracker.Alert{
|
||||
Message: fmt.Sprintf("VSTi host sample rate is %.0f Hz; sointu supports 44100 Hz only", s),
|
||||
Priority: tracker.Error,
|
||||
Duration: 10 * time.Second,
|
||||
})
|
||||
}
|
||||
go t.Main()
|
||||
parameters := make([]*vst2.Parameter, 0, tracker.ExtParamCount)
|
||||
for i := 0; i < tracker.ExtParamCount; i++ {
|
||||
parameters = append(parameters,
|
||||
&vst2.Parameter{
|
||||
Name: fmt.Sprintf("P%d", i),
|
||||
NotAutomated: true,
|
||||
})
|
||||
}
|
||||
context := VSTIProcessContext{host: h, parameters: parameters}
|
||||
buf := make(sointu.AudioBuffer, 1024)
|
||||
return vst2.Plugin{
|
||||
UniqueID: PLUGIN_ID,
|
||||
Version: version,
|
||||
InputChannels: 0,
|
||||
OutputChannels: 2,
|
||||
Name: PLUGIN_NAME,
|
||||
Vendor: "vsariola/sointu",
|
||||
Category: vst2.PluginCategorySynth,
|
||||
Flags: vst2.PluginIsSynth,
|
||||
Parameters: parameters,
|
||||
ProcessFloatFunc: func(in, out vst2.FloatBuffer) {
|
||||
left := out.Channel(0)
|
||||
right := out.Channel(1)
|
||||
if len(buf) < out.Frames {
|
||||
buf = append(buf, make(sointu.AudioBuffer, out.Frames-len(buf))...)
|
||||
}
|
||||
buf = buf[:out.Frames]
|
||||
player.Process(buf, &context)
|
||||
for i := 0; i < out.Frames; i++ {
|
||||
left[i], right[i] = buf[i][0], buf[i][1]
|
||||
}
|
||||
context.events = context.events[:0] // reset buffer, but keep the allocated memory
|
||||
context.eventIndex = 0
|
||||
},
|
||||
}, vst2.Dispatcher{
|
||||
CanDoFunc: func(pcds vst2.PluginCanDoString) vst2.CanDoResponse {
|
||||
switch pcds {
|
||||
case vst2.PluginCanReceiveEvents, vst2.PluginCanReceiveMIDIEvent, vst2.PluginCanReceiveTimeInfo:
|
||||
return vst2.YesCanDo
|
||||
}
|
||||
return vst2.NoCanDo
|
||||
},
|
||||
ProcessEventsFunc: func(ev *vst2.EventsPtr) {
|
||||
for i := 0; i < ev.NumEvents(); i++ {
|
||||
a := ev.Event(i)
|
||||
switch v := a.(type) {
|
||||
case *vst2.MIDIEvent:
|
||||
context.events = append(context.events, *v)
|
||||
}
|
||||
}
|
||||
},
|
||||
CloseFunc: func() {
|
||||
t.Exec() <- func() { t.ForceQuit().Do() }
|
||||
t.WaitQuitted()
|
||||
},
|
||||
GetChunkFunc: func(isPreset bool) []byte {
|
||||
retChn := make(chan []byte)
|
||||
t.Exec() <- func() { retChn <- t.MarshalRecovery() }
|
||||
return <-retChn
|
||||
},
|
||||
SetChunkFunc: func(data []byte, isPreset bool) {
|
||||
t.Exec() <- func() { t.UnmarshalRecovery(data) }
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func main() {}
|
||||
6
cmd/sointu-vsti/nameid_native.go
Normal file
6
cmd/sointu-vsti/nameid_native.go
Normal file
@ -0,0 +1,6 @@
|
||||
//go:build native
|
||||
|
||||
package main
|
||||
|
||||
var PLUGIN_ID = [4]byte{'S', 'n', 't', 'N'}
|
||||
var PLUGIN_NAME = "Sointu Native"
|
||||
6
cmd/sointu-vsti/nameid_not_native.go
Normal file
6
cmd/sointu-vsti/nameid_not_native.go
Normal file
@ -0,0 +1,6 @@
|
||||
//go:build !native
|
||||
|
||||
package main
|
||||
|
||||
var PLUGIN_ID = [4]byte{'S', 'n', 't', 'u'}
|
||||
var PLUGIN_NAME = "Sointu"
|
||||
1
examples/CMakeLists.txt
Normal file
1
examples/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory(code)
|
||||
68
examples/code/C/CMakeLists.txt
Normal file
68
examples/code/C/CMakeLists.txt
Normal file
@ -0,0 +1,68 @@
|
||||
# this fixes a bug in creating a static library from asm, similar to
|
||||
# https://discourse.cmake.org/t/building-lib-file-from-asm-cmake-bug/1959
|
||||
# but for NASM
|
||||
if(MSVC)
|
||||
set(CMAKE_ASM_NASM_CREATE_STATIC_LIBRARY "<CMAKE_AR> /OUT:<TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
COMMAND
|
||||
${compilecmd} -arch=${arch} -o physics_girl_st.asm "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml"
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
"${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml"
|
||||
${compilecmd}
|
||||
OUTPUT
|
||||
physics_girl_st.asm
|
||||
physics_girl_st.h
|
||||
physics_girl_st.inc
|
||||
COMMENT
|
||||
"Compiling ${PROJECT_SOURCE_DIR}/examples/patches/physics-girl-st.yml..."
|
||||
)
|
||||
|
||||
add_library(physics_girl_st physics_girl_st.asm)
|
||||
|
||||
if(WIN32)
|
||||
add_executable(cplay-winmm
|
||||
cplay.windows.winmm.c
|
||||
physics_girl_st.h
|
||||
)
|
||||
target_link_libraries(cplay-winmm PRIVATE winmm)
|
||||
target_link_libraries(cplay-winmm PRIVATE physics_girl_st)
|
||||
target_include_directories(cplay-winmm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(examples cplay-winmm)
|
||||
|
||||
add_executable(cplay-directsound
|
||||
cplay.windows.directsound.c
|
||||
physics_girl_st.h
|
||||
)
|
||||
target_link_libraries(cplay-directsound PRIVATE dsound ws2_32 ucrt)
|
||||
target_link_libraries(cplay-directsound PRIVATE physics_girl_st)
|
||||
target_include_directories(cplay-directsound PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(examples cplay-directsound)
|
||||
elseif(UNIX)
|
||||
add_executable(cplay
|
||||
cplay.unix.c
|
||||
physics_girl_st.h
|
||||
)
|
||||
target_link_libraries(cplay PRIVATE asound pthread)
|
||||
target_link_options(cplay PRIVATE -z noexecstack -no-pie)
|
||||
target_link_libraries(cplay PRIVATE physics_girl_st)
|
||||
target_include_directories(cplay PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(examples cplay)
|
||||
endif()
|
||||
|
||||
add_executable(cwav
|
||||
cwav.c
|
||||
physics_girl_st.h
|
||||
)
|
||||
if(WIN32)
|
||||
target_compile_definitions(cwav PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
elseif(UNIX)
|
||||
target_link_options(cwav PRIVATE -z noexecstack -no-pie)
|
||||
endif()
|
||||
target_link_libraries(cwav PRIVATE physics_girl_st)
|
||||
target_include_directories(cwav PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_dependencies(examples cwav)
|
||||
39
examples/code/C/cplay.unix.c
Normal file
39
examples/code/C/cplay.unix.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "physics_girl_st.h"
|
||||
|
||||
static SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
|
||||
static snd_pcm_t *pcm_handle;
|
||||
static pthread_t render_thread;
|
||||
static uint32_t render_thread_handle;
|
||||
|
||||
int main(int argc, char **args) {
|
||||
// Unix does not have gm.dls, no need to ifdef and setup here.
|
||||
|
||||
// We render in the background while playing already.
|
||||
render_thread_handle = pthread_create(&render_thread, 0, (void * (*)(void *))su_render_song, sound_buffer);
|
||||
|
||||
// We can't start playing too early or the missing samples will be audible.
|
||||
sleep(2.);
|
||||
|
||||
// Play the track.
|
||||
snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
||||
snd_pcm_set_params(
|
||||
pcm_handle,
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
SND_PCM_FORMAT_FLOAT,
|
||||
#else // SU_SAMPLE_FLOAT
|
||||
SND_PCM_FORMAT_S16_LE,
|
||||
#endif // SU_SAMPLE_FLOAT
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_RATE,
|
||||
0,
|
||||
SU_LENGTH_IN_SAMPLES
|
||||
);
|
||||
snd_pcm_writei(pcm_handle, sound_buffer, SU_LENGTH_IN_SAMPLES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
75
examples/code/C/cplay.windows.directsound.c
Normal file
75
examples/code/C/cplay.windows.directsound.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "physics_girl_st.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#include <Windows.h>
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#define CINTERFACE
|
||||
#include <dsound.h>
|
||||
|
||||
#ifndef DSBCAPS_TRUEPLAYPOSITION // Not defined in MinGW dsound headers, so let's add it
|
||||
#define DSBCAPS_TRUEPLAYPOSITION 0x00080000
|
||||
#endif
|
||||
|
||||
SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
|
||||
WAVEFORMATEX wave_format = {
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
WAVE_FORMAT_IEEE_FLOAT,
|
||||
#else
|
||||
WAVE_FORMAT_PCM,
|
||||
#endif
|
||||
SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_RATE,
|
||||
SU_SAMPLE_RATE * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE*8,
|
||||
0
|
||||
};
|
||||
DSBUFFERDESC buffer_description = {
|
||||
sizeof(DSBUFFERDESC),
|
||||
DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_TRUEPLAYPOSITION,
|
||||
SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
0,
|
||||
&wave_format,
|
||||
0
|
||||
};
|
||||
|
||||
int main(int argc, char **args) {
|
||||
// Load gm.dls if necessary.
|
||||
#ifdef SU_LOAD_GMDLS
|
||||
su_load_gmdls();
|
||||
#endif // SU_LOAD_GMDLS
|
||||
|
||||
HWND hWnd = GetForegroundWindow();
|
||||
if(hWnd == NULL) {
|
||||
hWnd = GetDesktopWindow();
|
||||
}
|
||||
|
||||
LPDIRECTSOUND direct_sound;
|
||||
LPDIRECTSOUNDBUFFER direct_sound_buffer;
|
||||
DirectSoundCreate(0, &direct_sound, 0);
|
||||
IDirectSound_SetCooperativeLevel(direct_sound, hWnd, DSSCL_PRIORITY);
|
||||
IDirectSound_CreateSoundBuffer(direct_sound, &buffer_description, &direct_sound_buffer, NULL);
|
||||
|
||||
LPVOID p1;
|
||||
DWORD l1;
|
||||
IDirectSoundBuffer_Lock(direct_sound_buffer, 0, SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT * SU_SAMPLE_SIZE, &p1, &l1, NULL, NULL, 0);
|
||||
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)su_render_song, p1, 0, 0);
|
||||
IDirectSoundBuffer_Play(direct_sound_buffer, 0, 0, 0);
|
||||
|
||||
// We need to handle windows messages properly while playing, as waveOutWrite is async.
|
||||
MSG msg = {0};
|
||||
DWORD last_play_cursor = 0;
|
||||
for(DWORD play_cursor = 0; play_cursor >= last_play_cursor; IDirectSoundBuffer_GetCurrentPosition(direct_sound_buffer, (DWORD*)&play_cursor, NULL)) {
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
last_play_cursor = play_cursor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
63
examples/code/C/cplay.windows.winmm.c
Normal file
63
examples/code/C/cplay.windows.winmm.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "physics_girl_st.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#include <Windows.h>
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
|
||||
SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
|
||||
HWAVEOUT wave_out_handle;
|
||||
WAVEFORMATEX wave_format = {
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
WAVE_FORMAT_IEEE_FLOAT,
|
||||
#else
|
||||
WAVE_FORMAT_PCM,
|
||||
#endif
|
||||
SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_RATE,
|
||||
SU_SAMPLE_RATE * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE*8,
|
||||
0
|
||||
};
|
||||
WAVEHDR wave_header = {
|
||||
(LPSTR)sound_buffer,
|
||||
SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
0,
|
||||
0,
|
||||
WHDR_PREPARED,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
MMTIME mmtime = {
|
||||
TIME_SAMPLES,
|
||||
0
|
||||
};
|
||||
|
||||
int main(int argc, char **args) {
|
||||
// Load gm.dls if necessary.
|
||||
#ifdef SU_LOAD_GMDLS
|
||||
su_load_gmdls();
|
||||
#endif // SU_LOAD_GMDLS
|
||||
|
||||
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)su_render_song, sound_buffer, 0, 0);
|
||||
|
||||
// We render in the background while playing already. Fortunately,
|
||||
// Windows is slow with the calls below, so we're not worried that
|
||||
// we don't have enough samples ready before the track starts.
|
||||
waveOutOpen(&wave_out_handle, WAVE_MAPPER, &wave_format, 0, 0, CALLBACK_NULL);
|
||||
waveOutWrite(wave_out_handle, &wave_header, sizeof(wave_header));
|
||||
|
||||
// We need to handle windows messages properly while playing, as waveOutWrite is async.
|
||||
for(MSG msg = {0}; mmtime.u.sample != SU_LENGTH_IN_SAMPLES; waveOutGetPosition(wave_out_handle, &mmtime, sizeof(MMTIME))) {
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
examples/code/C/cwav.c
Normal file
72
examples/code/C/cwav.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "physics_girl_st.h"
|
||||
|
||||
#define WAVE_FORMAT_PCM 0x1
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x3
|
||||
|
||||
static SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
char riff[4];
|
||||
uint32_t file_size;
|
||||
char wavefmt[8];
|
||||
} riff_header_t;
|
||||
|
||||
typedef struct {
|
||||
char data[4];
|
||||
uint32_t data_size;
|
||||
} data_header_t;
|
||||
|
||||
typedef struct {
|
||||
riff_header_t riff_header;
|
||||
uint32_t riff_header_size;
|
||||
uint16_t sample_type;
|
||||
uint16_t channel_count;
|
||||
uint32_t sample_rate;
|
||||
uint32_t bytes_per_second;
|
||||
uint16_t bytes_per_channel;
|
||||
uint16_t bits_per_sample;
|
||||
data_header_t data_header;
|
||||
} wave_header_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
int main(int argc, char **args) {
|
||||
wave_header_t wave_header = {
|
||||
.riff_header = (riff_header_t) {
|
||||
.riff = "RIFF",
|
||||
.file_size = sizeof(wave_header_t) + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
.wavefmt = "WAVEfmt ",
|
||||
},
|
||||
.riff_header_size = sizeof(riff_header_t),
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
.sample_type = WAVE_FORMAT_IEEE_FLOAT,
|
||||
#else // SU_SAMPLE_FLOAT
|
||||
.sample_type = WAVE_FORMAT_PCM,
|
||||
#endif // SU_SAMPLE_FLOAT
|
||||
.channel_count = SU_CHANNEL_COUNT,
|
||||
.sample_rate = SU_SAMPLE_RATE,
|
||||
.bytes_per_second = SU_SAMPLE_SIZE * SU_SAMPLE_RATE * SU_CHANNEL_COUNT,
|
||||
.bytes_per_channel = SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
.bits_per_sample = SU_SAMPLE_SIZE * 8,
|
||||
.data_header = (data_header_t) {
|
||||
.data = "data",
|
||||
.data_size = sizeof(data_header_t) + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
}
|
||||
};
|
||||
|
||||
// Load gm.dls if necessary.
|
||||
#ifdef SU_LOAD_GMDLS
|
||||
su_load_gmdls();
|
||||
#endif // SU_LOAD_GMDLS
|
||||
|
||||
su_render_song(sound_buffer);
|
||||
|
||||
FILE *file = fopen("physics_girl_st.wav", "wb");
|
||||
fwrite(&wave_header, sizeof(wave_header_t), 1, file);
|
||||
fwrite((uint8_t *)sound_buffer, 1, SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT, file);
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
34
examples/code/CMakeLists.txt
Normal file
34
examples/code/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
if(("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") AND MSVC)
|
||||
# in 32-bit mode with MSVC toolset, we can use Crinkler to compress the executable
|
||||
set(CRINKLER_LEVEL "off" CACHE STRING "Crinkler compression level: off, light, medium, heavy")
|
||||
|
||||
if(NOT CRINKLER_LEVEL STREQUAL OFF)
|
||||
find_program(CRINKLER NAMES Crinkler)
|
||||
if (NOT CRINKLER)
|
||||
message(WARNING "Crinkler not found. Cannot compress executable; using default linker. Get Crinkler from https://github.com/runestubbe/Crinkler & put it in path (as Crinkler.exe)")
|
||||
set(CRINKLER_LEVEL OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT CRINKLER_LEVEL STREQUAL OFF)
|
||||
message(STATUS "Crinkler found at: ${CRINKLER}")
|
||||
set(CRINKLER_FLAGS "/PROGRESSGUI /UNSAFEIMPORT /UNALIGNCODE /HASHSIZE:1000 /REPORT:<TARGET>.report.html")
|
||||
# TBD: do we add /SATURATE
|
||||
if (CRINKLER_LEVEL STREQUAL LIGHT)
|
||||
set(CRINKLER_FLAGS "${CRINKLER_FLAGS} /HASHTRIES:100 /COMPMODE:INSTANT /ORDERTRIES:2000")
|
||||
elseif (CRINKLER_LEVEL STREQUAL HEAVY)
|
||||
set(CRINKLER_FLAGS "${CRINKLER_FLAGS} /HASHTRIES:1000 /COMPMODE:VERYSLOW /ORDERTRIES:30000")
|
||||
else()
|
||||
set(CRINKLER_FLAGS "${CRINKLER_FLAGS} /HASHTRIES:300 /COMPMODE:SLOW /ORDERTRIES:9000")
|
||||
endif()
|
||||
|
||||
# we drop the whole manifest creation from the front; did not find a way to disable it from CMake otherwise
|
||||
set (CMAKE_C_LINK_EXECUTABLE "${CRINKLER} <OBJECTS> /out:<TARGET> ${CRINKLER_FLAGS} <LINK_LIBRARIES>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
add_custom_target(examples)
|
||||
|
||||
add_subdirectory(asm)
|
||||
add_subdirectory(C)
|
||||
7
examples/code/Python/.gitignore
vendored
Normal file
7
examples/code/Python/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.venv
|
||||
build
|
||||
dist
|
||||
__pycache__
|
||||
setup.py
|
||||
*.egg-info
|
||||
*.so
|
||||
18
examples/code/Python/README.md
Normal file
18
examples/code/Python/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Embed Sointu in Python
|
||||
This is an example for embedding Sointu into Python code.
|
||||
|
||||
# Configure the track
|
||||
Edit the `track` variable in `build.py` according to your needs.
|
||||
|
||||
# Build
|
||||
* Install Python 3.11 and poetry.
|
||||
* Download nasm and golang; place both of them in your system `PATH`.
|
||||
* Enable cgo by downloading a gcc and placing it into your system `PATH`.
|
||||
* Get the dependencies with `poetry install`.
|
||||
* Run the player using `poetry run python -m sointu_python`.
|
||||
* Pack everything into an executable using `poetry run pyinstaller sointu_python/sointu_python.spec`. The executable will be built in the `dist` subfolder.
|
||||
|
||||
# Rebuild after changes
|
||||
* Rebuild the example track bindings with `poetry build`.
|
||||
* Update the bindings module with `poetry install`.
|
||||
* Proceed iteration.
|
||||
149
examples/code/Python/build.py
Normal file
149
examples/code/Python/build.py
Normal file
@ -0,0 +1,149 @@
|
||||
from distutils.command.build_ext import build_ext
|
||||
from distutils.errors import (
|
||||
CCompilerError,
|
||||
DistutilsExecError,
|
||||
DistutilsPlatformError,
|
||||
)
|
||||
from distutils.core import Extension
|
||||
from os.path import (
|
||||
dirname,
|
||||
join,
|
||||
abspath,
|
||||
exists,
|
||||
basename,
|
||||
splitext,
|
||||
)
|
||||
from os import mkdir
|
||||
from subprocess import run
|
||||
from platform import system
|
||||
from sys import exit
|
||||
|
||||
track = "../../patches/physics_girl_st.yml"
|
||||
|
||||
class BuildFailed(Exception):
|
||||
pass
|
||||
|
||||
class ExtBuilder(build_ext):
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
build_ext.run(self)
|
||||
except (DistutilsPlatformError, FileNotFoundError):
|
||||
raise BuildFailed('File not found. Could not compile C extension.')
|
||||
|
||||
def build_extension(self, ext):
|
||||
try:
|
||||
build_ext.build_extension(self, ext)
|
||||
except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError):
|
||||
raise BuildFailed('Could not compile C extension.')
|
||||
|
||||
def build(setup_kwargs):
|
||||
# Make sure the build directory exists and setup the
|
||||
# relative paths correctly.
|
||||
cwd = abspath(".")
|
||||
print("Running from:", cwd)
|
||||
|
||||
current_source_dir = abspath(dirname(__file__))
|
||||
project_source_dir = abspath(join(current_source_dir, "..", "..", ".."))
|
||||
current_binary_dir = join(current_source_dir, 'build')
|
||||
if not exists(current_binary_dir):
|
||||
mkdir(current_binary_dir)
|
||||
host_is_windows = system() == "Windows"
|
||||
executable_suffix = ".exe" if host_is_windows else ""
|
||||
object_suffix = ".obj" if host_is_windows else ".o"
|
||||
|
||||
# Build the sointu compiler first.
|
||||
compiler_executable = join(current_binary_dir, "sointu-compile{}".format(executable_suffix))
|
||||
result = run(
|
||||
args=[
|
||||
"go", "build",
|
||||
"-o", compiler_executable,
|
||||
"cmd/sointu-compile/main.go",
|
||||
],
|
||||
cwd=project_source_dir,
|
||||
shell=True if host_is_windows else False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print("sointu-compile build process exited with:", result.returncode)
|
||||
print(result.stdout)
|
||||
exit(1)
|
||||
|
||||
track_file_name = abspath(join(current_source_dir, track))
|
||||
(track_name_base, _) = splitext(basename(track_file_name))
|
||||
print("Compiling track:", track_file_name)
|
||||
|
||||
# Compile the track.
|
||||
sointu_compiler_arch = "amd64"
|
||||
track_asm_file = join(current_binary_dir, '{}.asm'.format(track_name_base))
|
||||
result = run(
|
||||
args=[
|
||||
compiler_executable,
|
||||
"-o", track_asm_file,
|
||||
"-arch={}".format(sointu_compiler_arch),
|
||||
track_file_name,
|
||||
],
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print("sointu-compile process exited with:", result.returncode)
|
||||
print(result.stdout)
|
||||
exit(1)
|
||||
|
||||
# Assemble the track.
|
||||
nasm_abi = "Win64" if host_is_windows else "Elf64"
|
||||
track_object_file = join(current_binary_dir, '{}{}'.format(track_name_base, object_suffix))
|
||||
print("Assembling track asm source:", track_asm_file)
|
||||
result = run(
|
||||
args=[
|
||||
'nasm',
|
||||
'-o', track_object_file,
|
||||
'-f', nasm_abi,
|
||||
track_asm_file,
|
||||
],
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print("nasm process exited with:", result.returncode)
|
||||
print(result.stdout)
|
||||
exit(1)
|
||||
|
||||
# Export the plugin.
|
||||
print("Linking object file into Python extension module:", track_object_file)
|
||||
setup_kwargs.update({
|
||||
"ext_modules": [
|
||||
Extension(
|
||||
"sointu",
|
||||
include_dirs=[
|
||||
current_binary_dir,
|
||||
current_source_dir,
|
||||
],
|
||||
sources=[
|
||||
"sointu.c",
|
||||
],
|
||||
extra_compile_args=[
|
||||
"-DTRACK_HEADER=\"{}.h\"".format(track_name_base),
|
||||
] + ([
|
||||
"-DWIN32",
|
||||
] if host_is_windows else [
|
||||
"-DUNIX",
|
||||
"-fPIC",
|
||||
]),
|
||||
extra_objects=[
|
||||
track_object_file,
|
||||
],
|
||||
extra_link_args=[
|
||||
"dsound.lib",
|
||||
"ws2_32.lib",
|
||||
"ucrt.lib",
|
||||
"user32.lib",
|
||||
] if host_is_windows else [
|
||||
"-z", "noexecstack",
|
||||
"--no-pie",
|
||||
"-lasound",
|
||||
"-lpthread",
|
||||
"-lpython3.11",
|
||||
],
|
||||
),
|
||||
],
|
||||
"cmdclass": {
|
||||
"build_ext": ExtBuilder,
|
||||
},
|
||||
})
|
||||
132
examples/code/Python/poetry.lock
generated
Normal file
132
examples/code/Python/poetry.lock
generated
Normal file
@ -0,0 +1,132 @@
|
||||
# This file is automatically @generated by Poetry and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.4"
|
||||
description = "Python graph (network) package"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
|
||||
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macholib"
|
||||
version = "1.16.3"
|
||||
description = "Mach-O header analysis and editing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
|
||||
{file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
altgraph = ">=0.17"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pefile"
|
||||
version = "2023.2.7"
|
||||
description = "Python PE parsing module"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
files = [
|
||||
{file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"},
|
||||
{file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller"
|
||||
version = "6.0.0"
|
||||
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "<3.13,>=3.8"
|
||||
files = [
|
||||
{file = "pyinstaller-6.0.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d84b06fb9002109bfc542e76860b81459a8585af0bbdabcfc5dcf272ef230de7"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa922d1d73881d0820a341d2c406a571cc94630bdcdc275427c844a12e6e376e"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:52e5b3a2371d7231de17515c7c78d8d4a39d70c8c095e71d55b3b83434a193a8"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4a75bde5cda259bb31f2294960d75b9d5c148001b2b0bd20a91f9c2116675a6c"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:5314f6f08d2bcbc031778618ba97d9098d106119c2e616b3b081171fe42f5415"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0ad7cc3776ca17d0bededcc352cba2b1c89eb4817bfabaf05972b9da8c424935"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:cccdad6cfe7a5db7d7eb8df2e5678f8375268739d5933214e180da300aa54e37"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:fb6af82989dac7c58bd25ed9ba3323bc443f8c1f03804f69c9f5e363bf4a021c"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-win32.whl", hash = "sha256:68769f5e6722474bb1038e35560444659db8b951388bfe0c669bb52a640cd0eb"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-win_amd64.whl", hash = "sha256:438a9e0d72a57d5bba4f112d256e39ea4033c76c65414c0693d8311faa14b090"},
|
||||
{file = "pyinstaller-6.0.0-py3-none-win_arm64.whl", hash = "sha256:16a473065291dd7879bf596fa20e65bd9d1e8aafc2cef1bffa3e42e707e2e68e"},
|
||||
{file = "pyinstaller-6.0.0.tar.gz", hash = "sha256:d702cff041f30e7a53500b630e07b081e5328d4655023319253d73935e75ade2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
altgraph = "*"
|
||||
macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
|
||||
packaging = ">=20.0"
|
||||
pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""}
|
||||
pyinstaller-hooks-contrib = ">=2021.4"
|
||||
pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""}
|
||||
setuptools = ">=42.0.0"
|
||||
|
||||
[package.extras]
|
||||
hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller-hooks-contrib"
|
||||
version = "2023.9"
|
||||
description = "Community maintained hooks for PyInstaller"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pyinstaller-hooks-contrib-2023.9.tar.gz", hash = "sha256:76084b5988e3957a9df169d2a935d65500136967e710ddebf57263f1a909cd80"},
|
||||
{file = "pyinstaller_hooks_contrib-2023.9-py2.py3-none-any.whl", hash = "sha256:f34f4c6807210025c8073ebe665f422a3aa2ac5f4c7ebf4c2a26cc77bebf63b5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywin32-ctypes"
|
||||
version = "0.2.2"
|
||||
description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
|
||||
{file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "68.2.2"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
|
||||
{file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.11,<3.13"
|
||||
content-hash = "797bde9c30c55b3ddb24b1d3eceedd093d8a89eb934e6fe8fe7191dc9247224d"
|
||||
27
examples/code/Python/pyproject.toml
Normal file
27
examples/code/Python/pyproject.toml
Normal file
@ -0,0 +1,27 @@
|
||||
[tool.poetry]
|
||||
name = "sointu-python"
|
||||
version = "0.1.0"
|
||||
description = "Play back Sointu tracks in Python."
|
||||
authors = ["Alexander Kraus <nr4@z10.info>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
packages = [
|
||||
{ include = "sointu_python" },
|
||||
]
|
||||
include = [
|
||||
{ path = "sointu*.so", format="wheel" }
|
||||
]
|
||||
|
||||
[tool.poetry.build]
|
||||
script = "build.py"
|
||||
generate-setup-file = true
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.11,<3.13"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pyinstaller = "^6.0.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0a3", "poetry>=0.12", "setuptools", "wheel"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
212
examples/code/Python/sointu.c
Normal file
212
examples/code/Python/sointu.c
Normal file
@ -0,0 +1,212 @@
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
|
||||
#include TRACK_HEADER
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#include <Windows.h>
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#define CINTERFACE
|
||||
#include <dsound.h>
|
||||
|
||||
static WAVEFORMATEX wave_format = {
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
WAVE_FORMAT_IEEE_FLOAT,
|
||||
#else
|
||||
WAVE_FORMAT_PCM,
|
||||
#endif
|
||||
SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_RATE,
|
||||
SU_SAMPLE_RATE * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_SIZE*8,
|
||||
0
|
||||
};
|
||||
DSBUFFERDESC buffer_description = {
|
||||
sizeof(DSBUFFERDESC),
|
||||
DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_TRUEPLAYPOSITION,
|
||||
SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
|
||||
0,
|
||||
&wave_format,
|
||||
0
|
||||
};
|
||||
|
||||
static HWND hWnd;
|
||||
static LPDIRECTSOUND direct_sound;
|
||||
static LPDIRECTSOUNDBUFFER direct_sound_buffer;
|
||||
static LPVOID p1;
|
||||
static DWORD l1;
|
||||
static DWORD last_play_cursor = 0;
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef UNIX
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
static snd_pcm_t *pcm_handle;
|
||||
static pthread_t render_thread;
|
||||
static uint32_t render_thread_handle;
|
||||
static pthread_t playback_thread;
|
||||
static uint32_t playback_thread_handle;
|
||||
snd_htimestamp_t start_ts;
|
||||
|
||||
static int _snd_pcm_writei(void *params) {
|
||||
(void) params;
|
||||
snd_pcm_writei(pcm_handle, sound_buffer, SU_LENGTH_IN_SAMPLES);
|
||||
return 0;
|
||||
}
|
||||
#endif /* UNIX */
|
||||
|
||||
static PyObject *sointuError;
|
||||
|
||||
static PyObject *sointu_play_song(PyObject *self, PyObject *args) {
|
||||
#ifdef WIN32
|
||||
|
||||
#ifdef SU_LOAD_GMDLS
|
||||
su_load_gmdls();
|
||||
#endif // SU_LOAD_GMDLS
|
||||
|
||||
hWnd = GetForegroundWindow();
|
||||
if(hWnd == NULL) {
|
||||
hWnd = GetDesktopWindow();
|
||||
}
|
||||
|
||||
DirectSoundCreate(0, &direct_sound, 0);
|
||||
IDirectSound_SetCooperativeLevel(direct_sound, hWnd, DSSCL_PRIORITY);
|
||||
IDirectSound_CreateSoundBuffer(direct_sound, &buffer_description, &direct_sound_buffer, NULL);
|
||||
IDirectSoundBuffer_Lock(direct_sound_buffer, 0, SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT * SU_SAMPLE_SIZE, &p1, &l1, NULL, NULL, 0);
|
||||
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)su_render_song, p1, 0, 0);
|
||||
IDirectSoundBuffer_Play(direct_sound_buffer, 0, 0, 0);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef UNIX
|
||||
render_thread_handle = pthread_create(&render_thread, 0, (void * (*)(void *))su_render_song, sound_buffer);
|
||||
|
||||
// We can't start playing too early or the missing samples will be audible.
|
||||
sleep(2.);
|
||||
|
||||
// Play the track.
|
||||
snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
||||
snd_pcm_set_params(
|
||||
pcm_handle,
|
||||
#ifdef SU_SAMPLE_FLOAT
|
||||
SND_PCM_FORMAT_FLOAT,
|
||||
#else // SU_SAMPLE_FLOAT
|
||||
SND_PCM_FORMAT_S16_LE,
|
||||
#endif // SU_SAMPLE_FLOAT
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
SU_CHANNEL_COUNT,
|
||||
SU_SAMPLE_RATE,
|
||||
0,
|
||||
SU_LENGTH_IN_SAMPLES
|
||||
);
|
||||
|
||||
// Enable playback time querying.
|
||||
snd_pcm_sw_params_t *swparams;
|
||||
snd_pcm_sw_params_alloca(&swparams);
|
||||
snd_pcm_sw_params_current(pcm_handle, swparams);
|
||||
snd_pcm_sw_params_set_tstamp_mode(pcm_handle, swparams, SND_PCM_TSTAMP_ENABLE);
|
||||
snd_pcm_sw_params_set_tstamp_type(pcm_handle, swparams, SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY);
|
||||
snd_pcm_sw_params(pcm_handle, swparams);
|
||||
|
||||
playback_thread_handle = pthread_create(&playback_thread, 0, (void *(*)(void *))_snd_pcm_writei, 0);
|
||||
|
||||
// Get the start time stamp.
|
||||
snd_pcm_uframes_t avail;
|
||||
snd_pcm_htimestamp(pcm_handle, &avail, &start_ts);
|
||||
#endif /* UNIX */
|
||||
|
||||
return PyLong_FromLong(0);
|
||||
}
|
||||
|
||||
static PyObject *sointu_playback_position(PyObject *self, PyObject *args) {
|
||||
#ifdef WIN32
|
||||
DWORD play_cursor = 0;
|
||||
IDirectSoundBuffer_GetCurrentPosition(direct_sound_buffer, (DWORD*)&play_cursor, NULL);
|
||||
return Py_BuildValue("i", play_cursor / SU_CHANNEL_COUNT / sizeof(SUsample));
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef UNIX
|
||||
snd_htimestamp_t ts;
|
||||
snd_pcm_uframes_t avail;
|
||||
snd_pcm_htimestamp(pcm_handle, &avail, &ts);
|
||||
|
||||
return Py_BuildValue("i", (int)((ts.tv_sec - start_ts.tv_sec + 1.e-9 * (ts.tv_nsec - start_ts.tv_nsec)) * SU_SAMPLE_RATE));
|
||||
#endif /* UNIX */
|
||||
}
|
||||
|
||||
static PyObject *sointu_playback_finished(PyObject *self, PyObject *args) {
|
||||
bool result = false;
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD play_cursor = 0;
|
||||
IDirectSoundBuffer_GetCurrentPosition(direct_sound_buffer, (DWORD*)&play_cursor, NULL);
|
||||
result = play_cursor < last_play_cursor;
|
||||
last_play_cursor = play_cursor;
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef UNIX
|
||||
snd_htimestamp_t ts;
|
||||
snd_pcm_uframes_t avail;
|
||||
snd_pcm_htimestamp(pcm_handle, &avail, &ts);
|
||||
|
||||
result = ts.tv_sec - start_ts.tv_sec < 0;
|
||||
#endif /* UNIX */
|
||||
|
||||
return PyBool_FromLong(result);
|
||||
}
|
||||
|
||||
static PyObject *sointu_sample_rate(PyObject *self, PyObject *args) {
|
||||
return Py_BuildValue("i", SU_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
static PyObject *sointu_track_length(PyObject *self, PyObject *args) {
|
||||
return Py_BuildValue("i", SU_LENGTH_IN_SAMPLES);
|
||||
}
|
||||
|
||||
static PyMethodDef sointuMethods[] = {
|
||||
{"play_song", sointu_play_song, METH_VARARGS, "Play sointu track."},
|
||||
{"playback_position", sointu_playback_position, METH_VARARGS, "Get playback position of sointu track currently playing."},
|
||||
{"playback_finished", sointu_playback_finished, METH_VARARGS, "Check if currently playing sointu track has finished playing."},
|
||||
{"sample_rate", sointu_sample_rate, METH_VARARGS, "Return the sample rate of the track compiled into this module."},
|
||||
{"track_length", sointu_track_length, METH_VARARGS, "Return the track length in samples."},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct PyModuleDef sointumodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"sointu",
|
||||
NULL,
|
||||
-1,
|
||||
sointuMethods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_sointu(void) {
|
||||
PyObject *module = PyModule_Create(&sointumodule);
|
||||
if(module == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sointuError = PyErr_NewException("sointu.sointuError", NULL, NULL);
|
||||
Py_XINCREF(sointuError);
|
||||
|
||||
if(PyModule_AddObject(module, "error", sointuError) < 0) {
|
||||
Py_XDECREF(sointuError);
|
||||
Py_CLEAR(sointuError);
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
0
examples/code/Python/sointu_python/__init__.py
Normal file
0
examples/code/Python/sointu_python/__init__.py
Normal file
16
examples/code/Python/sointu_python/__main__.py
Normal file
16
examples/code/Python/sointu_python/__main__.py
Normal file
@ -0,0 +1,16 @@
|
||||
from sointu import (
|
||||
play_song,
|
||||
playback_position,
|
||||
playback_finished,
|
||||
sample_rate,
|
||||
track_length,
|
||||
)
|
||||
from sys import exit
|
||||
|
||||
if __name__ == '__main__':
|
||||
play_song()
|
||||
|
||||
while not playback_finished():
|
||||
print("Playback time:", playback_position() / sample_rate())
|
||||
|
||||
exit(0)
|
||||
58
examples/code/Python/sointu_python/sointu_python.spec
Normal file
58
examples/code/Python/sointu_python/sointu_python.spec
Normal file
@ -0,0 +1,58 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
from os.path import abspath, join
|
||||
from zipfile import ZipFile
|
||||
from platform import system
|
||||
|
||||
moduleName = 'sointu_python'
|
||||
rootPath = abspath('.')
|
||||
buildPath = join(rootPath, 'build')
|
||||
distPath = join(rootPath, 'dist')
|
||||
sourcePath = join(rootPath, moduleName)
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(
|
||||
[
|
||||
join(sourcePath, '__main__.py'),
|
||||
],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='{}'.format(moduleName),
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=None,
|
||||
)
|
||||
|
||||
exeFileName = '{}{}'.format(moduleName, '.exe' if system() == 'Windows' else '')
|
||||
zipFileName = '{}-{}.zip'.format(moduleName, 'windows' if system() == 'Windows' else 'linux')
|
||||
ZipFile(join(distPath, zipFileName), mode='w').write(join(distPath, exeFileName), arcname=exeFileName)
|
||||
10
examples/code/asm/386/CMakeLists.txt
Normal file
10
examples/code/asm/386/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
if(WIN32)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
|
||||
elseif(UNIX)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf32)
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> <DEFINES> <FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
|
||||
|
||||
add_asm_example(asmplay "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml" 386 32 "winmm" "asound;pthread")
|
||||
add_asm_example(asmwav "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml" 386 32 "" "")
|
||||
target_compile_definitions(asmwav-386 PRIVATE FILENAME="physics_girl_st.wav")
|
||||
81
examples/code/asm/386/asmplay.elf32.asm
Normal file
81
examples/code/asm/386/asmplay.elf32.asm
Normal file
@ -0,0 +1,81 @@
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define SND_PCM_FORMAT_S16_LE 0x2
|
||||
%define SND_PCM_FORMAT_FLOAT 0xE
|
||||
%define SND_PCM_ACCESS_RW_INTERLEAVED 0x3
|
||||
%define SND_PCM_STREAM_PLAYBACK 0x0
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
render_thread:
|
||||
resd 1
|
||||
|
||||
pcm_handle:
|
||||
resd 1
|
||||
|
||||
section .data
|
||||
default_device:
|
||||
db "default", 0
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern pthread_create
|
||||
extern sleep
|
||||
extern snd_pcm_open
|
||||
extern snd_pcm_set_params
|
||||
extern snd_pcm_writei
|
||||
|
||||
global main
|
||||
main:
|
||||
; elf32 uses the cdecl calling convention. This is more readable imo ;)
|
||||
|
||||
; Prologue
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
sub esp, 0x10
|
||||
|
||||
; Unix does not have gm.dls, no need to ifdef and setup here.
|
||||
|
||||
; We render in the background while playing already.
|
||||
push sound_buffer
|
||||
lea eax, su_render_song
|
||||
push eax
|
||||
push 0
|
||||
push render_thread
|
||||
call pthread_create
|
||||
|
||||
; We can't start playing too early or the missing samples will be audible.
|
||||
push 0x2
|
||||
call sleep
|
||||
|
||||
; Play the track.
|
||||
push 0x0
|
||||
push SND_PCM_STREAM_PLAYBACK
|
||||
push default_device
|
||||
push pcm_handle
|
||||
call snd_pcm_open
|
||||
|
||||
push SU_LENGTH_IN_SAMPLES
|
||||
push 0
|
||||
push SU_SAMPLE_RATE
|
||||
push SU_CHANNEL_COUNT
|
||||
push SND_PCM_ACCESS_RW_INTERLEAVED
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
push SND_PCM_FORMAT_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
push SND_PCM_FORMAT_S16_LE
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
push dword [pcm_handle]
|
||||
call snd_pcm_set_params
|
||||
|
||||
push SU_LENGTH_IN_SAMPLES
|
||||
push sound_buffer
|
||||
push dword [pcm_handle]
|
||||
call snd_pcm_writei
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
120
examples/code/asm/386/asmplay.win32.asm
Normal file
120
examples/code/asm/386/asmplay.win32.asm
Normal file
@ -0,0 +1,120 @@
|
||||
%define MANGLED
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define WAVE_FORMAT_PCM 0x1
|
||||
%define WAVE_FORMAT_IEEE_FLOAT 0x3
|
||||
%define WHDR_PREPARED 0x2
|
||||
%define WAVE_MAPPER 0xFFFFFFFF
|
||||
%define TIME_SAMPLES 0x2
|
||||
%define PM_REMOVE 0x1
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
wave_out_handle:
|
||||
resd 1
|
||||
|
||||
msg:
|
||||
resd 1
|
||||
message:
|
||||
resd 7
|
||||
|
||||
section .data
|
||||
wave_format:
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_IEEE_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_PCM
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
dw SU_CHANNEL_COUNT
|
||||
dd SU_SAMPLE_RATE
|
||||
dd SU_SAMPLE_SIZE * SU_SAMPLE_RATE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * 8
|
||||
dw 0
|
||||
|
||||
wave_header:
|
||||
dd sound_buffer
|
||||
dd SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
times 2 dd 0
|
||||
dd WHDR_PREPARED
|
||||
times 4 dd 0
|
||||
wave_header_end:
|
||||
|
||||
mmtime:
|
||||
dd TIME_SAMPLES
|
||||
sample:
|
||||
times 2 dd 0
|
||||
mmtime_end:
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern _CreateThread@24
|
||||
extern _waveOutOpen@24
|
||||
extern _waveOutWrite@12
|
||||
extern _waveOutGetPosition@12
|
||||
extern _PeekMessageA@20
|
||||
extern _TranslateMessage@4
|
||||
extern _DispatchMessageA@4
|
||||
|
||||
global _mainCRTStartup
|
||||
_mainCRTStartup:
|
||||
; win32 uses the cdecl calling convention. This is more readable imo ;)
|
||||
; We can also skip the prologue; Windows doesn't mind.
|
||||
|
||||
%ifdef SU_LOAD_GMDLS
|
||||
call _su_load_gmdls
|
||||
%endif ; SU_LOAD_GMDLS
|
||||
|
||||
times 2 push 0
|
||||
push sound_buffer
|
||||
lea eax, _su_render_song@4
|
||||
push eax
|
||||
times 2 push 0
|
||||
call _CreateThread@24
|
||||
|
||||
; We render in the background while playing already. Fortunately,
|
||||
; Windows is slow with the calls below, so we're not worried that
|
||||
; we don't have enough samples ready before the track starts.
|
||||
times 3 push 0
|
||||
push wave_format
|
||||
push WAVE_MAPPER
|
||||
push wave_out_handle
|
||||
call _waveOutOpen@24
|
||||
|
||||
push wave_header_end - wave_header
|
||||
push wave_header
|
||||
push dword [wave_out_handle]
|
||||
call _waveOutWrite@12
|
||||
|
||||
; We need to handle windows messages properly while playing, as waveOutWrite is async.
|
||||
mainloop:
|
||||
dispatchloop:
|
||||
push PM_REMOVE
|
||||
times 3 push 0
|
||||
push msg
|
||||
call _PeekMessageA@20
|
||||
jz dispatchloop_end
|
||||
|
||||
push msg
|
||||
call _TranslateMessage@4
|
||||
|
||||
push msg
|
||||
call _DispatchMessageA@4
|
||||
|
||||
jmp dispatchloop
|
||||
dispatchloop_end:
|
||||
|
||||
push mmtime_end - mmtime
|
||||
push mmtime
|
||||
push dword [wave_out_handle]
|
||||
call _waveOutGetPosition@12
|
||||
|
||||
cmp dword [sample], SU_LENGTH_IN_SAMPLES
|
||||
jne mainloop
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
91
examples/code/asm/386/asmwav.elf32.asm
Normal file
91
examples/code/asm/386/asmwav.elf32.asm
Normal file
@ -0,0 +1,91 @@
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define WAVE_FORMAT_PCM 0x1
|
||||
%define WAVE_FORMAT_IEEE_FLOAT 0x3
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
file:
|
||||
resd 1
|
||||
|
||||
section .data
|
||||
; Change the filename over -DFILENAME="yourfilename.wav"
|
||||
filename:
|
||||
db FILENAME, 0
|
||||
|
||||
format:
|
||||
db "wb", 0
|
||||
|
||||
; This is the wave file header.
|
||||
wave_file:
|
||||
db "RIFF"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_file
|
||||
db "WAVE"
|
||||
db "fmt "
|
||||
wave_format_end:
|
||||
dd wave_format_end - wave_file
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_IEEE_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_PCM
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
dw SU_CHANNEL_COUNT
|
||||
dd SU_SAMPLE_RATE
|
||||
dd SU_SAMPLE_SIZE * SU_SAMPLE_RATE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * 8
|
||||
wave_header_end:
|
||||
db "data"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_header_end
|
||||
wave_file_end:
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern fopen
|
||||
extern fwrite
|
||||
extern fclose
|
||||
|
||||
global main
|
||||
main:
|
||||
; elf32 uses the cdecl calling convention. This is more readable imo ;)
|
||||
|
||||
; Prologue
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
sub esp, 0x10
|
||||
|
||||
; Unix does not have gm.dls, no need to ifdef and setup here.
|
||||
|
||||
; We render the complete track here.
|
||||
push sound_buffer
|
||||
call su_render_song
|
||||
|
||||
; Now we open the file and save the track.
|
||||
push format
|
||||
push filename
|
||||
call fopen
|
||||
mov dword [file], eax
|
||||
|
||||
; Write header
|
||||
push dword [file]
|
||||
push 0x1
|
||||
push wave_file_end - wave_file
|
||||
push wave_file
|
||||
call fwrite
|
||||
|
||||
; write data
|
||||
push dword [file]
|
||||
push 0x1
|
||||
push SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
push sound_buffer
|
||||
call fwrite
|
||||
|
||||
push dword [file]
|
||||
call fclose
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
102
examples/code/asm/386/asmwav.win32.asm
Normal file
102
examples/code/asm/386/asmwav.win32.asm
Normal file
@ -0,0 +1,102 @@
|
||||
%define MANGLED
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define WAVE_FORMAT_PCM 0x1
|
||||
%define WAVE_FORMAT_IEEE_FLOAT 0x3
|
||||
%define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
%define CREATE_ALWAYS 2
|
||||
%define GENERIC_WRITE 0x40000000
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
file:
|
||||
resd 1
|
||||
|
||||
bytes_written:
|
||||
resd 1
|
||||
|
||||
section .data
|
||||
; Change the filename over -DFILENAME="yourfilename.wav"
|
||||
filename:
|
||||
db FILENAME, 0
|
||||
|
||||
; This is the wave file header.
|
||||
wave_file:
|
||||
db "RIFF"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_file
|
||||
db "WAVE"
|
||||
db "fmt "
|
||||
wave_format_end:
|
||||
dd wave_format_end - wave_file
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_IEEE_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_PCM
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
dw SU_CHANNEL_COUNT
|
||||
dd SU_SAMPLE_RATE
|
||||
dd SU_SAMPLE_SIZE * SU_SAMPLE_RATE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * 8
|
||||
wave_header_end:
|
||||
db "data"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_header_end
|
||||
wave_file_end:
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern _CreateFileA@28
|
||||
extern _WriteFile@20
|
||||
extern _CloseHandle@4
|
||||
|
||||
global _mainCRTStartup
|
||||
_mainCRTStartup:
|
||||
; Prologue
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
sub esp, 0x10
|
||||
|
||||
%ifdef SU_LOAD_GMDLS
|
||||
call _su_load_gmdls
|
||||
%endif ; SU_LOAD_GMDLS
|
||||
|
||||
; We render the complete track here.
|
||||
push sound_buffer
|
||||
call _su_render_song@4
|
||||
|
||||
; Now we open the file and save the track.
|
||||
push 0x0
|
||||
push FILE_ATTRIBUTE_NORMAL
|
||||
push CREATE_ALWAYS
|
||||
push 0x0
|
||||
push 0x0
|
||||
push GENERIC_WRITE
|
||||
push filename
|
||||
call _CreateFileA@28
|
||||
mov dword [file], eax
|
||||
|
||||
; This is the WAV header
|
||||
push 0x0
|
||||
push bytes_written
|
||||
push wave_file_end - wave_file
|
||||
push wave_file
|
||||
push dword [file]
|
||||
call _WriteFile@20
|
||||
|
||||
; There we write the actual samples
|
||||
push 0x0
|
||||
push bytes_written
|
||||
push SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT * SU_SAMPLE_SIZE
|
||||
push sound_buffer
|
||||
push dword [file]
|
||||
call _WriteFile@20
|
||||
|
||||
push dword [file]
|
||||
call _CloseHandle@4
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
58
examples/code/asm/CMakeLists.txt
Normal file
58
examples/code/asm/CMakeLists.txt
Normal file
@ -0,0 +1,58 @@
|
||||
# identifier: Name of the example
|
||||
# songfile: File path of the song YAML file.
|
||||
# architecture: 386 or amd64
|
||||
# abi: 32 or 64
|
||||
# windows_libraries: All libraries that you need to link on Windows
|
||||
# unix_libraries: All libraries that you need to link on unix
|
||||
function(add_asm_example identifier songfile architecture sizeof_void_ptr windows_libraries unix_libraries)
|
||||
get_filename_component(songprefix ${songfile} NAME_WE)
|
||||
|
||||
# Generate the song assembly file
|
||||
add_custom_command(
|
||||
COMMAND
|
||||
${compilecmd} -arch=${architecture} -o ${songprefix}_${architecture}.asm ${songfile}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${songfile}
|
||||
${compilecmd}
|
||||
OUTPUT
|
||||
${songprefix}_${architecture}.asm
|
||||
${songprefix}_${architecture}.h
|
||||
${songprefix}_${architecture}.inc
|
||||
COMMENT
|
||||
"Compiling ${PROJECT_SOURCE_DIR}/examples/patches/physics-girl-st.yml..."
|
||||
)
|
||||
|
||||
# Platform dependent options
|
||||
if(WIN32)
|
||||
set(abi win)
|
||||
set(libraries ${windows_libraries})
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(link_options -nostartfiles)
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
set(abi elf)
|
||||
set(link_options -z noexecstack -no-pie)
|
||||
set(libraries ${unix_libraries})
|
||||
endif()
|
||||
|
||||
# Add target
|
||||
add_executable(${identifier}-${architecture}
|
||||
${identifier}.${abi}${sizeof_void_ptr}.asm
|
||||
${songprefix}_${architecture}.asm
|
||||
${songprefix}_${architecture}.inc
|
||||
)
|
||||
set_target_properties(${identifier}-${architecture} PROPERTIES ASM_NASM_COMPILE_OPTIONS -f${abi}${sizeof_void_ptr})
|
||||
target_include_directories(${identifier}-${architecture} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_target_properties(${identifier}-${architecture} PROPERTIES LINKER_LANGUAGE C)
|
||||
target_link_options(${identifier}-${architecture} PRIVATE -m${sizeof_void_ptr} ${link_options})
|
||||
target_link_libraries(${identifier}-${architecture} PRIVATE ${libraries})
|
||||
target_compile_definitions(${identifier}-${architecture} PRIVATE TRACK_INCLUDE="${songprefix}_${architecture}.inc")
|
||||
|
||||
# Set up dependencies
|
||||
add_dependencies(examples ${identifier}-${architecture})
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(386)
|
||||
add_subdirectory(amd64)
|
||||
12
examples/code/asm/amd64/CMakeLists.txt
Normal file
12
examples/code/asm/amd64/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
if(WIN32)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
|
||||
elseif(UNIX)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> <DEFINES> <FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
|
||||
|
||||
if(UNIX)
|
||||
add_asm_example(asmplay "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml" amd64 64 "winmm" "asound;pthread")
|
||||
add_asm_example(asmwav "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml" amd64 64 "" "")
|
||||
target_compile_definitions(asmwav-amd64 PRIVATE FILENAME="physics_girl_st.wav")
|
||||
endif()
|
||||
81
examples/code/asm/amd64/asmplay.elf64.asm
Normal file
81
examples/code/asm/amd64/asmplay.elf64.asm
Normal file
@ -0,0 +1,81 @@
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define SND_PCM_FORMAT_S16_LE 0x2
|
||||
%define SND_PCM_FORMAT_FLOAT 0xE
|
||||
%define SND_PCM_ACCESS_RW_INTERLEAVED 0x3
|
||||
%define SND_PCM_STREAM_PLAYBACK 0x0
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
render_thread:
|
||||
resq 1
|
||||
|
||||
pcm_handle:
|
||||
resq 1
|
||||
|
||||
section .data
|
||||
default_device:
|
||||
db "default", 0
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern pthread_create
|
||||
extern sleep
|
||||
extern snd_pcm_open
|
||||
extern snd_pcm_set_params
|
||||
extern snd_pcm_writei
|
||||
|
||||
global main
|
||||
main:
|
||||
; Prologue
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, 0x10
|
||||
|
||||
; Unix does not have gm.dls, no need to ifdef and setup here.
|
||||
|
||||
; We render in the background while playing already.
|
||||
mov rcx, sound_buffer
|
||||
lea rdx, su_render_song
|
||||
mov rsi, 0x0
|
||||
mov rdi, render_thread
|
||||
call pthread_create
|
||||
|
||||
; We can't start playing too early or the missing samples will be audible.
|
||||
mov edi, 0x2
|
||||
call sleep
|
||||
|
||||
; Play the track.
|
||||
mov rdi, pcm_handle
|
||||
mov rsi, default_device
|
||||
mov rdx, SND_PCM_STREAM_PLAYBACK
|
||||
mov rcx, 0x0
|
||||
call snd_pcm_open
|
||||
|
||||
; This is unfortunate. amd64 ABI calling convention kicks in.
|
||||
; now we have to maintain the stack pointer :/
|
||||
mov rdi, qword [pcm_handle]
|
||||
sub rsp, 0x8
|
||||
push SU_LENGTH_IN_SAMPLES
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
mov rsi, SND_PCM_FORMAT_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
mov rsi, SND_PCM_FORMAT_S16_LE
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
mov rdx, SND_PCM_ACCESS_RW_INTERLEAVED
|
||||
mov rcx, SU_CHANNEL_COUNT
|
||||
mov r8d, SU_SAMPLE_RATE
|
||||
mov r9d, 0x0
|
||||
call snd_pcm_set_params
|
||||
|
||||
mov rdi, qword [pcm_handle]
|
||||
mov rsi, sound_buffer
|
||||
mov rdx, SU_LENGTH_IN_SAMPLES
|
||||
call snd_pcm_writei
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
91
examples/code/asm/amd64/asmwav.elf64.asm
Normal file
91
examples/code/asm/amd64/asmwav.elf64.asm
Normal file
@ -0,0 +1,91 @@
|
||||
%include TRACK_INCLUDE
|
||||
|
||||
%define WAVE_FORMAT_PCM 0x1
|
||||
%define WAVE_FORMAT_IEEE_FLOAT 0x3
|
||||
|
||||
section .bss
|
||||
sound_buffer:
|
||||
resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
|
||||
file:
|
||||
resq 1
|
||||
|
||||
section .data
|
||||
; Change the filename over -DFILENAME="yourfilename.wav"
|
||||
filename:
|
||||
db FILENAME, 0
|
||||
|
||||
format:
|
||||
db "wb", 0
|
||||
|
||||
; This is the wave file header.
|
||||
wave_file:
|
||||
db "RIFF"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_file
|
||||
db "WAVE"
|
||||
db "fmt "
|
||||
wave_format_end:
|
||||
dd wave_format_end - wave_file
|
||||
%ifdef SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_IEEE_FLOAT
|
||||
%else ; SU_SAMPLE_FLOAT
|
||||
dw WAVE_FORMAT_PCM
|
||||
%endif ; SU_SAMPLE_FLOAT
|
||||
dw SU_CHANNEL_COUNT
|
||||
dd SU_SAMPLE_RATE
|
||||
dd SU_SAMPLE_SIZE * SU_SAMPLE_RATE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
dw SU_SAMPLE_SIZE * 8
|
||||
wave_header_end:
|
||||
db "data"
|
||||
dd wave_file_end + SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT - wave_header_end
|
||||
wave_file_end:
|
||||
|
||||
section .text
|
||||
symbols:
|
||||
extern fopen
|
||||
extern fwrite
|
||||
extern fclose
|
||||
|
||||
global main
|
||||
main:
|
||||
; elf32 uses the cdecl calling convention. This is more readable imo ;)
|
||||
|
||||
; Prologue
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, 0x10
|
||||
|
||||
; Unix does not have gm.dls, no need to ifdef and setup here.
|
||||
|
||||
; We render the complete track here.
|
||||
mov rdi, sound_buffer
|
||||
call su_render_song
|
||||
|
||||
; Now we open the file and save the track.
|
||||
mov rsi, format
|
||||
mov rdi, filename
|
||||
call fopen
|
||||
mov qword [file], rax
|
||||
|
||||
; Write header
|
||||
mov rcx, qword [file]
|
||||
mov rdx, 0x1
|
||||
mov rsi, wave_file_end - wave_file
|
||||
mov rdi, wave_file
|
||||
call fwrite
|
||||
|
||||
; write data
|
||||
mov rcx, qword [file]
|
||||
mov rdx, 0x1
|
||||
mov rsi, SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT
|
||||
mov rdi, sound_buffer
|
||||
call fwrite
|
||||
|
||||
mov rdi, qword [file]
|
||||
call fclose
|
||||
|
||||
exit:
|
||||
; At least we can skip the epilogue :)
|
||||
leave
|
||||
ret
|
||||
14
examples/code/wasm/README.md
Normal file
14
examples/code/wasm/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
Requirements: sointu binaries, `wabt`
|
||||
|
||||
To generate the .wasm file:
|
||||
|
||||
```
|
||||
sointu-compile -o . -arch=wasm tests/test_chords.yml
|
||||
wat2wasm --enable-bulk-memory test_chords.wat
|
||||
```
|
||||
|
||||
To run the example:
|
||||
|
||||
```
|
||||
npx serve examples/code/wasm
|
||||
```
|
||||
51
examples/code/wasm/index.html
Normal file
51
examples/code/wasm/index.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>sointu WASM example</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="module">
|
||||
// button to start audio context
|
||||
const button = document.createElement("button");
|
||||
button.innerHTML = "start";
|
||||
document.body.appendChild(button);
|
||||
button.onclick = () => {
|
||||
document.body.removeChild(button);
|
||||
|
||||
fetch("test_chords.wasm")
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((bytes) => WebAssembly.instantiate(bytes, { m: Math }))
|
||||
.then(({ instance }) => {
|
||||
const context = new AudioContext({ sampleRate: 44100 });
|
||||
|
||||
let frames = instance.exports.t.value
|
||||
? instance.exports.l.value / 4
|
||||
: instance.exports.l.value / 8;
|
||||
|
||||
let wasmBuffer = new Float32Array(
|
||||
instance.exports.m.buffer,
|
||||
instance.exports.s.value,
|
||||
frames * 2
|
||||
);
|
||||
|
||||
const buffer = context.createBuffer(2, frames, context.sampleRate);
|
||||
|
||||
// convert wasm buffer to audio buffer
|
||||
for (let channel = 0; channel < 2; channel++) {
|
||||
const buffering = buffer.getChannelData(channel);
|
||||
for (let i = 0; i < frames; i++) {
|
||||
buffering[i] = wasmBuffer[i * 2 + channel];
|
||||
}
|
||||
}
|
||||
|
||||
// connect to output and start playing
|
||||
const src = context.createBufferSource();
|
||||
src.buffer = buffer;
|
||||
src.connect(context.destination);
|
||||
src.start();
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
examples/code/wasm/test_chords.wasm
Normal file
BIN
examples/code/wasm/test_chords.wasm
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user