nodeskini 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +31 -0
  2. package/client/archive/bundle.js +11528 -0
  3. package/client/archive/golem.html +60 -0
  4. package/client/archive/golemClient.js +595 -0
  5. package/client/archive/golembundle.js +11634 -0
  6. package/client/archive/sequencer.html +43 -0
  7. package/client/archive/sequenceurClient.js +815 -0
  8. package/client/archive/stylegolem.css +158 -0
  9. package/client/archive/stylesequenceur.css +204 -0
  10. package/client/clientListe/Sortable-master/.circleci/config.yml +33 -0
  11. package/client/clientListe/Sortable-master/.editorconfig +15 -0
  12. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/bug-report.md +73 -0
  13. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/custom-template.md +48 -0
  14. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/feature-request.md +41 -0
  15. package/client/clientListe/Sortable-master/.jshintrc +25 -0
  16. package/client/clientListe/Sortable-master/.testcaferc.json +7 -0
  17. package/client/clientListe/Sortable-master/CONTRIBUTING.md +26 -0
  18. package/client/clientListe/Sortable-master/LICENSE +21 -0
  19. package/client/clientListe/Sortable-master/README.md +813 -0
  20. package/client/clientListe/Sortable-master/Sortable.js +3709 -0
  21. package/client/clientListe/Sortable-master/Sortable.min.js +2 -0
  22. package/client/clientListe/Sortable-master/Sortable.min.old.js +2 -0
  23. package/client/clientListe/Sortable-master/Sortable.min.old.old.js +2 -0
  24. package/client/clientListe/Sortable-master/babel.config.js +27 -0
  25. package/client/clientListe/Sortable-master/bower.json +30 -0
  26. package/client/clientListe/Sortable-master/entry/entry-complete.js +8 -0
  27. package/client/clientListe/Sortable-master/entry/entry-core.js +19 -0
  28. package/client/clientListe/Sortable-master/entry/entry-defaults.js +19 -0
  29. package/client/clientListe/Sortable-master/index.html +460 -0
  30. package/client/clientListe/Sortable-master/modular/sortable.complete.esm.js +3701 -0
  31. package/client/clientListe/Sortable-master/modular/sortable.core.esm.js +3698 -0
  32. package/client/clientListe/Sortable-master/modular/sortable.esm.js +3699 -0
  33. package/client/clientListe/Sortable-master/package-lock.json +5704 -0
  34. package/client/clientListe/Sortable-master/package.json +56 -0
  35. package/client/clientListe/Sortable-master/plugins/AutoScroll/AutoScroll.js +270 -0
  36. package/client/clientListe/Sortable-master/plugins/AutoScroll/README.md +80 -0
  37. package/client/clientListe/Sortable-master/plugins/AutoScroll/index.js +1 -0
  38. package/client/clientListe/Sortable-master/plugins/MultiDrag/MultiDrag.js +617 -0
  39. package/client/clientListe/Sortable-master/plugins/MultiDrag/README.md +96 -0
  40. package/client/clientListe/Sortable-master/plugins/MultiDrag/index.js +1 -0
  41. package/client/clientListe/Sortable-master/plugins/OnSpill/OnSpill.js +79 -0
  42. package/client/clientListe/Sortable-master/plugins/OnSpill/README.md +60 -0
  43. package/client/clientListe/Sortable-master/plugins/OnSpill/index.js +1 -0
  44. package/client/clientListe/Sortable-master/plugins/README.md +178 -0
  45. package/client/clientListe/Sortable-master/plugins/Swap/README.md +55 -0
  46. package/client/clientListe/Sortable-master/plugins/Swap/Swap.js +90 -0
  47. package/client/clientListe/Sortable-master/plugins/Swap/index.js +1 -0
  48. package/client/clientListe/Sortable-master/scripts/banner.js +8 -0
  49. package/client/clientListe/Sortable-master/scripts/build.js +17 -0
  50. package/client/clientListe/Sortable-master/scripts/esm-build.js +28 -0
  51. package/client/clientListe/Sortable-master/scripts/minify.js +11 -0
  52. package/client/clientListe/Sortable-master/scripts/test-compat.js +30 -0
  53. package/client/clientListe/Sortable-master/scripts/test.js +21 -0
  54. package/client/clientListe/Sortable-master/scripts/umd-build.js +15 -0
  55. package/client/clientListe/Sortable-master/src/Animation.js +175 -0
  56. package/client/clientListe/Sortable-master/src/BrowserInfo.js +12 -0
  57. package/client/clientListe/Sortable-master/src/EventDispatcher.js +57 -0
  58. package/client/clientListe/Sortable-master/src/PluginManager.js +87 -0
  59. package/client/clientListe/Sortable-master/src/Sortable.js +1971 -0
  60. package/client/clientListe/Sortable-master/src/utils.js +556 -0
  61. package/client/clientListe/Sortable-master/st/app.js +224 -0
  62. package/client/clientListe/Sortable-master/st/iframe/frame.html +32 -0
  63. package/client/clientListe/Sortable-master/st/iframe/index.html +49 -0
  64. package/client/clientListe/Sortable-master/st/logo.png +0 -0
  65. package/client/clientListe/Sortable-master/st/og-image.png +0 -0
  66. package/client/clientListe/Sortable-master/st/prettify/prettify.css +1 -0
  67. package/client/clientListe/Sortable-master/st/prettify/prettify.js +46 -0
  68. package/client/clientListe/Sortable-master/st/prettify/run_prettify.js +64 -0
  69. package/client/clientListe/Sortable-master/st/saucelabs.svg +1 -0
  70. package/client/clientListe/Sortable-master/st/theme.css +254 -0
  71. package/client/clientListe/Sortable-master/tests/Sortable.compat.test.js +39 -0
  72. package/client/clientListe/Sortable-master/tests/Sortable.test.js +386 -0
  73. package/client/clientListe/Sortable-master/tests/dual-list.html +34 -0
  74. package/client/clientListe/Sortable-master/tests/empty-list.html +30 -0
  75. package/client/clientListe/Sortable-master/tests/filter.html +27 -0
  76. package/client/clientListe/Sortable-master/tests/handles.html +27 -0
  77. package/client/clientListe/Sortable-master/tests/nested.html +67 -0
  78. package/client/clientListe/Sortable-master/tests/single-list.html +25 -0
  79. package/client/clientListe/Sortable-master/tests/style.css +18 -0
  80. package/client/clientListe/clientListe.html +148 -0
  81. package/client/clientListe/clientListe.js +1508 -0
  82. package/client/clientListe/clientListebundle.js +13164 -0
  83. package/client/clientListe/images/poubelle.png +0 -0
  84. package/client/clientListe/images/start.png +0 -0
  85. package/client/clientListe/images/stop.png +0 -0
  86. package/client/clientListe/images/submit.png +0 -0
  87. package/client/clientListe/sortable-theme-bootstrap.css +90 -0
  88. package/client/configurateur/configReact.js +273 -0
  89. package/client/configurateur/configReactbundle.js +295 -0
  90. package/client/configurateur/configurateur.css +95 -0
  91. package/client/configurateur/configurateur.html +48 -0
  92. package/client/configurateur/lib/jexcel.css +755 -0
  93. package/client/configurateur/lib/jexcel.js +14970 -0
  94. package/client/configurateur/lib/jsuites.css +2801 -0
  95. package/client/configurateur/lib/jsuites.js +11822 -0
  96. package/client/configurateur/lib/react-dom.production.min.js +239 -0
  97. package/client/configurateur/lib/react.production.min.js +32 -0
  98. package/client/configurateur/src/configReact.js +247 -0
  99. package/client/controleur/clientcontroleur.js +536 -0
  100. package/client/controleur/clientcontroleur.test.js +282 -0
  101. package/client/controleur/controleur.html +51 -0
  102. package/client/controleur/controleurbundle.js +565 -0
  103. package/client/controleur/stylecontroleur.css +236 -0
  104. package/client/controleurHH/controleurHH.html +71 -0
  105. package/client/controleurHH/controleurHH.js +252 -0
  106. package/client/controleurHH/styles/index.css +320 -0
  107. package/client/controleurHH/styles/material.css +11552 -0
  108. package/client/parametrage/paramReact.js +473 -0
  109. package/client/parametrage/paramReactbundle.js +500 -0
  110. package/client/parametrage/parametrage.css +111 -0
  111. package/client/parametrage/parametrage.html +163 -0
  112. package/client/parametrage/src/paramReact.js +459 -0
  113. package/client/score/hash.js +83 -0
  114. package/client/score/p5.min.js +3 -0
  115. package/client/score/parto1.js +1171 -0
  116. package/client/score/parto1bundle.js +1181 -0
  117. package/client/score/processing.min.js +431 -0
  118. package/client/score/score.html +15 -0
  119. package/client/score/score.js +34 -0
  120. package/client/simulateurListe/simulateurFork.js +750 -0
  121. package/client/simulateurListe/simulateurFork.mjs +681 -0
  122. package/client/simulateurListe/simulateurForkSansReorg.js +569 -0
  123. package/client/simulateurListe/simulateurListe.js +628 -0
  124. package/myReact/archive/Nodeemitvaluedlocal1.hh.js +52 -0
  125. package/myReact/archive/abort-parNode.js +79 -0
  126. package/myReact/archive/abroNode.js +169 -0
  127. package/myReact/archive/abroNode2.js +80 -0
  128. package/myReact/archive/atom.compile.hh.js +51 -0
  129. package/myReact/archive/await-countNode.js +67 -0
  130. package/myReact/archive/await-nowvalNode.js +44 -0
  131. package/myReact/archive/callHH.js +96 -0
  132. package/myReact/archive/emit-if2.hh.compiled.js +113 -0
  133. package/myReact/archive/every1Node.js +35 -0
  134. package/myReact/archive/if-runNode.js +74 -0
  135. package/myReact/archive/if1Node.js +43 -0
  136. package/myReact/archive/makeawait.js +0 -0
  137. package/myReact/archive/myReact.old.js +684 -0
  138. package/myReact/archive/orchestration.js +281 -0
  139. package/myReact/archive/orchestration1.js +132 -0
  140. package/myReact/archive/orchestration1.xml +465 -0
  141. package/myReact/archive/orchestration2.js +161 -0
  142. package/myReact/archive/orchestrationHH.mano.js +280 -0
  143. package/myReact/archive/orchestrationHHTest.js +428 -0
  144. package/myReact/archive/orchestrationHHTest.xml +234 -0
  145. package/myReact/archive/orchestrationHHTestRun.js +104 -0
  146. package/myReact/archive/orchestrationHHTestRun.xml +34 -0
  147. package/myReact/archive/orchestrationTest0.js +178 -0
  148. package/myReact/archive/orchestrationTest1.js +181 -0
  149. package/myReact/archive/orchestrationTest2.js +281 -0
  150. package/myReact/archive/run3pointsNode.js +59 -0
  151. package/myReact/archive/runNode.js +123 -0
  152. package/myReact/archive/runNode2.js +91 -0
  153. package/myReact/archive/testAwait1.js +141 -0
  154. package/myReact/archive/testAwait1.xml +86 -0
  155. package/myReact/archive/testEvery1.js +122 -0
  156. package/myReact/archive/testEvery1.xml +79 -0
  157. package/myReact/archive/testHH1.js +135 -0
  158. package/myReact/archive/testHH1.xml +86 -0
  159. package/myReact/archive/testHH1revu.js +104 -0
  160. package/myReact/archive/testHH2.js +122 -0
  161. package/myReact/archive/testHH2.xml +79 -0
  162. package/myReact/archive/testHH3.js +130 -0
  163. package/myReact/archive/testHH3.xml +86 -0
  164. package/myReact/archive/testHHabort.js +121 -0
  165. package/myReact/archive/testHHabort.xml +83 -0
  166. package/myReact/archive/testMakeawait.js +202 -0
  167. package/myReact/archive/testRun1.js +168 -0
  168. package/myReact/archive/testRun1.xml +142 -0
  169. package/myReact/archive/titi.js +28 -0
  170. package/myReact/archive/titi.xml +110 -0
  171. package/myReact/archive/toto.js +73 -0
  172. package/myReact/archive/toto.xml +198 -0
  173. package/myReact/archive/trap-await-parallelNode.js +123 -0
  174. package/myReact/inutiles/hiver2022.xml +804 -0
  175. package/myReact/inutiles/hopeNode.xml +459 -0
  176. package/myReact/inutiles/mars2022.xml +871 -0
  177. package/myReact/inutiles/mystique1.xml +318 -0
  178. package/myReact/inutiles/mystiqueOSC.xml +277 -0
  179. package/myReact/inutiles/opus5Node.xml +1271 -0
  180. package/myReact/inutiles/opus5NodeLinux.xml +1241 -0
  181. package/myReact/inutiles/orchestrationHH.xml +541 -0
  182. package/myReact/inutiles/orchestrationHH2.xml +547 -0
  183. package/myReact/inutiles/testHH.xml +95 -0
  184. package/myReact/inutiles/trouveLaPercuTenor.xml +349 -0
  185. package/myReact/myReact.js +744 -0
  186. package/myReact/myReact.min.js +1 -0
  187. package/myReact/orchestrationHH.js +311 -0
  188. package/myReact/orchestrationHH.mjs +436 -0
  189. package/myReact/orchestrationHH.mjs.map +1 -0
  190. package/package.json +46 -0
  191. package/serveur/OSCandMidi.mjs +361 -0
  192. package/serveur/computeScore.mjs +415 -0
  193. package/serveur/controleDAW.mjs +1149 -0
  194. package/serveur/defaultSession.csv +2 -0
  195. package/serveur/defaultSkiniParametres.js +119 -0
  196. package/serveur/gameOSC.mjs +96 -0
  197. package/serveur/groupeClientsSons.mjs +1014 -0
  198. package/serveur/ipConfig.json +24 -0
  199. package/serveur/ipConfig127.json +19 -0
  200. package/serveur/ipConfig75.json +17 -0
  201. package/serveur/ipConfigBH.json +19 -0
  202. package/serveur/ipConfigLocal.json +19 -0
  203. package/serveur/midiConfig.json +26 -0
  204. package/serveur/midiConfigBH.json +26 -0
  205. package/serveur/midiConfigVoid.json +3 -0
  206. package/serveur/midimix.mjs +570 -0
  207. package/serveur/saveParam.mjs +159 -0
  208. package/serveur/skiniParametres.good.js +132 -0
  209. package/serveur/skiniParametres.js +106 -0
  210. package/serveur/utilsHHSkini.hh.js +64 -0
  211. package/serveur/utilsSkini.mjs +137 -0
  212. package/serveur/websocketServer.mjs +2052 -0
  213. package/serveur/workerInterfaceZ.mjs +327 -0
  214. package/serveur/workerSynchro.mjs +49 -0
  215. package/skini.mjs +141 -0
@@ -0,0 +1,681 @@
1
+ /**
2
+ * @fileOverview
3
+ * <H3>CODE CLIENT DE SIMULATION D'UNE AUDIENCE
4
+ * UTILISANT LE CLIENT AVEC LISTE (clientListe)</H3>
5
+ * <BR>
6
+ * Scénario possibles:
7
+ * - Les clips sont appelés de façon aléatoire selon la liste disponible.
8
+ * Ceci correspond à une audience qui fait à peu n'importe quoi sur les clips
9
+ * disponibles, en limitant les répétitions.
10
+ * - Les listes de clips correpondant à des séquences de type. Dans le cas de
11
+ * définition de type, ceci correspond à une audience qui joue parfaitement le jeu.
12
+ *
13
+ * Le simulateur est un outil de production de musique générative selon un combinatoire
14
+ * contrôlée.
15
+ *
16
+ * @version 1.2
17
+ * @author Bertrand Petit-Hédelin <bertrand@hedelin.fr>
18
+ * @copyright (C) 2022-2025 Bertrand Petit-Hédelin
19
+ *
20
+ * This program is free software: you can redistribute it and/or modify
21
+ * it under the terms of the GNU General Public License as published by
22
+ * the Free Software Foundation, either version 3 of the License, or
23
+ * any later version.
24
+ *
25
+ * This program is distributed in the hope that it will be useful,
26
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ * GNU General Public License for more details.
29
+ *
30
+ * You should have received a copy of the GNU General Public License
31
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
32
+ */
33
+ 'use strict'
34
+ import { createRequire } from 'module';
35
+ const require = createRequire(import.meta.url);
36
+
37
+ let par;
38
+ let ws;
39
+ const ipConfig = require('../../serveur/ipConfig');
40
+ const WebSocket = require('ws');
41
+
42
+ const debug = false;
43
+ const debug1 = true;
44
+
45
+ // For creating list of patterns according to a type sequence
46
+ let processTypes = false;
47
+
48
+ let tempoMax, tempoMin, limiteDureeAttente, dureeAttente = 10;
49
+ let derniersPatternsJoues = [];
50
+ let derniersInstrumentsJoue = [-1, -1, -1];
51
+ let nbeInstruments = 100; // Attention c'est en dur...
52
+
53
+ function setTableDerniersPatterns(nbeInstr) {
54
+ return Array(nbeInstr).fill().map(() => [-1, -1, -1]);
55
+ }
56
+
57
+ function initTempi() {
58
+ console.log("------------------------------------------------");
59
+
60
+ // Initialisation avec valeurs par défaut
61
+ tempoMax = par.tempoMax ?? 500;
62
+ tempoMin = par.tempoMin ?? 100;
63
+ limiteDureeAttente = par.limiteDureeAttente ?? 100;
64
+
65
+ // Logs des valeurs par défaut utilisées
66
+ if (par.tempoMax === undefined) console.log("tempoMax par défaut");
67
+ if (par.tempoMin === undefined) console.log("tempoMin par défaut");
68
+ if (par.limiteDureeAttente === undefined) console.log("limiteDureeAttente par défaut");
69
+
70
+ derniersPatternsJoues = setTableDerniersPatterns(nbeInstruments);
71
+ if (debug) console.log("derniersPatternsJoues:", derniersPatternsJoues);
72
+
73
+ console.log(`Paramètres tempo: Min=${tempoMin} Max=${tempoMax} limiteDureeAttente=${limiteDureeAttente}`);
74
+ }
75
+
76
+ if (ipConfig.websocketServeurPort !== undefined) {
77
+ var port = ipConfig.websocketServeurPort;
78
+ } else {
79
+ var port = 8080;
80
+ }
81
+
82
+ if (debug) console.log("----------------------------------------------\n");
83
+ if (debug) console.log("serveur:", ipConfig.serverIPAddress, " port:", ipConfig.websocketServeurPort);
84
+
85
+ var id = Math.floor((Math.random() * 1000000) + 1); // Pour identifier le client
86
+ var monGroupe = -1; // non initialisé
87
+ var DAWON = 0;
88
+ var pseudo = "sim" + id;
89
+ var listClips; // Devient une array avec toutes les infos sur les clips selectionnes
90
+ var nombreDePatternsPossible = 1; // Valeur par défaut qui peut être modifiée par l'orchestration
91
+
92
+ var numClip;
93
+ var myArgs = process.argv.slice(2);
94
+
95
+ // Décodage du paramètre pour une simulation indépendante de l'audience
96
+ var jeSuisUneAudience = true;
97
+ for (var i = 0; i < myArgs.length; i++) {
98
+ if (myArgs[i] === "-sim") {
99
+ jeSuisUneAudience = false;
100
+ }
101
+ }
102
+
103
+ /*******************************************************************
104
+ * GESTION DES TYPES
105
+ * Traitement des listes reçues pour s'adapter à une séquence de types.
106
+ * En utilisant les types avec des tanks on n'a pas besoin de gérer
107
+ * la mémoires des patterns sélectionnés, ni de revoir les FIFOs.
108
+ *******************************************************************/
109
+ // Table of positions for the types in listOfPatterns
110
+ // The index correpond to the type.
111
+ let types = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
112
+ let listOfTypes = [[]];
113
+
114
+ function resetListOfTypes() {
115
+ listOfTypes = Array(types.length + 1).fill(null).map(() => []);
116
+ if (debug) console.log("resetListOfTypes:", listOfTypes);
117
+ }
118
+
119
+ resetListOfTypes();
120
+
121
+ /**
122
+ * Initialize the list of patterns according to their types
123
+ * The index correponds to the type.
124
+ * @param {Array} list
125
+ */
126
+ function setListOfTypes(list) {
127
+ resetListOfTypes();
128
+
129
+ if (debug) console.log("setListOfTypes", list, "\nlistOfTypes :", listOfTypes);
130
+
131
+ list.forEach(item => {
132
+ const typeKey = item[7];
133
+ const value = item[3];
134
+ listOfTypes[typeKey].push(value);
135
+ });
136
+
137
+ if (debug) console.log("simulateur: setListOfTypes:", listOfTypes);
138
+ }
139
+
140
+ function getRandomInt(max) {
141
+ return Math.floor(Math.random() * max);
142
+ }
143
+
144
+ /**
145
+ * Get randomly an element in a list and remove it
146
+ * from the list
147
+ * @param {Array} list
148
+ * @returns {*} an element of the list
149
+ */
150
+ function selectOnePattern(list) {
151
+ let randomIndex;
152
+ let selected;
153
+ randomIndex = getRandomInt(list.length);
154
+ selected = list[randomIndex];
155
+ list.splice(randomIndex, 1);
156
+ if (debug) console.log("Simulateur: selectOnePattern:", selected);
157
+ return selected;
158
+ }
159
+
160
+ /**
161
+ * To remove a pattern from the list of patterns
162
+ * where the index is the type
163
+ * @param {Array} list of patterns
164
+ * @param patternName
165
+ */
166
+ function removePattern(list, patternName) {
167
+ for (let i = list.length - 1; i >= 0; i--) {
168
+ if (list[i][3] === patternName) {
169
+ list.splice(i, 1);
170
+ if (debug) console.log("Simulateur: removePattern:", patternName);
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * To get the complete pattern description
177
+ * according to a name
178
+ * @param {Array} list of pattern
179
+ * @param patternName
180
+ * @returns {*} a pattern descriptor
181
+ */
182
+ function getPattern(list, patternName) {
183
+ if (debug) console.log("Simulateur: getPattern :", list, patternName, listOfTypes);
184
+ for (let i = 0; i < list.length; i++) {
185
+ if (list[i][3] === patternName) {
186
+ return list[i];
187
+ }
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Create a list of "selected patterns" according to
193
+ * a sequence described in types.
194
+ * @param {Array} list of present types
195
+ * @param {Array} types
196
+ * @param {Array} listOfPatterns
197
+ * @returns {Array} selected list of Skini notes
198
+ */
199
+ function getListOfPatternsSelected(list, types, listOfPatterns) {
200
+ var selected = [];
201
+ var indexTypes;
202
+ var patternSelected;
203
+ var numClips = [];
204
+ var gotAPattern;
205
+
206
+ if (debug) {
207
+ var testList = [];
208
+ for (var i = 0; i < listOfPatterns.length; i++) {
209
+ if (listOfPatterns[i] !== undefined) {
210
+ testList.push([listOfPatterns[i][0], listOfPatterns[i][7]]);
211
+ }
212
+ }
213
+ console.log("** simulateur: getListOfPatternsSelected: listOfPatterns:", testList);
214
+ }
215
+
216
+ if (debug) {
217
+ var testList = [];
218
+ for (var i = 0; i < list.length; i++) {
219
+ if (list[i] !== undefined) {
220
+ testList.push(list[i][0]);
221
+ }
222
+ }
223
+ console.log("** simulateur: getListOfPatternsSelected: listOfTypes:", testList);
224
+ }
225
+
226
+ // For each type we select a pattern
227
+ for (let i = 0; i < types.length; i++) {
228
+ indexTypes = types[i];
229
+ // Process the list of pattern with a specific type which is indexTypes
230
+ if (list[indexTypes] !== undefined) {
231
+ if (list[indexTypes].length !== 0) {
232
+ patternSelected = selectOnePattern(list[indexTypes]);
233
+
234
+ gotAPattern = getPattern(listOfPatterns, patternSelected);
235
+ selected.push(gotAPattern); // Add the pattern to the selected list
236
+
237
+ removePattern(listOfPatterns, patternSelected);
238
+ }
239
+ }
240
+ }
241
+
242
+ if (debug) {
243
+ testList = [];
244
+ for (var i = 0; i < selected.length; i++) {
245
+ if (selected[i] !== undefined) {
246
+ testList.push([selected[i][0], selected[i][7]]);
247
+ }
248
+ }
249
+ console.log("** simulateur: getListOfPatternsSelected: selected:", testList, "\n");
250
+ }
251
+
252
+ // A ce niveau on a une liste des patterns, il nous faut juste la liste des notes
253
+ // limitée au nombre de patterns dans la liste à soumettre.
254
+ for (var i = 0; i < selected.length ; i++) {
255
+ if (selected[i] !== undefined) {
256
+ numClips.push(selected[i][0]);
257
+ }
258
+ }
259
+ return numClips;
260
+ }
261
+
262
+ /************************ NON REPETITION DES CLIPS ********************
263
+ Table des commandes donnée par les listes de patterns
264
+
265
+ 0= note, 1=note stop, 2=flag, 3=nom, 4=fichier son,
266
+ 5=instrument, 6=Slot, 7=type, 8=free, 9=groupe, 10=durée
267
+ 11= IP, 12= buffer, 13=niveau
268
+
269
+ **********************************************************************/
270
+
271
+ function isInList(element, list) {
272
+ return list.includes(element);
273
+ }
274
+
275
+ function sendPseudo(texte) {
276
+ if (debug) console.log("sendPseudo:", texte);
277
+ ws.send(JSON.stringify({
278
+ type: "clientPseudo",
279
+ pseudo: texte
280
+ }));
281
+ }
282
+ /* --------------------------------------------------------------------
283
+ * On évite de reprendre un élément de la liste qui serait dans la mémoire.
284
+ * Nous avons les cas particuliers où la liste est de taille équivalente
285
+ * ou inferieure à la mémoire.
286
+ * Cette fonction retourne un élément de la liste en tenant compte de l'état de la mémoire.
287
+ * C'est utilisé pour les instruments et pour les patterns.
288
+ * --------------------------------------------------------------------*/
289
+ function selectRandomInList(memoire, liste) {
290
+ if (!memoire || !liste?.length) return undefined;
291
+ if (liste.length === 1) return liste[0];
292
+
293
+ const isInMemory = (item) => liste.length <= memoire.length
294
+ ? item === memoire[memoire.length - 1] // Évite juste le dernier
295
+ : memoire.includes(item); // Évite tout ce qui est en mémoire
296
+
297
+ let selection, attempts = 0;
298
+ do {
299
+ selection = liste[Math.floor(Math.random() * liste.length)];
300
+ } while (isInMemory(selection) && ++attempts < liste.length * 10);
301
+
302
+ memoire.shift();
303
+ memoire.push(selection);
304
+ return selection;
305
+ }
306
+
307
+ // Retourne laSelectionClip note MIDI (Skini) d'un pattern choisi au hasard
308
+ function selectNextClip() {
309
+ let selectionClip;
310
+ let listeSelectionClip = [];
311
+ let listeInstruments = [];
312
+ let instrument;
313
+
314
+ //Mettre à jour le nombre d'instruments donnés par la liste
315
+ for (let i = 0; i < listClips.length; i++) {
316
+ if (!isInList(listClips[i][5], listeInstruments)) {
317
+ listeInstruments.push(listClips[i][5]);
318
+ }
319
+ }
320
+ if (debug) console.log("*** selectNextClip:listeInstruments:", listeInstruments);
321
+
322
+ //Choisir un instrument au hasard, et pas toujours le même
323
+ instrument = selectRandomInList(derniersInstrumentsJoue, listeInstruments);
324
+ if (debug) console.log("*** selectNextClip:instrument:", instrument);
325
+ if (instrument === undefined) {
326
+ console.log("ERR:selectNextClip:instrument undefined");
327
+ return undefined;
328
+ }
329
+
330
+ //Choisir les commandes MIDI des patterns pour l'instrument sélectioné
331
+ listeSelectionClip = listClips
332
+ .filter(clip => clip[5] === instrument)
333
+ .map(clip => clip[0]);
334
+ if (debug) console.log("*** selectNextClip:listeSelectionClip:", listeSelectionClip);
335
+
336
+ // Choisir un pattern pour l'instrument sélectionné
337
+ // Pas suffisant avec l'application de modèles sur la suite des patterns
338
+ // La sélection doit se faire en fonction des types.
339
+ selectionClip = selectRandomInList(derniersPatternsJoues[instrument], listeSelectionClip);
340
+ if (selectionClip === undefined) {
341
+ console.log("ERR:selectNextClip:selectionClip undefined");
342
+ return undefined;
343
+ }
344
+ if (debug) console.log("*** selectNextClip:selectionClip:", selectionClip);
345
+
346
+ return selectionClip;
347
+ }
348
+
349
+ /**
350
+ * To get the number of pattern the simulator can send
351
+ * @param {Array} list of pattern posible by type
352
+ * @param {number} my goup
353
+ * @returns {number} a number of pattern
354
+ */
355
+ function getnombreDePatternsPossible(listOfLengthPerType, myGroup) {
356
+ // Cherche d'abord le groupe spécifique
357
+ const specificGroup = listOfLengthPerType.find(item => item[1] === myGroup);
358
+ if (specificGroup) return specificGroup[0];
359
+
360
+ // Sinon cherche le groupe broadcast (255)
361
+ const broadcastGroup = listOfLengthPerType.find(item => item[1] === 255);
362
+ return broadcastGroup?.[0];
363
+ }
364
+
365
+ /*********************************************
366
+
367
+ WEBSOCKET AVEC NODE JS
368
+
369
+ **********************************************/
370
+
371
+ function initWSSocket(port) {
372
+ var tempoInstantListClip = 0;
373
+
374
+ if (ws !== undefined) {
375
+ if (debug1) console.log("INFO: simulateurFork.js: close the socket");
376
+ ws.close();
377
+ }
378
+
379
+ ws = new WebSocket("ws://" + ipConfig.serverIPAddress + ":" + ipConfig.websocketServeurPort); // NODE JS
380
+
381
+ // Par défaut je suis hors audience
382
+ var monIdentite = "simulateur";
383
+ if (jeSuisUneAudience) monIdentite = "sim";
384
+
385
+ ws.onopen = function (event) {
386
+ if (debug) console.log("INFO: simulateurFork.js Websocket : ", "ws://" + ipConfig.serverIPAddress + ":" + port + "/hop/serv");
387
+ const messages = [
388
+ { type: "startSpectateur", text: monIdentite, id },
389
+ { type: "getNombreDePatternsPossibleEnListe" }
390
+ ];
391
+
392
+ messages.forEach(msg => ws.send(JSON.stringify(msg)))
393
+ };
394
+
395
+ //Traitement de la Réception sur le client
396
+ ws.onmessage = function (event) {
397
+ let msgRecu = JSON.parse(event.data);
398
+ //console.log( "Client: received [%s]", event.data );
399
+ switch (msgRecu.type) {
400
+
401
+ case "DAWON":
402
+ DAWON = msgRecu.value;
403
+ actionSurDAWON();
404
+ break;
405
+
406
+ case "DAWStatus":
407
+ if (debug) console.log("Reçu DAWStatus:", event.value);
408
+ DAWON = msgRecu.value;
409
+ actionSurDAWON();
410
+ break;
411
+
412
+ case "demandeDeSonParPseudo":
413
+ if (debug) console.log("Reçu Texte Broadcast demande de son par pseudo:", msgRecu.value);
414
+ break;
415
+
416
+ case "dureeAttente": // Quand le son a été demandé
417
+ if (debug) console.log("SimulatuerFork.js: dureeAttente:", msgRecu.text, msgRecu.son);
418
+ dureeAttente = parseInt(msgRecu.text);
419
+ break;
420
+
421
+ case "groupe":
422
+ //Si le simulateur doit être dissocicé de l'audience,
423
+ // il sera dans le dernier groupe de la table des possibles.
424
+ if (jeSuisUneAudience) {
425
+ // Le simulateur simule l'audience.
426
+ // Il se comporte comme tout le monde, avec le groupe que le serveur assigne
427
+ monGroupe = msgRecu.noDeGroupe;
428
+ if (debug) console.log("SIMULATION DE L'AUDIENCE");
429
+ } else if (!par.simulatorInAseperateGroup) {
430
+ // Je suis ne pas un simulateur de l'audience
431
+ // et la config n'a pas prévu de simulateur indépendant de l'audience.
432
+ // On force un comportement de simulateur d'audience.
433
+ console.log("WARN: le simulateur demande à être indépendant, mais ce n'est pas prévu dans la configuration");
434
+ monGroupe = msgRecu.noDeGroupe;
435
+ } else {
436
+ // La config a prévu un simulateur indépendant de l'audience
437
+ // et je ne suis pas un simulateur d'audience.
438
+ // Je définis mon groupe en m'attribuant donc le dernier groupe de client
439
+ // Ceci est redondant avec le serveur dans ce cas qui fournit aussi le même groupe
440
+ // resérvé.
441
+ console.log("SIMULATION INDEPENDANTE DE L'AUDIENCE");
442
+ monGroupe = par.nbeDeGroupesClients - 1;
443
+ }
444
+ if (debug1) console.log("INFO: Simulator in group:", monGroupe, "pseudo:", pseudo);
445
+ actionSurDAWON();
446
+ break;
447
+
448
+ case "groupeClientStatus":
449
+ if (debug) console.log("Reçu Broadcast: groupeClientStatus:", msgRecu, msgRecu.groupeClient);
450
+ if (msgRecu.groupeClient == monGroupe || msgRecu.groupeClient == 255) {
451
+ actionSurGroupeClientStatus(msgRecu.groupeName, msgRecu.status);
452
+ }
453
+ break;
454
+
455
+ case "infoPlayDAW":
456
+ if (debug) console.log("Reçu Texte Broadcast infoPlayDAW:", msgRecu.value);
457
+ break;
458
+
459
+ case "listClips":
460
+ listClips = msgRecu.listClips;
461
+ if (listClips === -1) {
462
+ if (debug) console.log("WS Recu : listClips: groupe de client inexistant", listClips);
463
+ break;
464
+ }
465
+
466
+ if (listClips === undefined) {
467
+ if (debug) console.log("WS Recu : listClips: undefined, pas de clip");
468
+ break;
469
+ }
470
+
471
+ if (listClips.length === 0) {
472
+ if (debug) console.log("WS Recu : listClips vide");
473
+ if (tempoMax === tempoMin) {
474
+ console.log("WARN: tempoMin and tempoMax are equal");
475
+ tempoInstantListClip = tempoMax;
476
+ }
477
+ else {
478
+ tempoInstantListClip = Math.floor(parseInt(tempoMin) + parseInt((Math.random() * (tempoMax - tempoMin))));
479
+ }
480
+ if (debug) console.log("Simulateur : TEMPO INSTANT LIST CLIP:", tempoInstantListClip, tempoMax, tempoMin);
481
+ if (DAWON) setTimeout(function () {
482
+ selectListClips(); // Envoie une demande des clips dispos au serveur
483
+ },
484
+ tempoInstantListClip);
485
+ break;
486
+ }
487
+
488
+ // Selection de clips dans la liste
489
+ if (debug) console.log("\n--- Simulateur Recu : listClips 1ere ligne:", listClips[0][4], "Nombre clip dispo:", listClips.length);
490
+ var sequenceLocale = [];
491
+
492
+ if (processTypes) {
493
+ setListOfTypes(listClips);
494
+ sequenceLocale = getListOfPatternsSelected(listOfTypes, types, listClips);
495
+ if (debug) console.log("Simulateur: sequence selon les types:", sequenceLocale);
496
+ } else {
497
+ for (var i = 0; i < nombreDePatternsPossible; i++) {
498
+ //Version qui évite trop de répétitions
499
+ numClip = selectNextClip();
500
+ sequenceLocale[i] = numClip;
501
+ // On a une liste
502
+ if (debug) console.log("--- Simulateur Recu : listClips: choisi", numClip, " : ", listClips[numClip][4], "\n");
503
+ }
504
+ }
505
+
506
+ // Emission de la liste
507
+ if (debug) console.log("-- simulateur : sendPatternSequence: attente:", dureeAttente, limiteDureeAttente);
508
+ if (dureeAttente < limiteDureeAttente) { // On est dans des délais raisonnables
509
+ if (debug) console.log("-- sendPatternSequence", sequenceLocale, pseudo);
510
+ ws.send(JSON.stringify({
511
+ type: "sendPatternSequence",
512
+ patternSequence: sequenceLocale,
513
+ pseudo: pseudo,
514
+ groupe: monGroupe,
515
+ idClient: id
516
+ }));
517
+ } else {
518
+ dureeAttente = 0;
519
+ }
520
+
521
+ tempoInstantListClip = Math.floor(parseInt(tempoMin) + parseInt((Math.random() * (tempoMax - tempoMin))));
522
+ if (debug) console.log("TEMPO INSTANT LIST CLIP:", tempoInstantListClip, pseudo);
523
+ if (DAWON) setTimeout(function () {
524
+ selectListClips();
525
+ },
526
+ tempoInstantListClip);
527
+ break;
528
+
529
+ case "listeDesTypes":
530
+ types = msgRecu.text.split(',');
531
+ for (var i = 0; i < types.length; i++) {
532
+ types[i] = parseInt(types[i]);
533
+ }
534
+ if (debug1) console.log("Simulator: List of Types:", types);
535
+ break;
536
+
537
+ case "message":
538
+ if (debug) console.log(msgRecu.text);
539
+ break;
540
+
541
+ case "nombreDePatternsPossible":
542
+ nombreDePatternsPossible = getnombreDePatternsPossible(msgRecu.value, monGroupe);
543
+ if (debug1) console.log("Simulator: nombreDePatternsPossible:", nombreDePatternsPossible);
544
+ break;
545
+
546
+ case "nombreDePatternsPossibleEnListe":
547
+ nombreDePatternsPossible = getnombreDePatternsPossible(msgRecu.nombreDePatternsPossible, monGroupe);
548
+ if (debug1) console.log("Simulator : nombreDePatternsPossible:nombreSonsPossibleInit ", nombreDePatternsPossible);
549
+ break;
550
+
551
+ case "patternSequenceAck":
552
+ if (debug) console.log("Reçu socket : patternSequenceAck: score ", msgRecu.score);
553
+ break;
554
+
555
+ case "setListeDesTypes":
556
+ if (debug1) console.log("Simulator: Set the type list")
557
+ processTypes = true;
558
+ break;
559
+
560
+ case "texteServeur":
561
+ if (debug) console.log("Reçu Broadcast:", msgRecu.value);
562
+ break;
563
+
564
+ case "unsetListeDesTypes":
565
+ if (debug1) console.log("Simulator: Unset the type list")
566
+ processTypes = false;
567
+ break;
568
+
569
+ default: if (debug) console.log("Le simulateur reçoit un message inconnu", msgRecu);
570
+ break;
571
+ }
572
+ };
573
+
574
+ ws.onerror = function (event) {
575
+ console.log("simulateur.js : received ERROR on WS");
576
+ }
577
+
578
+ ws.onclose = function (event) {
579
+ console.log("INFO: simulateurFork.js : on CLOSE on WS");
580
+ }
581
+ }
582
+
583
+ //- Attention d'avoir initialisation avant de faire server.addEventListener('DAWStatus', function( event )---
584
+ // Cette fonction de remise à jour de l'affichage est appelée sur plusieurs évènements :
585
+ // onload, Modif DAW, Modif sur groupe de sons, reconnexion, rechargement de la page.
586
+
587
+ export function initialisation() {
588
+ if (debug) console.log("simulateur.js:initialisation: PSEUDO ", pseudo);
589
+ sendPseudo(pseudo);
590
+ }
591
+
592
+ export function init(port) {
593
+ initWSSocket(port);
594
+ }
595
+
596
+ function actionSurDAWON() {
597
+ if (DAWON == false) {
598
+ if (debug) console.log("simulateur.js:actionSurDAWON:false");
599
+ initialisation();
600
+ return;
601
+ }
602
+
603
+ if (debug) console.log("simulateur.js:actionSurDAWON:true:", DAWON);
604
+ initialisation(); //Pour le cas où le client recharge sa page en cours d'interaction
605
+ selectListClips(); // Pour le déclenchement de la simulation
606
+ }
607
+
608
+ function actionSurGroupeClientStatus(sons, status) {
609
+ if (DAWON == false) {
610
+ if (debug) console.log("simulateur.js:actionSurGroupeClientStatus:DAWON:false");
611
+ initialisation();
612
+ return;
613
+ }
614
+ if (debug) console.log("WS actionSurGroupeClientStatus:", monGroupe);
615
+
616
+ if (sons == "" || sons == undefined) {
617
+ } else {
618
+ if (status) {
619
+ }
620
+ }
621
+ }
622
+
623
+ //========== Controle des CLIPS =================================
624
+ function selectListClips() { // selecteurV2
625
+ if (debug) console.log("simulateur: selectListClips: groupe", monGroupe);
626
+ ws.send(JSON.stringify({
627
+ type: "selectAllClips",
628
+ groupe: monGroupe
629
+ }));
630
+ }
631
+
632
+ // Demande au serveur de lancer le clip
633
+ var compteurTest = 0;
634
+ // export function startClip(indexChoisi) {
635
+
636
+ // if (indexChoisi == -1) return -1; // Protection sur un choix sans selection au départ
637
+ // msg.pseudo = pseudo; //noms[index];
638
+
639
+ // msg.type = "DAWStartClip";
640
+ // msg.clipChoisi = listClips[indexChoisi];
641
+
642
+ // compteurTest++;
643
+ // console.log("startClip:", compteurTest, " :", listClips[indexChoisi][3], "par", pseudo);
644
+ // //msg.pseudo = pseudo;
645
+ // msg.groupe = monGroupe;
646
+ // ws.send(JSON.stringify(msg));
647
+ // indexChoisi = -1;
648
+ // }
649
+
650
+ // ========================= Lancement du simulateur =================
651
+ process.on('message', (message) => {
652
+ // This is necessary, I dont know why. Otherwise I have an erro on message in the switch
653
+ // ReferenceError: Cannot access 'message' before initialization
654
+ var messageLocal = message;
655
+
656
+ if (debug) console.log("INFO: Simulator message : ", messageLocal);
657
+
658
+ switch (messageLocal.type) {
659
+ case 'START_SIMULATOR':
660
+ //console.log('Simulator received START message');
661
+ init(port);
662
+ setTimeout(() => selectListClips(), 500);
663
+ let message = `Simulation Launched by ${pseudo}`;
664
+ process.send(message);
665
+ break;
666
+
667
+ case 'PARAMETERS':
668
+ if (debug) console.log("INFO: Simulator parameters : ", messageLocal.data.groupesDesSons[0]);
669
+ par = messageLocal.data;
670
+ initTempi();
671
+ break;
672
+
673
+ case 'STOP_SIMULATOR':
674
+ if (debug1) console.log("INFO: simulateurFork.js : Simulator Stopped");
675
+ ws.close();
676
+ process.exit(0);
677
+ break;
678
+
679
+ default: console.log("INFO: Fork Simulator: Type de message inconnu : ", messageLocal);
680
+ }
681
+ });