├── LICENSE ├── OSCBPM.js ├── OSCRTMGC.js ├── OSCRTMMD.js ├── README.md ├── RealTime.noisette ├── RealTimeLEDFX.noisette ├── RealTimeWLED.noisette ├── RealTimeWLEDLedFX.noisette ├── Snapshot_1680949776.csv ├── Snapshot_1681488887.csv ├── Snapshot_1682072453.csv ├── WLEDAudioSync.js ├── WLEDAudioSync30.ico ├── aubio.cmd ├── friture.cmd ├── icon.png ├── labels.txt ├── module.json ├── multicast.cmd ├── rtmgc.cmd └── rtmmd.cmd /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 zak-45 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OSCBPM.js: -------------------------------------------------------------------------------- 1 | /* 2 | a: zak45 3 | d: 07/04/2023 4 | v: 2.0.0 5 | 6 | Script to detect each Beat from aubio via osc 7 | From odd to even. 8 | Provide list of probable genres. 9 | To be used with WLEDAudioSync module. 10 | 11 | */ 12 | 13 | var newOSCRTContainer = ''; 14 | var soundCardModule = root.modules.soundCard; 15 | var beat = ''; 16 | var beat_SC = ''; 17 | var beat_Exist = false; 18 | var prob = ''; 19 | var bpm_Value = 0; 20 | 21 | function init() 22 | { 23 | local.register("/WLEDAudioSync/beat/BPM", "OSCBPM"); 24 | newOSCRTContainer = local.addContainer("WLEDAudioSync"); 25 | beat = newOSCRTContainer.addBoolParameter("Beat", "Beat odd even", true); 26 | if (soundCardModule.name != "undefined") 27 | { 28 | beat_SC = soundCardModule.values.addBoolParameter("Beat", "Beat odd even", true); 29 | beat_SC.setAttribute("readOnly", true); 30 | bpm_SC = soundCardModule.values.addFloatParameter("BPM", "Beat Per Minute", 0); 31 | bpm_SC.setAttribute("readOnly", true); 32 | beat_Exist = true; 33 | } 34 | prob = newOSCRTContainer.addStringParameter("ProbGenre", "List of Probable playing music genres based on the BPM", '[]'); 35 | 36 | } 37 | 38 | function OSCBPM(address, args) 39 | { 40 | 41 | //script.log("Received message : "+ address + " with value of : " + args[0]); 42 | 43 | bpm_Value = parseInt(local.values._WLEDAudioSync_beat_BPM.get()); 44 | 45 | if (beat.get() == 0) 46 | { 47 | beat.set(1); 48 | if (beat_Exist) 49 | { 50 | beat_SC.set(1); 51 | bpm_SC.set(bpm_Value); 52 | root.modules.wLEDAudioSync.values.beat.set(1); 53 | } 54 | 55 | 56 | } else { 57 | 58 | beat.set(0); 59 | if (beat_Exist) 60 | { 61 | beat_SC.set(0); 62 | root.modules.wLEDAudioSync.values.beat.set(0); 63 | } 64 | } 65 | 66 | prob.set(getProbableGenres(bpm_Value)); 67 | } 68 | 69 | // We take the BPM to obtain a list of genre probability, based on medium values. 70 | // could be associated to RTMGC 71 | function getProbableGenres (bpm) 72 | { 73 | // Name: min BPM, max BPM 74 | var genres = [ 75 | 'Ambient: 60, 100', 76 | 'Bachata: 128, 128', 77 | 'Ballad: 60, 80', 78 | 'Blues: 60, 120', 79 | 'Blues Rock: 100, 120', 80 | 'Classical: 60, 120', 81 | 'Country: 60, 120', 82 | 'Crunk: 80, 80', 83 | 'Cumbia: 70, 80', 84 | 'Disco: 110, 140', 85 | 'Deep House: 120, 125', 86 | 'Down Tempo: 70, 100', 87 | 'Drum n Bass: 160, 180', 88 | 'Dubstep: 130, 150', 89 | 'Electro House: 125, 130', 90 | 'Electronic: 120, 140', 91 | 'Eurodance: 126, 132', 92 | 'Euro House: 126, 130', 93 | 'Frenchcore: 200, 210', 94 | 'Folk: 90, 130', 95 | 'Funk: 90, 120', 96 | 'Funk Metal: 115, 130', 97 | 'Funky House: 128, 136', 98 | 'Hard Rock: 122, 160', 99 | 'Heavy Metal: 100, 135', 100 | 'Hip Hop: 85, 115', 101 | 'House: 120, 130', 102 | 'Indie: 100, 160', 103 | 'Jazz: 80, 140', 104 | 'Latin: 90, 130', 105 | 'Louisiana Blues: 80, 120', 106 | 'Makina: 150, 190', 107 | 'Metal: 100, 200', 108 | 'New Beat: 110, 120', 109 | 'Pop: 90, 130', 110 | 'Psytrance: 140, 145', 111 | 'Punk: 150, 200', 112 | 'R&B: 60, 100', 113 | 'Rap: 90, 100', 114 | 'Reggae: 60, 110', 115 | 'Reggaeton: 80, 90', 116 | 'Rock: 100, 160', 117 | 'Salsa: 150, 250', 118 | 'Soul: 60, 120', 119 | 'Synth-pop: 90, 130', 120 | 'Tango: 50, 56', 121 | 'Tech House: 120, 135', 122 | 'Techno: 120, 140', 123 | 'Techno Hardcore: 170, 200', 124 | 'Trap: 139, 141', 125 | 'Trance: 130, 150', 126 | 'Tribe: 145, 180', 127 | 'Trip Hop: 60, 120', 128 | 'UK Garage: 130, 135' 129 | ]; 130 | 131 | var probableGenres = ""; 132 | 133 | for (var i = 0; i < genres.length; i ++) { 134 | var genre = genres[i].split(':'); 135 | var bpmRange = genre[1].split(','); 136 | if (bpm >= parseInt(bpmRange[0]) && bpm <= parseInt(bpmRange[1])) { 137 | probableGenres = probableGenres + genre[0] + ","; 138 | } 139 | } 140 | 141 | return probableGenres.substring(0,probableGenres.length-1); 142 | } 143 | -------------------------------------------------------------------------------- /OSCRTMGC.js: -------------------------------------------------------------------------------- 1 | /* 2 | a: zak45 3 | d: 05/05/2023 4 | v: 1.1.0 5 | 6 | Script to create Container values from received JSON via OSC. 7 | Used for Real Time Music Genre Classification from ESSENTIA.js 8 | Designed for WLEDAudioSync module. 9 | 10 | */ 11 | 12 | var newOSCRTMGCContainer = ''; 13 | var names = []; 14 | var mostProbGenre = ''; 15 | 16 | function init () 17 | { 18 | local.register("/WLEDAudioSync/RTMGC", "OSCRTMGC"); 19 | newOSCRTMGCContainer = local.addContainer("WLEDAudioSync"); 20 | mostProbGenre = newOSCRTMGCContainer.addStringParameter("Most Probable Genre", "Most detected genre name, to be used with only one id", ''); 21 | } 22 | 23 | // update data, Top 5 predictions, from 1st to 5th 24 | // and populate 'names' dict to determine the Most Probable Genre 25 | function OSCRTMGC (address, args) 26 | { 27 | // script.log("Received message : "+ address + " with value of : " + args[0]); 28 | 29 | var includefirstOnly = true; 30 | 31 | var testAllPredictions = util.getObjectProperties(root.modules.wLEDAudioSync.parameters.rtmgcParams.includeAllPredictions); 32 | if (testAllPredictions) 33 | { 34 | var testAll = root.modules.wLEDAudioSync.parameters.rtmgcParams.includeAllPredictions.get(); 35 | if (testAll == 1) 36 | { 37 | includefirstOnly = false; 38 | } 39 | } 40 | 41 | names = []; 42 | 43 | var rtmgcJsonData = JSON.parse(args[0]); 44 | var id = rtmgcJsonData.WLEDAudioSync.id; 45 | 46 | var rtmgcToUpdate = newOSCRTMGCContainer.getChild("RTMGC " + id); 47 | 48 | if ( rtmgcToUpdate.name != "undefined" ) { 49 | 50 | rtmgcToUpdate.timestamp.set(rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.TimeStamp); 51 | 52 | var j = 0; 53 | for (var i = 0; i < 5; i++) 54 | { 55 | j = i + 1 ; 56 | var parentGenre = rtmgcToUpdate.predictions.getChild("parentGenre"+j); 57 | parentGenre.set(rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.Predictions[i].parentGenre); 58 | var name = rtmgcToUpdate.predictions.getChild("name"+j); 59 | name.set(rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.Predictions[i].name); 60 | 61 | if (includefirstOnly === true && i == 0) 62 | { 63 | names[0] = rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.Predictions[0].name; 64 | 65 | } else if (includefirstOnly === false) { 66 | 67 | names[i] = rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.Predictions[i].name; 68 | } 69 | 70 | var score = rtmgcToUpdate.predictions.getChild("score"+j); 71 | score.set(rtmgcJsonData.WLEDAudioSync.RTMGCDiscogs.Predictions[i].score); 72 | } 73 | 74 | mostProbGenre.set(mostProb()); 75 | 76 | } else { 77 | 78 | createRTMGC (id); 79 | 80 | } 81 | } 82 | 83 | // create container for the unique id received from sender 84 | function createRTMGC (id) 85 | { 86 | var newidRTMGCContainer = newOSCRTMGCContainer.addContainer("RTMGC " + id); 87 | newidRTMGCContainer.addStringParameter('Timestamp','Timestamp from generated message', ''); 88 | var newPredictions = newidRTMGCContainer.addContainer("Predictions"); 89 | 90 | for (var i = 1; i < 6; i ++) 91 | { 92 | var newStrPar = newPredictions.addStringParameter('parentGenre'+i,'Parent',''); 93 | newStrPar.setAttribute("saveValueOnly", false); 94 | var newStrPar = newPredictions.addStringParameter('name'+i,'Name',''); 95 | newStrPar.setAttribute("saveValueOnly", false); 96 | var newFloatPar = newPredictions.addFloatParameter('score'+i,'Score: bigger, better',0.0); 97 | newFloatPar.setAttribute("saveValueOnly", false); 98 | } 99 | } 100 | 101 | // Found the most Probable genre name 102 | function mostProb() 103 | { 104 | var includeBPM = false; 105 | // test BPM param exist 106 | var testBPM = util.getObjectProperties(root.modules.wLEDAudioSync.parameters.rtmgcParams.includeBPMData); 107 | if (testBPM) 108 | { 109 | var test = root.modules.wLEDAudioSync.parameters.rtmgcParams.includeBPMData.get(); 110 | if ( test == 1) 111 | { 112 | includeBPM = true; 113 | 114 | } 115 | } 116 | // generate all genres name detected 117 | // check to see if BPM present and true to append 118 | if (newOSCRTMGCContainer.probGenre.name != "undefined" && includeBPM === true) 119 | { 120 | var namesBPM = newOSCRTMGCContainer.probGenre.get().split(','); 121 | var namesLength = names.length; 122 | for ( var j = 0; j < namesBPM.length; j++) 123 | { 124 | names[namesLength+j] = namesBPM[j]; 125 | } 126 | } 127 | 128 | // found unique names 129 | var uniqueNames = []; 130 | var j = 0; 131 | for ( var i = 0; i < names.length; i++) 132 | { 133 | if ( !uniqueNames.contains(names[i]) ) 134 | { 135 | uniqueNames[j] = names[i]; 136 | j = j + 1; 137 | } 138 | } 139 | 140 | // calculate occurence by name 141 | var occurrences = []; 142 | for ( var i = 0 ; i < uniqueNames.length; i++ ) 143 | { 144 | var numberOccurrence = 0; 145 | for (var j = 0 ; j < names.length ; j++) 146 | { 147 | if (uniqueNames[i] == names[j]) 148 | { 149 | numberOccurrence = numberOccurrence + 1; 150 | } 151 | } 152 | 153 | occurrences[i] = uniqueNames[i] + ":" + numberOccurrence ; 154 | } 155 | 156 | var nameMostSeen = ""; 157 | var maxOccurrences = 0; 158 | 159 | // found the one most present 160 | for ( var i = 0; i < occurrences.length; i++ ) 161 | { 162 | occurrenceName = occurrences[i].split(':')[0]; 163 | occurrenceByName = occurrences[i].split(':')[1]; 164 | if (occurrenceByName > maxOccurrences) 165 | { 166 | maxOccurrences = occurrenceByName; 167 | nameMostSeen = occurrenceName; 168 | } 169 | } 170 | 171 | return nameMostSeen; 172 | } -------------------------------------------------------------------------------- /OSCRTMMD.js: -------------------------------------------------------------------------------- 1 | /* 2 | a: zak45 3 | d: 18/10/2023 4 | v: 1.0.0 5 | 6 | Script to create Container values from received JSON via OSC. 7 | Used for Real Time Music Mood Detection. 8 | Designed for WLEDAudioSync module. 9 | 10 | // Mood 11 | var disgust_pos = [-0.9, 0]; 12 | var angry_pos = [-0.5, 0.5]; 13 | var alert_pos = [0, 0.5]; 14 | var happy_pos = [0.5, 0.5]; 15 | var calm_pos = [0.4, -0.4]; 16 | var relaxed_pos = [0, -0.6]; 17 | var sad_pos = [-0.5, -0.5]; 18 | var neu_pos = [0.0, 0.0]; 19 | 20 | */ 21 | 22 | var newOSCRTMMDContainer = ''; 23 | var moodColor = ''; 24 | 25 | function init () 26 | { 27 | // script callback 28 | local.register("/WLEDAudioSync/mood/data", "OSCRTMMDData"); 29 | local.register("/WLEDAudioSync/mood/color", "OSCRTMMDColor"); 30 | // Main container 31 | newOSCRTMMDContainer = local.addContainer("WLEDAudioSync"); 32 | newOSCRTMMDContainer.addColorParameter("Music Mood Color", "Respective Color from detected music mood", [1,0,1]); 33 | newOSCRTMMDContainer.addStringParameter("Mood", "Detected mood name", 'neutral'); 34 | // Mood Data container 35 | var newRTMMDDataContainer = newOSCRTMMDContainer.addContainer("Mood Data"); 36 | newRTMMDDataContainer.addStringParameter("win_class",'win_class',''); 37 | newRTMMDDataContainer.addStringParameter("win_class_energy",'win_class_energy',''); 38 | newRTMMDDataContainer.addStringParameter("win_class_valence",'win_class_valence',''); 39 | newRTMMDDataContainer.addFloatParameter("soft_valence",'soft_valence',0); 40 | newRTMMDDataContainer.addFloatParameter("soft_energy",'soft_energy',0); 41 | } 42 | 43 | // set Data 44 | function OSCRTMMDData (address, args) 45 | { 46 | // script.log("Received message : "+ address + " with value of : " + args[0]); 47 | 48 | var rtmmddJsonData = JSON.parse(args[0]); 49 | local.wLEDAudioSync.moodData.win_class.set(rtmmddJsonData.win_class); 50 | local.wLEDAudioSync.moodData.win_class_energy.set(rtmmddJsonData.win_class_energy); 51 | local.wLEDAudioSync.moodData.win_class_valence.set(rtmmddJsonData.win_class_valence); 52 | local.wLEDAudioSync.moodData.soft_valence.set(rtmmddJsonData.soft_valence); 53 | local.wLEDAudioSync.moodData.soft_energy.set(rtmmddJsonData.soft_energy); 54 | 55 | // retreive Mood 56 | local.wLEDAudioSync.mood.set(detectMood(rtmmddJsonData.soft_valence, rtmmddJsonData.soft_energy)); 57 | } 58 | 59 | // set Color 60 | function OSCRTMMDColor (address, args) 61 | { 62 | // script.log("Received message : "+ address + " with value of : " + args[0]); 63 | 64 | var rtmmdcJsonData = JSON.parse(args[0]); 65 | local.wLEDAudioSync.musicMoodColor.set([rtmmdcJsonData.R / 255, rtmmdcJsonData.G / 255, rtmmdcJsonData.B / 255]); 66 | } 67 | 68 | // util 69 | 70 | // returned value is not supposed represent real mood 71 | // only a extraprolation from visual representation 72 | function detectMood(x, y) 73 | { 74 | // white (neutral 75 | if (x <= 0.2 && x >= -0.2 && y <= 0.2 && y >= -0.2) { 76 | 77 | return "neutral"; 78 | 79 | // yellow (happy) 80 | } else if (x >= 0 && y >= 0) { 81 | 82 | if ( x >= 0.4 && y >= 0.4){ 83 | return "joy"; 84 | } else if ( y >= 0.6) { 85 | return "extase"; 86 | } else { 87 | return "serenity"; 88 | } 89 | // blue (sad) 90 | } else if (x <= 0 && y <= 0) { 91 | 92 | if ( x <= -0.9 && y <= 0.2 && y >= -0.2) { 93 | return "disgust"; 94 | } else if (x <= -0.4 && y <= -0.4){ 95 | return "sad"; 96 | } else { 97 | return "pensinve"; 98 | } 99 | // red (angry) 100 | } else if (x <= 0 && y >= 0) { 101 | 102 | if ( x <= -0.9 && y <= 0.2 && y >= -0.2) { 103 | return "disgust"; 104 | } else if ((x <= -0.4 && y >= 0.4) || y >= 0.6){ 105 | return "rage"; 106 | } else { 107 | return "angry"; 108 | } 109 | // green (relax) 110 | } else if (x >= 0 && y <= 0) { 111 | 112 | if ( x <= 0.4 && y <= -0.4) { 113 | return "relax"; 114 | } else { 115 | return "calm"; 116 | } 117 | 118 | } else { 119 | 120 | return "Error : No mood defined ...."; 121 | } 122 | } 123 | 124 | function test () 125 | { 126 | 127 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![image](https://user-images.githubusercontent.com/121941293/283798323-94bb9a2c-65b0-4d98-a483-e49d4d9b0eb1.png)](http://benjamin.kuperberg.fr/chataigne/en) **+** ![image](https://user-images.githubusercontent.com/121941293/227901678-8f3d1f7c-ae1d-4b85-8199-5b763ec91a5b.png) **=** 2 | # **WLEDAudioSync Module for Chataigne.** 3 | 4 | ## Stream music/audio datas to WLED Audio reactive. 5 | 6 | **Real time audio analysis** : the real time audio datas are not supposed to be fully accurate for scientific works but enough for light show creation. 7 | See : https://youtu.be/YtS6dwke0LE 8 | 9 | _Should work on any OS where Chataigne is running._(Win/Mac/Linux) 10 | 11 | ***This can be used with or without WLED device*** 12 | 13 | As options: 14 | 15 | - **Real Time Beat/ BPM** sent to OSC 16 | 17 | - **Real Time Music Genre Classification** sent to OSC : get real-time music genre predictions based on the analysed audio stream. 18 | 19 | - **Real Time Music Mood Detection** sent to OSC: set Colors based on the music mood. 20 | 21 | All features: 22 | 23 | ``` 24 | - Send your music from any computer to WLED sound reactive LED. 25 | 26 | - Should Work on any OS where Chataigne run ( Win/Mac/Linux/Pi ). 27 | 28 | - You only need to have WLED Sound Reactive version installed. 29 | No Hardware( micro: analog or digital) required. 30 | 31 | - Use UDP Multicast, so your LED strip can be anywhere. 32 | adjustable rate let you choose between bandwidth / reactivity 33 | 34 | - Send different message version, to different UDP port with different settings at same time 35 | thanks to Chataigne's Multiple Instances feature. 36 | 37 | - Capture audio datas ( snapshot ) and replay them ( replay ). 38 | 39 | - All WLED Sound Reactive effects supported: volume based or FFT based. 40 | 41 | - Message version 1 (V1) and version 2 (V2) included, so can stream even to ESP8266 42 | 43 | - Real time FFT Analysis fully customisable by GUI 44 | this provide different way for effects customisation. 45 | 46 | - Real time pitch detection : freq / pitch / note / octave 47 | thanks to Chataigne... 48 | 49 | - Real Time audio analysis : 50 | thanks to https://friture.org/ 51 | 52 | - Real Time Beat and BPM send data via OSC 53 | thanks to https://github.com/DrLuke/aubio-beat-osc 54 | 55 | - Real Time Music Genre Classification send data via OSC 56 | thanks to Essentia.js https://mtg.github.io/essentia.js/ 57 | 58 | - Real Time Music Mood Detection send data via OSC 59 | thanks to : https://github.com/tyiannak/color_your_music_mood 60 | 61 | ``` 62 | 63 | For Chataigne : http://benjamin.kuperberg.fr/chataigne/en#download --> min version 1.9.17b10 64 | 65 | For beat / BPM see : https://github.com/zak-45/WLEDAudioSyncRTBeat 66 | 67 | For Friture see : https://friture.org/ 68 | 69 | For RMTGC see: https://github.com/zak-45/WLEDAudioSyncRTMGC 70 | 71 | For RTMMD see: https://github.com/zak-45/WLEDAudioSyncRTMood 72 | 73 | --- 74 | 75 | ## ***Installation :*** 76 | 77 | ### For Windows 78 | 79 | Download release : [Windows Installer](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/releases) 80 | 81 | You have two options : 82 | 83 | 84 | -1- **WLEDAudioSync.exe** provide full installation, options : 85 | 86 | ``` 87 | This will install chataigne module / and optionally : Chataigne && all portable apps e.g. Friture / WrtmgcSRV ... 88 | 89 | Nota : Provide portable Nodejs with WrtmgcSRV.js preconfigured (optional but recommanded to use RTMGC). 90 | ``` 91 | 92 | -2- **WLEDAudioSync-Portable.zip** is a 'portable' version : 93 | 94 | If you want only to use the WLED audio sync feature in a easy way, this one is for you. 95 | 96 | ``` 97 | Just unzip it and execute WLEDAudioSync.cmd. 98 | This will do all necessary steps to have a running Chataigne with Beat detection. 99 | No installation, only required folder creation (done when first time run it). 100 | --- Check "%USERPROFILE%\Documents\Chataigne" folder 101 | ``` 102 | 103 | You need to accept the unknown app and allow firewall 104 | 105 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/2ea134a3-d14a-46d2-a4f2-43783be65f71) 106 | 107 | 108 | 109 | ### Manual (any OS with Chataigne installed) 110 | ``` 111 | Take all from this repository and 112 | Copy to \chataigne\modules\WLEDAudioSync. 113 | 114 | This is enough if you want to use WLED audio sync only. 115 | ``` 116 | 117 | _Options_ 118 | ``` 119 | You will need additional step for beat / BPM / RTMGC or RTMMD if you want to use these features. 120 | For BPM, you can download binary from https://github.com/zak-45/WLEDAudioSyncRTBeat 121 | For RTMGC, you can download binary from https://github.com/zak-45/WLEDAudioSyncRTMGC 122 | For RTMMD, you can download binary from https://github.com/zak-45/WLEDAudioSyncRTMood 123 | To use integrated tools (not mandatory), you need to customize : 124 | rtmmd.cmd, rtmgc.cmd, aubio.cmd, friture.cmd, multicast.cmd 125 | 126 | ``` 127 | ---- 128 | 129 | ## ***Use it (Win 'portable' version):*** 130 | 131 | Open folder with unzipped files and click on **WLEDAudioSync.cmd** 132 | 133 | 134 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/0b7d3499-e97e-4347-a609-2158119f9793) 135 | 136 | 137 | You will be able to found the running program under 'hidden icons': 138 | 139 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/fcf70fbb-6c32-46d4-a624-0bed09f3b155) 140 | 141 | 142 | 143 | If you "left - click" on it, this will open the main interface. ("right - click" is for EXIT) : 144 | 145 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/4035170d-7c2f-4c64-b57b-9441dfa07a84) 146 | 147 | 148 | 149 | From there, you will be able to modify settings /parameters. This should be necessary only the first time to put your audio parameters and the defaults one e.g. run at startup, minimized etc ... 150 | 151 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/41fbfb01-15e7-46df-8690-8de416b73f86) 152 | 153 | 154 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/cd494688-f6ab-4826-920c-5c93a9647896) 155 | 156 | 157 | If you want to be able to acces main dashboard menu via a Web Browser : 158 | 159 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/107b195e-7f2f-49d3-83a4-1ddc3815a392) 160 | 161 | 162 | Once done, click on save and close Chataigne with the 'cross X' 163 | 164 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/d9dbde16-de6e-4f54-a096-bdff43fe6d47) 165 | 166 | 167 | 168 | You are ready now to send your audio datas to any WLED device with audio reactive firmware configured to receive them. 169 | 170 | If you want to modify data sent, you can access the main features from any web browser, this mean even from your phone / tablet, by entering the IP address of your running PC and port number '9998' e.g. http://192.168.x.y:9998 171 | 172 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/6ae987e5-57ea-46f0-bb1d-d0c544e27d99) 173 | 174 | 175 | ## ***Use it (full options):*** 176 | 177 | ``` 178 | Open Chataigne. 179 | 180 | Go to Modules, right click, Protocol/Community Modules, WLEDAudioSync. 181 | ``` 182 | ![image](https://user-images.githubusercontent.com/121941293/227391581-d8341ed8-aeb0-4507-9ab9-d0bdd89a4c07.png) 183 | 184 | Initial settings with WLED : https://youtu.be/5Y2O9qGDVE0 185 | 186 | ``` 187 | On Inspector: 188 | 189 | Multicast Mode: need to be checked 190 | IP Address to bind: select the computer IP address if more than one. 191 | Send Test Message: if more than one network interface and had trouble to send data to MulticastGroup, click on it to send a test message. 192 | Live : use real time audio data, uncheck when want to use the replay feature. 193 | Visualize live audio : run Friture, live audio analyzer. 194 | Audio V1 : V1 message format 195 | Audio V2 : V2 message format ( to be used mainly ) 196 | Delay : delay in ms before sending audio data. audio data during delay are lost. 197 | Volume Multiplier : multiply Chataigne volume audio data before sent 198 | Frequency Magnitude Multiplier : multiply Chataigne FFT Magnitude data before sent 199 | Take snapshot : This will take audio datas snapshot and save them to file. Used by the replay feature. 200 | 201 | Local : send to local IP (127.0.0.1). This will freeze audio data to send. 202 | Remote Host : MulticastGroup address 203 | Remote Port : port number to bind 204 | 205 | Use BPM : will create corresponding process for Beat via OSC 206 | if unchecked and WLEDAudioSyncRTBeat process is running, this will kill it. 207 | Input audio : audio devices detected by WLEDAudioSyncRTBeat list command 208 | the one selected will be used when 'Force reload' clicked. 209 | Script file : script file name for OSC module 210 | use OSCBPM.js under modules folder. 211 | Force reload : kill (if running) and create a new WLEDAudioSyncRTBeat process. 212 | 213 | Use RTMGC : this will execute the Nodejs server and launch chrome 214 | Server Port : port number for the Nodejs server , default to 8000 215 | Script file: script file name for OSC module 216 | use OSCRTMGC.js under modules folder. 217 | 218 | Update Rate : frequence to send audio data message to WLED (fps) 219 | set rate from 1 fps to 1000 (for test stress: dangerous), 50 is recommended. 220 | 221 | ``` 222 | ![image](https://user-images.githubusercontent.com/121941293/227391790-5bddd576-7fdd-440a-b03e-cc8985c81764.png) 223 | 224 | ![image](https://user-images.githubusercontent.com/121941293/230686974-c077ef89-51f3-4a71-a101-e385d02b8aa6.png) 225 | 226 | ![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/d651b923-8cc5-4abf-b7c6-a8beecbadded) 227 | 228 | ``` 229 | On Command Tester, Replay / FFT : all WLEDAudioSync available commands 230 | 231 | Replay / Snapshot : provide you the possibility to 'replay' audio data from snapshot with defined duration (max 1500 ms). 232 | The snapshot is not limited to the played effect, you can change settings and/or effect. 233 | ``` 234 | ![image](https://user-images.githubusercontent.com/121941293/227524093-53dd4caa-0807-4d2f-a673-2ba36b40c21a.png) 235 | 236 | ![image](https://user-images.githubusercontent.com/121941293/227524612-29fdfaf6-22f0-438d-9aab-433358002675.png) 237 | 238 | 239 | ``` 240 | FFT / WLED : got two choices on how FFT data will be captured. OLD or NEW. 241 | / Custom : custom FFT data analysis capture with variable size. 242 | ``` 243 | 244 | ![image](https://user-images.githubusercontent.com/121941293/227527086-6d9b9d29-70e2-40ea-8e87-e5b547255a27.png) 245 | 246 | ![image](https://user-images.githubusercontent.com/121941293/227527270-46aeb219-3c6f-49b4-a337-e613d9f8b410.png) 247 | 248 | 249 | 250 | --- 251 | 252 | Let see that on the FFT Analysis Chataigne sound card Module. You can even do any modification you like afterward. 253 | 254 | NEW 255 | ![image](https://user-images.githubusercontent.com/121941293/227527762-76316aa2-4284-4c68-b6c2-b217abacf5fe.png) 256 | 257 | OLD 258 | ![image](https://user-images.githubusercontent.com/121941293/227594966-2d4ab958-761b-42dd-820a-dc676cb6c2b3.png) 259 | 260 | Custom / size 0.10 261 | ![image](https://user-images.githubusercontent.com/121941293/227595263-a79bf314-5c95-4ee0-90d1-04d3bd7d3b1c.png) 262 | 263 | 264 | --- 265 | 266 | 267 | Audio Configuration: 268 | 269 | Linux : https://wiki.ubuntu.com/record_system_sound 270 | 271 | Mac : https://github.com/ExistentialAudio/BlackHole 272 | 273 | Win : https://thegeekpage.com/stereo-mix/ 274 | 275 | For audio control, Voicemeeter is one of the best tools : https://voicemeeter.com/ 276 | 277 | https://user-images.githubusercontent.com/121941293/227597492-aff9c8a6-5314-4f5f-9825-353296f6ff28.mp4 278 | 279 | 280 | --- 281 | 282 | --- 283 | 284 | 285 | Real Time audio analysis: all values you see there can be used by State Machine or others and by scripts. 286 | 287 | 288 | https://user-images.githubusercontent.com/121941293/230689672-cc5d42c5-c94b-488a-aab2-aea43275ef82.mp4 289 | 290 | 291 | RTMGC : real time music genre detection. Detected music genre is sent to Chataigne via OSC. 292 | 293 | 294 | 295 | https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/958e140b-c4e1-4627-93b5-a1b53836775c 296 | 297 | --- 298 | 299 | LedFx demo 300 | 301 | Click here : https://youtu.be/yu8QgQlLT5g 302 | 303 | [![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/19165bed-26b6-47a9-99d7-b0846780ff2c)](https://youtu.be/yu8QgQlLT5g) 304 | 305 | 306 | --- 307 | 308 | WLED demo 309 | 310 | click here : https://youtu.be/NIcdctzx6TY?feature=shared 311 | 312 | [![image](https://github.com/zak-45/WLEDAudioSync-Chataigne-Module/assets/121941293/757030aa-e2d3-48e2-87db-651de051de63)](https://youtu.be/NIcdctzx6TY) 313 | 314 | 315 | --- 316 | 317 | ## ***Info *** 318 | 319 | This module use WLED Audio Sync feature to send data via UDP / Multicast. Message version 1 & 2 are provided. 320 | // On 10/03/2023: Multicast do not work as expected on Chataigne, mainly when more than one network card. Small python utility provided to bind on UDP port on specified IP address and join the MulticastGroup in case of. 321 | See : https://github.com/zak-45/WLEDAudioSyncMCast 322 | 323 | On 26/03/2023: 324 | for ESP8266, old SR WLED fw version required : 0.13.0b3 https://wled-install.github.io/. 325 | Port to the 0.14.xx version is on TO DO list... 326 | 327 | On 27/10/2024: WLED Beta 0.15.0b6 (160) include the Audio Reactive userModule, so now ESP8266 can act as UDP sync receiver for the audio. 328 | -------------------------------------------------------------------------------- /RealTime.noisette: -------------------------------------------------------------------------------- 1 | {"metaData": {"version": "1.9.17", "versionNumber": 67854}, "projectSettings": {"containers": {"dashboardSettings": {"parameters": [{"value": "/main", "controlAddress": "/showDashboardOnStartup", "enabled": false}, {"value": true, "controlAddress": "/enableDashboardServer"}, {"value": 9998, "hexMode": false, "controlAddress": "/serverPort"}]}, "customDefinitions": {}}}, "dashboardManager": {"parameters": [{"value": false, "controlAddress": "/editMode"}], "items": [{"niceName": "Main", "type": "BaseItem", "itemManager": {"parameters": [{"value": [800.0, 600.0], "controlAddress": "/canvasSize", "enabled": true}, {"value": [0.3529411852359772, 0.3529411852359772, 0.3529411852359772, 1.0], "controlAddress": "/backgroundColor"}], "items": [{"parameters": [{"value": [-338.0, -141.0], "controlAddress": "/viewUIPosition"}, {"value": [110.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/live", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/live", "controllable": "/modules/wLEDAudioSync/parameters/live"}, {"parameters": [{"value": [-338.0, -81.0], "controlAddress": "/viewUIPosition"}, {"value": [110.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/audioV1", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 1", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/audioV1", "controllable": "/modules/wLEDAudioSync/parameters/audioV1"}, {"parameters": [{"value": [-338.0, -19.0], "controlAddress": "/viewUIPosition"}, {"value": [110.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/audioV2", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 2", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/audioV2", "controllable": "/modules/wLEDAudioSync/parameters/audioV2"}, {"parameters": [{"value": [-189.0, -129.0], "controlAddress": "/viewUIPosition"}, {"value": [70.0, 150.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/takeSnapshot", "controlAddress": "/target"}, {"value": "SnapShot", "controlAddress": "/customText", "enabled": true}, {"value": 12, "hexMode": false, "controlAddress": "/textSize", "enabled": true}, {"value": "", "controlAddress": "/customImage", "enabled": false}], "niceName": "Item 5", "hideInEditor": true, "type": "DashboardTriggerItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/takeSnapshot", "controllable": "/modules/wLEDAudioSync/parameters/takeSnapshot"}, {"parameters": [{"value": [-338.0, -229.0], "controlAddress": "/viewUIPosition"}, {"value": [219.0, 56.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/enabled", "controlAddress": "/target"}, {"value": "Enable Audio Data", "controlAddress": "/customText", "enabled": true}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 6", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/enabled", "controllable": "/modules/soundCard/enabled"}, {"parameters": [{"value": [-86.0, -129.0], "controlAddress": "/viewUIPosition"}, {"value": [220.0, 150.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/scripts/wLEDAudioSync/updateRate", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": 12, "hexMode": false, "controlAddress": "/textSize", "enabled": false}, {"value": [0.3803921639919281, 0.2039215713739395, 0.03529411926865578, 1.0], "controlAddress": "/borderColor", "enabled": true}, {"value": false, "controlAddress": "/opaqueBackground"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 7", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/scripts/wLEDAudioSync/updateRate", "controllable": "/modules/wLEDAudioSync/scripts/wLEDAudioSync/updateRate"}, {"parameters": [{"value": [209.0, -129.0], "controlAddress": "/viewUIPosition"}, {"value": [132.0, 52.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/beatParams/useBPM", "controlAddress": "/target"}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 8", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/beatParams/useBPM", "controllable": "/modules/wLEDAudioSync/parameters/beatParams/useBPM"}, {"parameters": [{"value": [-26.0, -179.0], "controlAddress": "/viewUIPosition"}, {"value": [77.0, 24.0], "controlAddress": "/viewUISize"}, {"value": "Rate (FPS)", "controlAddress": "/text"}, {"value": 16.0, "customUI": 3, "controlAddress": "/size"}, {"value": [0.800000011920929, 0.6745098233222961, 0.2549019753932953, 1.0], "controlAddress": "/color"}], "niceName": "Comment", "hideInEditor": true, "type": "DashboardCommentItem"}, {"parameters": [{"value": [-338.0, 74.0], "controlAddress": "/viewUIPosition"}, {"value": [279.0, 190.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/volumeMultiplier", "controlAddress": "/target"}, {"value": [1.0, 1.0, 1.0, 1.0], "controlAddress": "/borderColor", "enabled": true}, {"value": [0.0117647061124444, 0.003921568859368563, 0.09019608050584793, 1.0], "controlAddress": "/backgroundColor", "enabled": true}, {"value": [0.5254902243614197, 0.01568627543747425, 0.01568627543747425, 1.0], "controlAddress": "/foregroundColor", "enabled": true}, {"value": "Rotary Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 3", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/volumeMultiplier", "controllable": "/modules/wLEDAudioSync/parameters/volumeMultiplier"}, {"parameters": [{"value": [62.0, 74.0], "controlAddress": "/viewUIPosition"}, {"value": [279.0, 190.0], "controlAddress": "/viewUISize"}, {"value": "/modules/wLEDAudioSync/parameters/frequencyMagnitudeMultiplier", "controlAddress": "/target"}, {"value": [0.6313725709915161, 0.6313725709915161, 0.6313725709915161, 1.0], "controlAddress": "/textColor", "enabled": false}, {"value": [1.0, 1.0, 1.0, 1.0], "controlAddress": "/borderColor", "enabled": true}, {"value": [0.007843137718737125, 0.1490196138620377, 0.1529411822557449, 1.0], "controlAddress": "/backgroundColor", "enabled": true}, {"value": [0.7058823704719543, 0.6941176652908325, 0.1294117718935013, 1.0], "controlAddress": "/foregroundColor", "enabled": true}, {"value": "Rotary Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 4", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/wLEDAudioSync/parameters/frequencyMagnitudeMultiplier", "controllable": "/modules/wLEDAudioSync/parameters/frequencyMagnitudeMultiplier"}, {"parameters": [{"value": [144.0, -31.0], "controlAddress": "/viewUIPosition"}, {"value": [197.0, 52.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/parameters/pitchDetectionMethod", "controlAddress": "/target"}, {"value": "Horizontal Bar", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 9", "hideInEditor": true, "type": "DashboardEnumParameterItem", "ghostAddress": "/modules/soundCard/parameters/pitchDetectionMethod", "controllable": "/modules/soundCard/parameters/pitchDetectionMethod"}, {"parameters": [{"value": [159.0, -67.0], "controlAddress": "/viewUIPosition"}, {"value": [40.0, 22.0], "controlAddress": "/viewUISize"}, {"value": "Pitch", "controlAddress": "/text"}], "niceName": "Comment 1", "hideInEditor": true, "type": "DashboardCommentItem"}, {"parameters": [{"value": [144.0, -229.0], "controlAddress": "/viewUIPosition"}, {"value": [197.0, 56.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/parameters/fftAnalysis/enabled", "controlAddress": "/target"}, {"value": "Enable FFT", "controlAddress": "/customText", "enabled": true}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 10", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/parameters/fftAnalysis/enabled", "controllable": "/modules/soundCard/parameters/fftAnalysis/enabled"}, {"parameters": [{"value": [-49.0, 84.0], "controlAddress": "/viewUIPosition"}, {"value": [101.0, 36.0], "controlAddress": "/viewUISize"}, {"value": "/states/command/processors/mapping/outputs/mappingOutput3/trigger", "controlAddress": "/target"}, {"value": "reset", "controlAddress": "/customText", "enabled": true}, {"value": "", "controlAddress": "/customImage", "enabled": false}], "niceName": "Item 11", "hideInEditor": true, "type": "DashboardTriggerItem", "ghostAddress": "/states/command/processors/mapping/outputs/mappingOutput3/trigger", "controllable": "/states/command/processors/mapping/outputs/mappingOutput3/trigger"}], "viewOffset": [-2, 0], "viewZoom": 1.0}, "editing": true}, {"niceName": "Pitch View", "type": "BaseItem", "itemManager": {"parameters": [{"value": [800.0, 600.0], "controlAddress": "/canvasSize", "enabled": true}, {"value": [0.3529411852359772, 0.3529411852359772, 0.3529411852359772, 1.0], "controlAddress": "/backgroundColor"}, {"value": "", "controlAddress": "/backgroundImage"}], "items": [{"parameters": [{"value": [-25.0, -133.0], "controlAddress": "/viewUIPosition"}, {"value": [183.0, 105.0], "controlAddress": "/viewUISize"}, {"value": "/modules/osc/values/wLEDAudioSyncBeat", "controlAddress": "/target"}, {"value": 12, "hexMode": false, "controlAddress": "/textSize", "enabled": true}, {"value": [0.8078431487083435, 0.8078431487083435, 0.8078431487083435, 1.0], "controlAddress": "/borderColor", "enabled": true}, {"value": true, "controlAddress": "/readOnly"}, {"value": false, "controlAddress": "/showValue"}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 1", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/osc/values/wLEDAudioSyncBeat", "controllable": "/modules/osc/values/wLEDAudioSyncBeat"}, {"parameters": [{"value": [-249.0, -189.0], "controlAddress": "/viewUIPosition"}, {"value": [509.0, 46.0], "controlAddress": "/viewUISize"}, {"value": "/modules/osc/values/_WLEDAudioSync_beat_BPM", "controlAddress": "/target"}, {"value": "BPM", "controlAddress": "/customText", "enabled": true}, {"value": 20, "hexMode": false, "controlAddress": "/textSize", "enabled": true}, {"value": [0.3803921639919281, 0.07450980693101883, 0.007843137718737125, 1.0], "controlAddress": "/borderColor", "enabled": true}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/osc/values/_WLEDAudioSync_beat_BPM", "controllable": "/modules/osc/values/_WLEDAudioSync_beat_BPM"}, {"parameters": [{"value": [-249.0, 59.0], "controlAddress": "/viewUIPosition"}, {"value": [509.0, 27.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/volume", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 2", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/volume", "controllable": "/modules/soundCard/values/volume"}, {"parameters": [{"value": [-249.0, -133.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/pitchDetection/freq", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 3", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/pitchDetection/freq", "controllable": "/modules/soundCard/values/pitchDetection/freq"}, {"parameters": [{"value": [-249.0, -68.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/pitchDetection/pitch", "controlAddress": "/target"}, {"value": "Horizontal Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 4", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/pitchDetection/pitch", "controllable": "/modules/soundCard/values/pitchDetection/pitch"}, {"parameters": [{"value": [-249.0, -18.0], "controlAddress": "/viewUIPosition"}, {"value": [439.0, 41.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Horizontal Bar", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 5", "hideInEditor": true, "type": "DashboardEnumParameterItem", "ghostAddress": "/modules/soundCard/values/pitchDetection/note", "controllable": "/modules/soundCard/values/pitchDetection/note"}, {"parameters": [{"value": [209.0, -72.0], "controlAddress": "/viewUIPosition"}, {"value": [51.0, 95.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/pitchDetection/octave", "controlAddress": "/target"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 6", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/pitchDetection/octave", "controllable": "/modules/soundCard/values/pitchDetection/octave"}, {"parameters": [{"value": [-290.0, -223.0], "controlAddress": "/viewUIPosition"}, {"value": [590.0, 331.0], "controlAddress": "/viewUISize"}, {"value": [1.0, 0.0, 0.0, 0.03921568766236305], "controlAddress": "/backgroundColor", "enabled": true}], "niceName": "Group", "hideInEditor": true, "type": "DashboardGroupItem", "itemManager": {"parameters": [{"value": [582.0, 323.0], "controlAddress": "/canvasSize", "enabled": false}], "editorIsCollapsed": true, "viewOffset": [-295, -165], "viewZoom": 1.0}}], "viewOffset": [1, 0], "viewZoom": 1.0}}, {"niceName": "FFT View", "type": "BaseItem", "itemManager": {"parameters": [{"value": [800.0, 600.0], "controlAddress": "/canvasSize", "enabled": true}, {"value": [0.3529411852359772, 0.3529411852359772, 0.3529411852359772, 1.0], "controlAddress": "/backgroundColor"}], "items": [{"parameters": [{"value": [223.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer16Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer16Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer16Value"}, {"parameters": [{"value": [193.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer15Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 1", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer15Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer15Value"}, {"parameters": [{"value": [163.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer14Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 2", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer14Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer14Value"}, {"parameters": [{"value": [133.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer13Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 3", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer13Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer13Value"}, {"parameters": [{"value": [103.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer12Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 4", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer12Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer12Value"}, {"parameters": [{"value": [73.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer11Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 5", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer11Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer11Value"}, {"parameters": [{"value": [43.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer10Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 6", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer10Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer10Value"}, {"parameters": [{"value": [13.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer9Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 7", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer9Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer9Value"}, {"parameters": [{"value": [-17.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer8Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 8", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer8Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer8Value"}, {"parameters": [{"value": [-47.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer7Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 9", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer7Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer7Value"}, {"parameters": [{"value": [-77.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer6Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 10", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer6Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer6Value"}, {"parameters": [{"value": [-107.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer5Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 11", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer5Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer5Value"}, {"parameters": [{"value": [-137.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer4Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 12", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer4Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer4Value"}, {"parameters": [{"value": [-167.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer3Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 13", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer3Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer3Value"}, {"parameters": [{"value": [-197.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer2Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 14", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer2Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer2Value"}, {"parameters": [{"value": [-227.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [20.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/fftEnveloppes/analyzer1Value", "controlAddress": "/target"}, {"value": false, "controlAddress": "/showLabel"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 15", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/fftEnveloppes/analyzer1Value", "controllable": "/modules/soundCard/values/fftEnveloppes/analyzer1Value"}, {"parameters": [{"value": [-227.0, 111.0], "controlAddress": "/viewUIPosition"}, {"value": [470.0, 30.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/values/volume", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 16", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/values/volume", "controllable": "/modules/soundCard/values/volume"}, {"parameters": [{"value": [-323.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [70.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/parameters/fftAnalysis/minDB", "controlAddress": "/target"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 17", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/parameters/fftAnalysis/minDB", "controllable": "/modules/soundCard/parameters/fftAnalysis/minDB"}, {"parameters": [{"value": [267.0, -112.0], "controlAddress": "/viewUIPosition"}, {"value": [70.0, 180.0], "controlAddress": "/viewUISize"}, {"value": "/modules/soundCard/parameters/fftAnalysis/maxDB", "controlAddress": "/target"}, {"value": "Vertical Slider", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 18", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/modules/soundCard/parameters/fftAnalysis/maxDB", "controllable": "/modules/soundCard/parameters/fftAnalysis/maxDB"}, {"parameters": [{"value": [-243.0, -152.0], "controlAddress": "/viewUIPosition"}, {"value": [500.0, 220.0], "controlAddress": "/viewUISize"}, {"value": 2.0, "controlAddress": "/borderWidth"}, {"value": [0.2862745225429535, 0.6941176652908325, 1.0, 1.0], "controlAddress": "/borderColor"}, {"value": [0.4000000059604645, 0.1725490242242813, 0.2980392277240753, 0.2549019753932953], "controlAddress": "/backgroundColor", "enabled": true}], "niceName": "Group", "hideInEditor": true, "type": "DashboardGroupItem", "itemManager": {"parameters": [{"value": [492.0, 212.0], "controlAddress": "/canvasSize", "enabled": false}], "editorIsCollapsed": true, "viewOffset": [-250, -110], "viewZoom": 1.0}}, {"parameters": [{"value": [-243.0, -221.0], "controlAddress": "/viewUIPosition"}, {"value": [111.0, 49.0], "controlAddress": "/viewUISize"}, {"value": "/customVariables/group/variables/bassonOff/bassonOff", "controlAddress": "/target"}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 19", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/customVariables/group/variables/bassonOff/bassonOff", "controllable": "/customVariables/group/variables/bassonOff/bassonOff"}, {"parameters": [{"value": [-47.0, -221.0], "controlAddress": "/viewUIPosition"}, {"value": [111.0, 49.0], "controlAddress": "/viewUISize"}, {"value": "/customVariables/group/variables/midonOff/midonOff", "controlAddress": "/target"}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 20", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/customVariables/group/variables/midonOff/midonOff", "controllable": "/customVariables/group/variables/midonOff/midonOff"}, {"parameters": [{"value": [146.0, -221.0], "controlAddress": "/viewUIPosition"}, {"value": [111.0, 49.0], "controlAddress": "/viewUISize"}, {"value": "/customVariables/group/variables/highonOff/highonOff", "controlAddress": "/target"}, {"value": "Toggle Button", "controlAddress": "/style"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 21", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/customVariables/group/variables/highonOff/highonOff", "controllable": "/customVariables/group/variables/highonOff/highonOff"}, {"parameters": [{"value": [-323.0, 164.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/states/command/processors/mapping/outputs/mappingOutput/trigger", "controlAddress": "/target"}, {"value": "Wled New", "controlAddress": "/customText", "enabled": true}, {"value": "", "controlAddress": "/customImage", "enabled": false}], "niceName": "Item 22", "hideInEditor": true, "type": "DashboardTriggerItem", "ghostAddress": "/states/command/processors/mapping/outputs/mappingOutput/trigger", "controllable": "/states/command/processors/mapping/outputs/mappingOutput/trigger"}, {"parameters": [{"value": [-107.0, 164.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/states/command/processors/mapping/outputs/mappingOutput1/trigger", "controlAddress": "/target"}, {"value": "Wled Old", "controlAddress": "/customText", "enabled": true}, {"value": "", "controlAddress": "/customImage", "enabled": false}], "niceName": "Item 23", "hideInEditor": true, "type": "DashboardTriggerItem", "ghostAddress": "/states/command/processors/mapping/outputs/mappingOutput1/trigger", "controllable": "/states/command/processors/mapping/outputs/mappingOutput1/trigger"}, {"parameters": [{"value": [137.0, 164.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/states/command/processors/mapping/outputs/mappingOutput2/trigger", "controlAddress": "/target"}, {"value": "Custom", "controlAddress": "/customText", "enabled": true}, {"value": "", "controlAddress": "/customImage", "enabled": false}], "niceName": "Item 24", "hideInEditor": true, "type": "DashboardTriggerItem", "ghostAddress": "/states/command/processors/mapping/outputs/mappingOutput2/trigger", "controllable": "/states/command/processors/mapping/outputs/mappingOutput2/trigger"}, {"parameters": [{"value": [137.0, 214.0], "controlAddress": "/viewUIPosition"}, {"value": [200.0, 40.0], "controlAddress": "/viewUISize"}, {"value": "/states/command/processors/mapping/outputs/mappingOutput2/command/size", "controlAddress": "/target"}, {"value": "", "controlAddress": "/toggleImage", "enabled": false}], "niceName": "Item 25", "hideInEditor": true, "type": "DashboardParameterItem", "ghostAddress": "/states/command/processors/mapping/outputs/mappingOutput2/command/size", "controllable": "/states/command/processors/mapping/outputs/mappingOutput2/command/size"}], "viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "parrots": {"viewOffset": [0, 0], "viewZoom": 1.0}, "layout": {"mainLayout": {"type": 1, "width": 1536, "height": 821, "direction": 2, "shifters": [{"type": 1, "width": 1536, "height": 821, "direction": 1, "shifters": [{"type": 0, "width": 1075, "height": 821, "currentContent": "Dashboard", "tabs": [{"name": "Dashboard"}, {"name": "State Machine"}, {"name": "Modules"}, {"name": "Custom Variables"}, {"name": "Logger"}]}, {"type": 0, "width": 455, "height": 821, "currentContent": "Inspector", "tabs": [{"name": "Inspector"}]}]}]}, "windows": null}, "modules": {"items": [{"niceName": "Sound Card", "type": "Sound Card", "scripts": {"viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": "YIN", "controlAddress": "/pitchDetectionMethod"}], "containers": {"inputVolumes": {}, "outputVolumes": {"editorIsCollapsed": true}, "monitor": {"parameters": [{"value": false, "controlAddress": "/enabled"}]}, "fftAnalysis": {"parameters": [{"value": true, "controlAddress": "/enabled"}, {"value": -50.0, "controlAddress": "/minDB"}], "editorIsCollapsed": true, "items": [{"parameters": [{"value": 0.02, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 1", "type": "BaseItem"}, {"parameters": [{"value": 0.03, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 2", "type": "BaseItem"}, {"parameters": [{"value": 0.04, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 3", "type": "BaseItem"}, {"parameters": [{"value": 0.045, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 4", "type": "BaseItem"}, {"parameters": [{"value": 0.06, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 5", "type": "BaseItem"}, {"parameters": [{"value": 0.075, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 6", "type": "BaseItem"}, {"parameters": [{"value": 0.09, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 7", "type": "BaseItem"}, {"parameters": [{"value": 0.12, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 8", "type": "BaseItem"}, {"parameters": [{"value": 0.15, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 9", "type": "BaseItem"}, {"parameters": [{"value": 0.19, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 10", "type": "BaseItem"}, {"parameters": [{"value": 0.245, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 11", "type": "BaseItem"}, {"parameters": [{"value": 0.31, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 12", "type": "BaseItem"}, {"parameters": [{"value": 0.39, "controlAddress": "/position"}, {"value": 0.06, "controlAddress": "/size"}], "niceName": "Analyzer 13", "type": "BaseItem"}, {"parameters": [{"value": 0.48, "controlAddress": "/position"}, {"value": 0.06, "controlAddress": "/size"}], "niceName": "Analyzer 14", "type": "BaseItem"}, {"parameters": [{"value": 0.59, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 15", "type": "BaseItem"}, {"parameters": [{"value": 0.7, "controlAddress": "/position"}, {"value": 0.05, "controlAddress": "/size"}], "niceName": "Analyzer 16", "type": "BaseItem"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "ltc": {"parameters": [{"value": false, "controlAddress": "/enabled"}]}}}, "templates": {"viewOffset": [0, 0], "viewZoom": 1.0}, "audioSettings": "\r\n\r\n\r\n", "analyzer": {"parameters": [{"value": true, "controlAddress": "/enabled"}, {"value": -50.0, "controlAddress": "/minDB"}], "editorIsCollapsed": true, "items": [{"parameters": [{"value": 0.02, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 1", "type": "BaseItem"}, {"parameters": [{"value": 0.03, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 2", "type": "BaseItem"}, {"parameters": [{"value": 0.04, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 3", "type": "BaseItem"}, {"parameters": [{"value": 0.045, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 4", "type": "BaseItem"}, {"parameters": [{"value": 0.06, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 5", "type": "BaseItem"}, {"parameters": [{"value": 0.075, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 6", "type": "BaseItem"}, {"parameters": [{"value": 0.09, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 7", "type": "BaseItem"}, {"parameters": [{"value": 0.12, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 8", "type": "BaseItem"}, {"parameters": [{"value": 0.15, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 9", "type": "BaseItem"}, {"parameters": [{"value": 0.19, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 10", "type": "BaseItem"}, {"parameters": [{"value": 0.245, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 11", "type": "BaseItem"}, {"parameters": [{"value": 0.31, "controlAddress": "/position"}, {"value": 0.04, "controlAddress": "/size"}], "niceName": "Analyzer 12", "type": "BaseItem"}, {"parameters": [{"value": 0.39, "controlAddress": "/position"}, {"value": 0.06, "controlAddress": "/size"}], "niceName": "Analyzer 13", "type": "BaseItem"}, {"parameters": [{"value": 0.48, "controlAddress": "/position"}, {"value": 0.06, "controlAddress": "/size"}], "niceName": "Analyzer 14", "type": "BaseItem"}, {"parameters": [{"value": 0.59, "controlAddress": "/position"}, {"value": 0.03, "controlAddress": "/size"}], "niceName": "Analyzer 15", "type": "BaseItem"}, {"parameters": [{"value": 0.7, "controlAddress": "/position"}, {"value": 0.05, "controlAddress": "/size"}], "niceName": "Analyzer 16", "type": "BaseItem"}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "OS", "type": "OS", "scripts": {"viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"containers": {"appControl": {}, "pingIPs": {}}}, "templates": {"viewOffset": [0, 0], "viewZoom": 1.0}, "values": {"containers": {"appControl": {}, "pingStatus": {}}}}, {"niceName": "OSC", "type": "OSC", "scripts": {"items": [{"parameters": [{"value": "WLEDAudioSync/OSCBPM.js", "controlAddress": "/filePath"}], "niceName": "OSCBPM", "type": "BaseItem", "scriptParams": {"hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"containers": {"oscInput": {}, "oscOutputs": {"viewOffset": [0, 0], "viewZoom": 1.0}, "pass_through": {}}}, "templates": {"viewOffset": [0, 0], "viewZoom": 1.0}, "values": {"parameters": [{"value": 112.2444152832031, "controlAddress": "/_WLEDAudioSync_beat_BPM", "type": "Float", "niceName": "/WLEDAudioSync/beat/BPM", "customizable": true, "removable": true, "description": "", "hideInEditor": false, "feedbackOnly": false, "shortName": "_WLEDAudioSync_beat_BPM"}, {"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/wLEDAudioSyncBeat", "type": "Boolean", "niceName": "WLEDAudioSyncBeat", "customizable": true, "removable": false, "description": "Value change at each beat", "hideInEditor": false, "feedbackOnly": false}]}}, {"niceName": "WLEDAudioSync", "type": "WLEDAudioSync", "scripts": {"items": [{"parameters": [{"value": true, "controlAddress": "/enableLog"}], "niceName": "WLEDAudioSync", "type": "BaseItem", "scriptParams": {"hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": "Raw", "controlAddress": "/protocol"}, {"value": false, "controlAddress": "/autoAdd"}, {"value": "1 value per byte", "controlAddress": "/messageStructure"}, {"value": true, "controlAddress": "/firstValueIsTheName"}, {"value": true, "controlAddress": "/multicastMode"}, {"value": "192.168.1.132", "controlAddress": "/ipAddressToBind"}, {"value": true, "controlAddress": "/live"}, {"value": false, "controlAddress": "/audioV1"}, {"value": true, "controlAddress": "/audioV2"}, {"value": 1024.0, "controlAddress": "/volumeMultiplier"}, {"value": 254.0, "controlAddress": "/frequencyMagnitudeMultiplier"}], "containers": {"input": {"parameters": [{"value": false, "controlAddress": "/enabled"}], "hideInEditor": true}, "output": {"parameters": [{"value": false, "controlAddress": "/local"}, {"value": "239.0.0.1", "controlAddress": "/remoteHost"}, {"value": 11988, "hexMode": false, "controlAddress": "/remotePort"}]}, "pass_through": {}, "beatParams": {"parameters": [{"value": true, "controlAddress": "/useBPM"}, {"value": "[0] Microsoft Sound Mapper - Input", "controlAddress": "/inputAudio"}, {"value": "OSCBPM.js", "controlAddress": "/scriptFile"}], "editorIsCollapsed": true}}}, "templates": {"viewOffset": [0, 0], "viewZoom": 1.0}, "values": {"hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "customVariables": {"items": [{"niceName": "Group", "type": "CVGroup", "params": {}, "variables": {"items": [{"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/bassonOff", "feedbackOnly": false, "type": "Boolean", "niceName": "bassonOff", "customizable": true, "removable": false, "description": "Custom control of type Boolean", "hideInEditor": false}], "niceName": "bassonOff", "editorIsCollapsed": true, "type": "Bool Parameter"}, {"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/midonOff", "feedbackOnly": false, "type": "Boolean", "niceName": "midonOff", "customizable": true, "removable": false, "description": "Custom control of type Boolean", "hideInEditor": false}], "niceName": "midonOff", "editorIsCollapsed": true, "type": "Bool Parameter"}, {"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/highonOff", "feedbackOnly": false, "type": "Boolean", "niceName": "highonOff", "customizable": true, "removable": false, "description": "Custom control of type Boolean", "hideInEditor": false}], "niceName": "highonOff", "editorIsCollapsed": true, "type": "Bool Parameter"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "presets": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "WLED", "type": "CVGroup", "params": {}, "variables": {"viewOffset": [0, 0], "viewZoom": 1.0}, "presets": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "states": {"items": [{"parameters": [{"value": [-536.0, -577.0], "controlAddress": "/viewUIPosition"}, {"value": [290.0, 404.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "Pitch", "type": "State", "processors": {"items": [{"parameters": [{"value": false, "controlAddress": "/enabled"}], "niceName": "Action", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/osc/values/wLEDAudioSyncBeat", "controlAddress": "/inputValue"}, {"value": true, "controlAddress": "/alwaysTrigger"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": "Change", "controlAddress": "/comparisonFunction"}, {"value": false, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "Replay", "commandType": "Snapshot", "command": {"parameters": [{"value": "WLEDAudioSync/Snapshot_1681488887.csv", "controlAddress": "/fileName"}, {"value": 1, "hexMode": false, "controlAddress": "/duration"}], "paramLinks": {}}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteC", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "C", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteC#", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "C#", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteD", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "D", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteD#", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "D#", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteE", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "E", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteF", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "F", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteF#", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "F#", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteG", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "G", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteG#", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "G#", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteA", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "A", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteA#", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "A#", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "NoteB", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/pitchDetection/note", "controlAddress": "/inputValue"}], "niceName": "From Input Value 1", "type": "From Input Value", "comparator": {"parameters": [{"value": "B", "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-536.0, -66.0], "controlAddress": "/viewUIPosition"}, {"value": [290.0, 110.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "BeatBPM", "type": "State", "processors": {"items": [{"niceName": "Beat", "editorIsCollapsed": true, "type": "Mapping", "im": {"items": [{"parameters": [{"value": "/modules/osc/values/wLEDAudioSyncBeat", "controlAddress": "/inputValue"}], "niceName": "Input Value", "type": "Input Value"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": 50, "hexMode": false, "controlAddress": "/updateRate"}], "editorIsCollapsed": true}, "filters": {"items": [{"niceName": "Condition", "type": "Condition", "filterParams": {"paramLinks": {}}, "conditions": {"items": [{"parameters": [{"value": "/modules/osc/values/wLEDAudioSyncBeat", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": true, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "outputs": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "BPM", "editorIsCollapsed": true, "type": "Mapping", "im": {"items": [{"parameters": [{"value": "/modules/osc/values/_WLEDAudioSync_beat_BPM", "controlAddress": "/inputValue"}], "niceName": "Input Value", "type": "Input Value"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": 50, "hexMode": false, "controlAddress": "/updateRate"}], "editorIsCollapsed": true}, "filters": {"viewOffset": [0, 0], "viewZoom": 1.0}, "outputs": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-536.0, -163.0], "controlAddress": "/viewUIPosition"}, {"value": [290.0, 87.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "Volume", "type": "State", "processors": {"items": [{"niceName": "Vol", "editorIsCollapsed": true, "type": "Mapping", "im": {"items": [{"parameters": [{"value": "/modules/soundCard/values/volume", "controlAddress": "/inputValue"}], "niceName": "Input Value", "type": "Input Value"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": 5, "hexMode": false, "controlAddress": "/updateRate"}, {"value": true, "controlAddress": "/sendOnInputChangeOnly"}, {"value": true, "controlAddress": "/sendOnOutputChangeOnly"}], "editorIsCollapsed": true}, "filters": {"items": [{"niceName": "Math", "type": "Math", "filterParams": {"parameters": [{"value": "Multiply", "controlAddress": "/operation"}, {"value": 250.0, "controlAddress": "/value"}], "paramLinks": {}}, "operationValue": {"value": 250.0, "controlAddress": "/states/volume/processors/vol/filters/math/filterParams/value"}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "outputs": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-805.0, -577.0], "controlAddress": "/viewUIPosition"}, {"value": [259.0, 165.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "FFT", "type": "State", "processors": {"items": [{"niceName": "Sub-bass", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer1Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.6358548998832703, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "Bass", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer2Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.6358548998832703, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "Bass 1", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer3Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.6358548998832703, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "Bass-mid", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer4Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.6358548998832703, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-805.0, -402.0], "controlAddress": "/viewUIPosition"}, {"value": [259.0, 248.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "FFT 1", "type": "State", "processors": {"items": [{"niceName": "midrange", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer5Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.3897815942764282, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange 1", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer6Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4683156311511993, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange 2", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer7Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4526088237762451, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange 3", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer8Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4526088237762451, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange 4", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer9Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4473732113838196, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange 5", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer10Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4840224385261536, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midrange high mid", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer11Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.4002528190612793, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-805.0, -144.0], "controlAddress": "/viewUIPosition"}, {"value": [259.0, 188.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "FFT 2", "type": "State", "processors": {"items": [{"niceName": "high mid", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer12Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.3897815942764282, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "high mid 1", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer13Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.3688392043113708, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "high mid 2", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer14Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.374074786901474, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "high mid high", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer15Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.2274779379367828, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "high", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/modules/soundCard/values/fftEnveloppes/analyzer16Value", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": ">", "controlAddress": "/comparisonFunction"}, {"value": 0.2745983600616455, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": [-236.0, -577.0], "controlAddress": "/viewUIPosition"}, {"value": [240.0, 210.0], "controlAddress": "/viewUISize"}, {"value": true, "controlAddress": "/active"}], "niceName": "Command", "type": "State", "processors": {"items": [{"niceName": "bassFFTonOff", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/customVariables/customVariables/values/group/bassonOff", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": true, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "bassFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/bassFFTonOff/consequencesTRUE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "bassFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/bassFFTonOff/consequencesFALSE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "midFFTonOff", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/customVariables/customVariables/values/group/midonOff", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": true, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "midFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/midFFTonOff/consequencesTRUE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "midFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/midFFTonOff/consequencesFALSE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"niceName": "highFFTonOff", "editorIsCollapsed": true, "type": "Action", "conditions": {"items": [{"parameters": [{"value": "/customVariables/customVariables/values/group/highonOff", "controlAddress": "/inputValue"}], "niceName": "From Input Value", "type": "From Input Value", "comparator": {"parameters": [{"value": true, "controlAddress": "/reference"}], "hideInEditor": true}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequences": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "highFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": true, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/highFFTonOff/consequencesTRUE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}, "consequencesOff": {"items": [{"niceName": "Consequence", "type": "Consequence", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "highFFT", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"items": [{"parameters": [{"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/#1"}], "niceName": "#1", "type": "Boolean", "param": {"value": false, "minValue": 0, "maxValue": 1, "default": false, "controlAddress": "/states/command/processors/highFFTonOff/consequencesFALSE/consequence/command/arguments/#1/#1"}}], "viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}}, {"parameters": [{"value": false, "controlAddress": "/enabled"}], "niceName": "Mapping", "editorIsCollapsed": true, "type": "Mapping", "im": {"items": [{"parameters": [{"value": "", "controlAddress": "/inputValue"}], "niceName": "Input Value", "type": "Input Value"}], "viewOffset": [0, 0], "viewZoom": 1.0}, "params": {"parameters": [{"value": 50, "hexMode": false, "controlAddress": "/updateRate"}], "editorIsCollapsed": true}, "filters": {"viewOffset": [0, 0], "viewZoom": 1.0}, "outputs": {"items": [{"niceName": "MappingOutput", "type": "BaseItem", "commandModule": "wLEDAudioSync", "commandPath": "FFT", "commandType": "WLED", "command": {"paramLinks": {}}}, {"niceName": "MappingOutput 1", "type": "BaseItem", "commandModule": "wLEDAudioSync", "commandPath": "FFT", "commandType": "WLED", "command": {"parameters": [{"value": true, "controlAddress": "/oldStyle"}], "paramLinks": {}}}, {"niceName": "MappingOutput 2", "type": "BaseItem", "commandModule": "wLEDAudioSync", "commandPath": "FFT", "commandType": "Custom", "command": {"parameters": [{"value": 0.04465002566576004, "controlAddress": "/size"}], "paramLinks": {}}}, {"niceName": "MappingOutput 3", "type": "BaseItem", "commandModule": "wLEDAudioSync", "commandPath": "", "commandType": "Script callback", "command": {"parameters": [{"value": "resetVolMag", "controlAddress": "/callback"}], "paramLinks": {}, "customValues": {"viewOffset": [0, 0], "viewZoom": 1.0}}}], "viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [0, 0], "viewZoom": 1.0}}], "viewOffset": [378, 238], "viewZoom": 1.0, "transitions": {"hideInEditor": true, "viewOffset": [0, 0], "viewZoom": 1.0}, "comments": {"hideInEditor": true, "viewOffset": [378, 238], "viewZoom": 1.0}}, "sequences": {"viewOffset": [0, 0], "viewZoom": 1.0}, "routers": {"viewOffset": [0, 0], "viewZoom": 1.0}} -------------------------------------------------------------------------------- /Snapshot_1680949776.csv: -------------------------------------------------------------------------------- 1 | 139.3870697021484;70;124.4254766106606;86;124.4254766106606;107.3197726011276;113.4982729554176;105.0870252251625;86.47971713542938;59.52036842703819;63.62694537639618;93.18147921562195;68.25793844461441;60.85871863365173;63.25479558110237;62.31666395068169;62.64834943413734;44.29674127697945;23.59565012156963;18.94844445586205;new -------------------------------------------------------------------------------- /Snapshot_1681488887.csv: -------------------------------------------------------------------------------- 1 | 473.7827453613281;70;186.8938126564026;86;186.8938126564026;164.0961641073227;170.9807366132736;125.9639758467674;73.71842151880264;67.78828597068787;45.19069561362267;26.71769452095032;27.90712235867977;15.34503522515297;7.650540146976709;2.349683361127973;1.014400693587959;0.0;0.0;0.0;new -------------------------------------------------------------------------------- /Snapshot_1682072453.csv: -------------------------------------------------------------------------------- 1 | 0;0;0;0;;;;;;;;;;;;;;;;;new -------------------------------------------------------------------------------- /WLEDAudioSync.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | a:zak45 4 | d:25/01/2023 5 | v:2.1.0 6 | 7 | Chataigne Module for WLED Sound Reactive 8 | Send sound card audio data via UDP. 9 | This script will take Audio data provided by Chataigne and try to map them to WLED values. 10 | It also provide some real time sound data analysis (e.g Pitch, FFT, BPM, etc..). 11 | 12 | 13 | Classical (Classique) : 60-120 BPM 14 | Jazz : 80-140 BPM 15 | Blues : 60-120 BPM 16 | Rock : 100-160 BPM 17 | Pop : 90-130 BPM 18 | R&B : 60-100 BPM 19 | Hip Hop : 60-100 BPM 20 | Electronic (EDM, Trance, House) : 120-140 BPM (varie selon les sous-genres) 21 | Country : 60-120 BPM 22 | Reggae : 70-100 BPM 23 | Funk : 90-120 BPM 24 | Metal : 100-200 BPM (varie selon les sous-genres) 25 | Punk : 150-200 BPM 26 | Salsa : 150-250 BPM 27 | Ballad : 60-80 BPM 28 | 29 | 30 | 31 | Names of frequency responses 32 | 20 - 40 Hz Low Bass 33 | 40 - 80 Hz Mid Bass 34 | 80 - 160 Hz Upper Bass 35 | 160 - 320 Hz Lower Midrange 36 | 320 - 640 Hz Middle Midrange 37 | 640 Hz - 1.28 кHz Upper Midrange 38 | 1.28 - 2.56 кHz Lower Treble 39 | 2.56 - 5.12 кHz Middele Treble 40 | 5.12 - 10.2 кHz Upper Treble 41 | 10.2 - 20.4 кHz Top Octave 42 | 43 | The UDP Multicast IP is 239.0.0.1, and the default UDP port is 11988. 44 | 45 | // From WLED Infos 46 | UDP port can be changed in WLED config pages, for example to have several groups of devices by assigning different UDP ports to each group. 47 | the software sends/receives one packet every 20 milliseconds (approx). An external sender may be slower, but not faster than 20ms = 50fps 48 | // 49 | 50 | -------------------------------------- BIN ----------------- 51 | 52 | // Range 53 | fftCalc[0] = (fftAdd(3,4)) /2; // 60 - 100 54 | fftCalc[1] = (fftAdd(4,5)) /2; // 80 - 120 55 | fftCalc[2] = (fftAdd(5,7)) /3; // 100 - 160 56 | fftCalc[3] = (fftAdd(7,9)) /3; // 140 - 200 57 | fftCalc[4] = (fftAdd(9,12)) /4; // 180 - 260 58 | fftCalc[5] = (fftAdd(12,16)) /5; // 240 - 340 59 | fftCalc[6] = (fftAdd(16,21)) /6; // 320 - 440 60 | fftCalc[7] = (fftAdd(21,28)) /8; // 420 - 600 61 | fftCalc[8] = (fftAdd(28,37)) /10; // 580 - 760 62 | fftCalc[9] = (fftAdd(37,48)) /12; // 740 - 980 63 | fftCalc[10] = (fftAdd(48,64)) /17; // 960 - 1300 64 | fftCalc[11] = (fftAdd(64,84)) /21; // 1280 - 1700 65 | fftCalc[12] = (fftAdd(84,111)) /28; // 1680 - 2240 66 | fftCalc[13] = (fftAdd(111,147)) /37; // 2220 - 2960 67 | fftCalc[14] = (fftAdd(147,194)) /48; // 2940 - 3900 68 | fftCalc[15] = (fftAdd(194, 255)) /62; // 3880 - 5120 // avoid the last 5 bins, which are usually inaccurate 69 | // 70 | 71 | fftCalc[ 0] = fftAddAvg(1,2); // 1 43 - 86 sub-bass 72 | fftCalc[ 1] = fftAddAvg(2,3); // 1 86 - 129 bass 73 | fftCalc[ 2] = fftAddAvg(3,5); // 2 129 - 216 bass 74 | fftCalc[ 3] = fftAddAvg(5,7); // 2 216 - 301 bass + midrange 75 | 76 | fftCalc[ 4] = fftAddAvg(7,10); // 3 301 - 430 midrange 77 | fftCalc[ 5] = fftAddAvg(10,13); // 3 430 - 560 midrange 78 | fftCalc[ 6] = fftAddAvg(13,19); // 5 560 - 818 midrange 79 | fftCalc[ 7] = fftAddAvg(19,26); // 7 818 - 1120 midrange -- 1Khz should always be the center ! 80 | fftCalc[ 8] = fftAddAvg(26,33); // 7 1120 - 1421 midrange 81 | fftCalc[ 9] = fftAddAvg(33,44); // 9 1421 - 1895 midrange 82 | fftCalc[10] = fftAddAvg(44,56); // 12 1895 - 2412 midrange + high mid 83 | fftCalc[11] = fftAddAvg(56,70); // 14 2412 - 3015 high mid 84 | fftCalc[12] = fftAddAvg(70,86); // 16 3015 - 3704 high mid 85 | fftCalc[13] = fftAddAvg(86,104); // 18 3704 - 4479 high mid 86 | fftCalc[14] = fftAddAvg(104,165) * 0.88f; // 61 4479 - 7106 high mid + high -- with slight damping 87 | // don't use the last bins from 216 to 255. They are usually contaminated by aliasing (aka noise) 88 | fftCalc[15] = fftAddAvg(165,215) * 0.70f; // 50 7106 - 9259 high -- with some damping 89 | 90 | 91 | */ 92 | 93 | // sound Card 94 | var SCexist = false; 95 | 96 | // osc 97 | var OSCModule = null; 98 | var OSCIP = "127.0.0.1"; 99 | 100 | // TMPDIR 101 | var tempDIR = ""; 102 | 103 | //HOME Location 104 | //%USERPROFILE% for WIN and $HOME for others 105 | var homeDIR = ""; 106 | var winHOME = ""; 107 | 108 | // Volume 109 | var wledVol = 0; 110 | // Volume Multiplier 111 | var volMultiplier = 512; 112 | 113 | // Global FFT Multiplier 114 | var fftMultiplier = 254; 115 | // FFT Data 116 | var FFTWLED = []; 117 | // FFT Max Freq / Magnitude 118 | var fftSoundMaxFreqMagnitude = 0; 119 | var fftSoundMaxFreqIndex = 0; 120 | // FFT Mode 121 | var fftMode = ""; 122 | //minAudio/max DB 123 | var minDB = -50; 124 | var maxDB = 0; 125 | // Frequence table 126 | var FREQTABLE = []; 127 | 128 | // samplePeak 129 | var wledPeak = 0; 130 | 131 | // Wled Freq/Mag 132 | var wledFreq = 0; 133 | var wledMag = 0; 134 | 135 | // UDP 136 | var multicastIP = "239.0.0.1"; 137 | var uDPPort = 11988; 138 | var myIP = "127.0.0.1"; 139 | 140 | // Init Flag 141 | // to made some logic only once at init 142 | var isInit = true; 143 | 144 | // snapshot 145 | var snapshot = false; 146 | 147 | //replay 148 | var replay = false; 149 | var duration = 0; 150 | var previousFile = ""; 151 | var SOUNDDATA = []; 152 | 153 | // UDP Data 154 | var UDP_AUDIO_SYNC = []; 155 | var UDP_AUDIO_SYNC_V2 = []; 156 | 157 | // BPM 158 | var aubioCmdName = "aubio.cmd"; 159 | var aubioProcName = "WLEDAudioSyncRTBeat"; 160 | 161 | // Friture 162 | var fritureCmdName = "friture.cmd"; 163 | // RTMGC 164 | var rtmgcCmdName = "rtmgc.cmd"; 165 | var rtmgcProcName = "WrtmgcSRV"; 166 | // RTMMD 167 | var rtmmdCmdName = "rtmmd.cmd"; 168 | // multicast 169 | var multicastCmdName = "multicast.cmd"; 170 | 171 | // module 172 | var moduleDIR = "/Chataigne/modules/WLEDAudioSync/"; 173 | 174 | var options = ""; 175 | 176 | // SCAnalyzer test 177 | var SCAModule = false; 178 | 179 | //We create necessary entries in module. 180 | function init () 181 | { 182 | script.log("-- Custom command called init()"); 183 | 184 | local.scripts.wLEDAudioSync.updateRate.setAttribute("readOnly",false); 185 | 186 | var infos = util.getOSInfos(); 187 | script.log("Hello "+infos.username); 188 | script.log("We run under : "+infos.name); 189 | 190 | if ( infos.name.contains("Win") ) 191 | { 192 | homeDIR = util.getEnvironmentVariable("USERPROFILE") + "/Documents"; 193 | winHOME = util.getEnvironmentVariable("USERPROFILE"); 194 | 195 | } else { 196 | 197 | homeDIR = util.getEnvironmentVariable("$HOME"); 198 | } 199 | 200 | // update rate (no more than 50fps but let choice) 201 | script.setUpdateRate(50); 202 | } 203 | 204 | 205 | function update () 206 | { 207 | 208 | // Send audio data and return 209 | if (SCexist && 210 | root.modules.soundCard.values.volume.get()!= 0 && 211 | replay === false && 212 | local.parameters.live.get() == 1 && 213 | local.parameters.beatParams.syncToBeat.get() == 0 214 | ) 215 | { 216 | sendAudio(false); 217 | 218 | return; 219 | 220 | } else if (replay === true){ 221 | 222 | if ( duration > 0 ) 223 | { 224 | sendAudio(true); 225 | 226 | } else { 227 | 228 | replay = false; 229 | 230 | for ( var k = 0; k < 10; k += 1 ) 231 | { 232 | sendAudio(false); 233 | } 234 | 235 | script.setUpdateRate(50); 236 | } 237 | 238 | return; 239 | } 240 | 241 | // Initialize only once some Params when script run for first time 242 | if (isInit === true) 243 | { 244 | script.log('Initialize'); 245 | 246 | isInit = false; 247 | 248 | // Module test 249 | 250 | OSCModule = root.modules.getItemWithName("OSC"); 251 | SCAModule = root.modules.getItemWithName("SCAnalyzer"); 252 | 253 | if (OSCModule.name == "osc") 254 | { 255 | script.log("Module OSC exist"); 256 | 257 | } else { 258 | 259 | script.log("Module OSC do not exist"); 260 | 261 | } 262 | 263 | if (SCAModule.name != "undefined") 264 | { 265 | script.log("Module SCAnalyzer exist"); 266 | 267 | } else { 268 | 269 | script.log("Module SCAnalyzer does not exist"); 270 | 271 | } 272 | 273 | if (checkModuleExist("OS")) 274 | { 275 | script.log("Module OS exist"); 276 | 277 | } else { 278 | 279 | root.modules.addItem("OS"); 280 | } 281 | 282 | 283 | if (checkModuleExist("Sound Card")) 284 | { 285 | script.log("Sound Card present"); 286 | SCexist = true; 287 | 288 | } else { 289 | 290 | script.log("No Sound Card present"); 291 | var newSCModule = root.modules.addItem("Sound Card"); 292 | if (newSCModule.name != "undefined") 293 | { 294 | SCexist = true; 295 | 296 | } else { 297 | 298 | SCexist = false; 299 | } 300 | } 301 | 302 | if (SCexist === true) 303 | { 304 | root.modules.soundCard.parameters.pitchDetectionMethod.set("MPM"); 305 | root.modules.soundCard.parameters.activityThreshold.set(0.075); 306 | } 307 | 308 | // if run from portable version need to set right script path 309 | // and execute BPM if not running 310 | if (local.parameters.beatParams.useBPM.get() == 1) 311 | { 312 | var checkProcess = root.modules.os.getRunningProcesses("*"); 313 | var aubioIsRunning = false; 314 | var aubioProcessName = ""; 315 | var aubiodevice = local.parameters.beatParams.inputAudio.get(); 316 | if (aubiodevice == null) 317 | { 318 | aubiodevice = 0; 319 | } 320 | 321 | addOSCScript('OSCBPM'); 322 | root.modules.osc.scripts.oscbpm.reload.trigger(); 323 | 324 | for ( var i = 0; i < checkProcess.length; i ++) 325 | { 326 | if (checkProcess[i].contains(aubioProcName)) 327 | { 328 | aubioIsRunning = true; 329 | aubioProcessName = checkProcess[i]; 330 | script.log("aubio is running"); 331 | break; 332 | } 333 | } 334 | 335 | if (aubioIsRunning === false ) { 336 | options = " beat -s " + OSCIP + " " + root.modules.osc.parameters.oscInput.localPort.get() + ' "/WLEDAudioSync/beat/BPM"' + 337 | " -d " + aubiodevice + 338 | " -b " + local.parameters.beatParams.aubioBuffer.get(); 339 | var command = homeDIR + moduleDIR + aubioCmdName + options; 340 | script.log("command to run : " + command); 341 | root.modules.os.launchCommand(command, true); 342 | } 343 | } 344 | 345 | // retreive all IPs 346 | var ips = util.getIPs(); 347 | local.parameters.ipAddressToBind.removeOptions(); 348 | 349 | for( var i=0; i 0) 695 | { 696 | util.delayThreadMS(mydelay); 697 | } 698 | 699 | // v1 message 700 | if (local.parameters.audioV1.get() == 1) 701 | { 702 | local.sendBytesTo (multicastIP,uDPPort,udpdataV1); 703 | } 704 | // v2 message 705 | if (local.parameters.audioV2.get() == 1) 706 | { 707 | var udpdataV2 = udpAudioSyncV2(udpdataV1); 708 | local.sendBytesTo (multicastIP,uDPPort,udpdataV2); 709 | } 710 | } 711 | 712 | /* 713 | Sound Card 714 | */ 715 | 716 | // Create 16 FFT analysis entries with default name : adjustable size - custom 717 | function createFFT(size) 718 | { 719 | 720 | removeFFT(); 721 | root.modules.soundCard.parameters.fftAnalysis.minDB.set(minDB); 722 | root.modules.soundCard.parameters.fftAnalysis.maxDB.set(maxDB); 723 | 724 | fftMode = "custom"; 725 | 726 | if (size > 1) 727 | { 728 | size = 1; 729 | 730 | } else if (size == 0) { 731 | 732 | size = 0.1; 733 | } 734 | 735 | for (var i = 0; i < 16; i += 1) 736 | { 737 | var bin = root.modules.soundCard.parameters.fftAnalysis.addItem(); 738 | bin.position.set(0.0625 * i); 739 | bin.size.set(size); 740 | updateFreqTable(fftMode, i); 741 | } 742 | } 743 | 744 | // Create 16 FFT analysis entries with default name : WLED OLD/NEW -- true/false 745 | function createWLEDFFT(old) 746 | { 747 | 748 | removeFFT(); 749 | root.modules.soundCard.parameters.fftAnalysis.minDB.set(minDB); 750 | root.modules.soundCard.parameters.fftAnalysis.maxDB.set(maxDB); 751 | 752 | if (old) 753 | { 754 | fftMode = "old"; 755 | 756 | } else { 757 | 758 | fftMode = "new"; 759 | } 760 | 761 | 762 | for (var i = 0; i < 16; i += 1) 763 | { 764 | var bin = root.modules.soundCard.parameters.fftAnalysis.addItem(); 765 | 766 | if (i == 0) 767 | { 768 | if (old) 769 | { 770 | bin.position.set(0.020); 771 | bin.size.set(0.030); 772 | 773 | } else { 774 | 775 | bin.position.set(0.020); 776 | bin.size.set(0.020); 777 | } 778 | 779 | } else if (i == 1) { 780 | 781 | if (old) 782 | { 783 | bin.position.set(0.030); 784 | bin.size.set(0.030); 785 | 786 | } else { 787 | 788 | bin.position.set(0.030); 789 | bin.size.set(0.020); 790 | } 791 | 792 | } else if (i == 2) { 793 | 794 | if (old) 795 | { 796 | bin.position.set(0.040); 797 | bin.size.set(0.030); 798 | 799 | } else { 800 | 801 | bin.position.set(0.045); 802 | bin.size.set(0.020); 803 | } 804 | 805 | } else if (i == 3) { 806 | 807 | if (old) 808 | { 809 | bin.position.set(0.045); 810 | bin.size.set(0.030); 811 | 812 | } else { 813 | 814 | bin.position.set(0.065); 815 | bin.size.set(0.020); 816 | } 817 | 818 | } else if (i == 4) { 819 | 820 | if (old) 821 | { 822 | bin.position.set(0.060); 823 | bin.size.set(0.030); 824 | 825 | } else { 826 | 827 | bin.position.set(0.090); 828 | bin.size.set(0.020); 829 | } 830 | 831 | } else if (i == 5) { 832 | 833 | if (old) 834 | { 835 | bin.position.set(0.075); 836 | bin.size.set(0.030); 837 | 838 | } else { 839 | 840 | bin.position.set(0.110); 841 | bin.size.set(0.040); 842 | } 843 | 844 | } else if (i == 6) { 845 | 846 | if (old) 847 | { 848 | bin.position.set(0.090); 849 | bin.size.set(0.040); 850 | 851 | } else { 852 | 853 | bin.position.set(0.160); 854 | bin.size.set(0.040); 855 | } 856 | 857 | } else if (i == 7) { 858 | 859 | if (old) 860 | { 861 | bin.position.set(0.120); 862 | bin.size.set(0.040); 863 | 864 | } else { 865 | 866 | bin.position.set(0.215); 867 | bin.size.set(0.050); 868 | } 869 | 870 | } else if (i == 8) { 871 | 872 | if (old) 873 | { 874 | bin.position.set(0.150); 875 | bin.size.set(0.040); 876 | 877 | } else { 878 | 879 | bin.position.set(0.265); 880 | bin.size.set(0.050); 881 | } 882 | 883 | } else if (i == 9) { 884 | 885 | if (old) 886 | { 887 | bin.position.set(0.190); 888 | bin.size.set(0.040); 889 | 890 | } else { 891 | 892 | bin.position.set(0.340); 893 | bin.size.set(0.050); 894 | } 895 | 896 | } else if (i == 10) { 897 | 898 | if (old) 899 | { 900 | bin.position.set(0.245); 901 | bin.size.set(0.040); 902 | 903 | } else { 904 | 905 | bin.position.set(0.410); 906 | bin.size.set(0.050); 907 | } 908 | 909 | } else if (i == 11) { 910 | 911 | if (old) 912 | { 913 | bin.position.set(0.310); 914 | bin.size.set(0.040); 915 | 916 | } else { 917 | 918 | bin.position.set(0.490); 919 | bin.size.set(0.050); 920 | } 921 | 922 | } else if (i == 12) { 923 | 924 | if (old) 925 | { 926 | bin.position.set(0.390); 927 | bin.size.set(0.060); 928 | 929 | } else { 930 | 931 | bin.position.set(0.570); 932 | bin.size.set(0.060); 933 | } 934 | 935 | } else if (i == 13) { 936 | 937 | if (old) 938 | { 939 | bin.position.set(0.480); 940 | bin.size.set(0.060); 941 | 942 | } else { 943 | 944 | bin.position.set(0.645); 945 | bin.size.set(0.070); 946 | } 947 | 948 | } else if (i == 14) { 949 | 950 | if (old) 951 | { 952 | bin.position.set(0.590); 953 | bin.size.set(0.030); 954 | 955 | } else { 956 | 957 | bin.position.set(0.830); 958 | bin.size.set(0.070); 959 | } 960 | 961 | } else if (i == 15) { 962 | 963 | if (old) 964 | { 965 | bin.position.set(0.700); 966 | bin.size.set(0.050); 967 | 968 | } else { 969 | 970 | bin.position.set(0.915); 971 | bin.size.set(0.070); 972 | } 973 | } 974 | 975 | updateFreqTable(fftMode, i); 976 | } 977 | } 978 | 979 | // update Frequences Table depend on FFT mode 980 | function updateFreqTable(fftMode, index) 981 | { 982 | 983 | if ( index == 0 ) 984 | { 985 | if ( fftMode == "new" ) 986 | { 987 | FREQTABLE[index] = 86; 988 | 989 | } else if ( fftMode == "old" ) { 990 | 991 | FREQTABLE[index] = 100; 992 | 993 | } else if ( fftMode == "custom" ) { 994 | 995 | FREQTABLE[index] = 50; 996 | 997 | } 998 | 999 | } else if ( index == 1 ) { 1000 | 1001 | if ( fftMode == "new" ) 1002 | { 1003 | FREQTABLE[index] = 129; 1004 | 1005 | } else if ( fftMode == "old" ) { 1006 | 1007 | FREQTABLE[index] = 120; 1008 | 1009 | } else if ( fftMode == "custom" ) { 1010 | 1011 | FREQTABLE[index] = 280; 1012 | 1013 | } 1014 | 1015 | } else if ( index == 2 ) { 1016 | 1017 | if ( fftMode == "new" ) 1018 | { 1019 | FREQTABLE[index] = 216; 1020 | 1021 | } else if ( fftMode == "old" ) { 1022 | 1023 | FREQTABLE[index] = 160; 1024 | 1025 | } else if ( fftMode == "custom" ) { 1026 | 1027 | FREQTABLE[index] = 600; 1028 | 1029 | } 1030 | 1031 | } else if ( index == 3 ) { 1032 | 1033 | if ( fftMode == "new" ) 1034 | { 1035 | FREQTABLE[index] = 301; 1036 | 1037 | } else if ( fftMode == "old" ) { 1038 | 1039 | FREQTABLE[index] = 200; 1040 | 1041 | } else if ( fftMode == "custom" ) { 1042 | 1043 | FREQTABLE[index] = 950; 1044 | 1045 | } 1046 | 1047 | } else if ( index == 4 ) { 1048 | 1049 | if ( fftMode == "new" ) 1050 | { 1051 | FREQTABLE[index] = 430; 1052 | 1053 | } else if ( fftMode == "old" ) { 1054 | 1055 | FREQTABLE[index] = 260; 1056 | 1057 | } else if ( fftMode == "custom" ) { 1058 | 1059 | FREQTABLE[index] = 1300; 1060 | 1061 | } 1062 | 1063 | } else if ( index == 5 ) { 1064 | 1065 | if ( fftMode == "new" ) 1066 | { 1067 | FREQTABLE[index] = 560; 1068 | 1069 | } else if ( fftMode == "old" ) { 1070 | 1071 | FREQTABLE[index] = 340; 1072 | 1073 | } else if ( fftMode == "custom" ) { 1074 | 1075 | FREQTABLE[index] = 1700; 1076 | 1077 | } 1078 | 1079 | } else if ( index == 6 ) { 1080 | 1081 | if ( fftMode == "new" ) 1082 | { 1083 | FREQTABLE[index] = 818; 1084 | 1085 | } else if ( fftMode == "old" ) { 1086 | 1087 | FREQTABLE[index] = 440; 1088 | 1089 | } else if ( fftMode == "custom" ) { 1090 | 1091 | FREQTABLE[index] = 2150; 1092 | 1093 | } 1094 | 1095 | } else if ( index == 7 ) { 1096 | 1097 | if ( fftMode == "new" ) 1098 | { 1099 | FREQTABLE[index] = 1120; 1100 | 1101 | } else if ( fftMode == "old" ) { 1102 | 1103 | FREQTABLE[index] = 600; 1104 | 1105 | } else if ( fftMode == "custom" ) { 1106 | 1107 | FREQTABLE[index] = 2600; 1108 | 1109 | } 1110 | 1111 | } else if ( index == 8 ) { 1112 | 1113 | if ( fftMode == "new" ) 1114 | { 1115 | FREQTABLE[index] = 1421; 1116 | 1117 | } else if ( fftMode == "old" ) { 1118 | 1119 | FREQTABLE[index] = 760; 1120 | 1121 | } else if ( fftMode == "custom" ) { 1122 | 1123 | FREQTABLE[index] = 3100; 1124 | 1125 | } 1126 | 1127 | } else if ( index == 9 ) { 1128 | 1129 | if ( fftMode == "new" ) 1130 | { 1131 | FREQTABLE[index] = 1895; 1132 | 1133 | } else if ( fftMode == "old" ) { 1134 | 1135 | FREQTABLE[index] = 980; 1136 | 1137 | } else if ( fftMode == "custom" ) { 1138 | 1139 | FREQTABLE[index] = 3600; 1140 | 1141 | } 1142 | 1143 | } else if ( index == 10 ) { 1144 | 1145 | if ( fftMode == "new" ) 1146 | { 1147 | FREQTABLE[index] = 2412; 1148 | 1149 | } else if ( fftMode == "old" ) { 1150 | 1151 | FREQTABLE[index] = 1300; 1152 | 1153 | } else if ( fftMode == "custom" ) { 1154 | 1155 | FREQTABLE[index] = 4200; 1156 | 1157 | } 1158 | 1159 | } else if ( index == 11 ) { 1160 | 1161 | if ( fftMode == "new" ) 1162 | { 1163 | FREQTABLE[index] = 3015; 1164 | 1165 | } else if ( fftMode == "old" ) { 1166 | 1167 | FREQTABLE[index] = 1700; 1168 | 1169 | } else if ( fftMode == "custom" ) { 1170 | 1171 | FREQTABLE[index] = 4950; 1172 | 1173 | } 1174 | 1175 | } else if ( index == 12 ) { 1176 | 1177 | if ( fftMode == "new" ) 1178 | { 1179 | FREQTABLE[index] = 3704; 1180 | 1181 | } else if ( fftMode == "old" ) { 1182 | 1183 | FREQTABLE[index] = 2240; 1184 | 1185 | } else if ( fftMode == "custom" ) { 1186 | 1187 | FREQTABLE[index] = 5750; 1188 | 1189 | } 1190 | 1191 | } else if ( index == 13 ) { 1192 | 1193 | if ( fftMode == "new" ) 1194 | { 1195 | FREQTABLE[index] = 4479; 1196 | 1197 | } else if ( fftMode == "old" ) { 1198 | 1199 | FREQTABLE[index] = 2960; 1200 | 1201 | } else if ( fftMode == "custom" ) { 1202 | 1203 | FREQTABLE[index] = 6800; 1204 | 1205 | } 1206 | 1207 | } else if ( index == 14 ) { 1208 | 1209 | if ( fftMode == "new" ) 1210 | { 1211 | FREQTABLE[index] = 7106; 1212 | 1213 | } else if ( fftMode == "old" ) { 1214 | 1215 | FREQTABLE[index] = 3900; 1216 | 1217 | } else if ( fftMode == "custom" ) { 1218 | 1219 | FREQTABLE[index] = 8100; 1220 | 1221 | } 1222 | 1223 | } else if ( index == 15 ) { 1224 | 1225 | if ( fftMode == "new" ) 1226 | { 1227 | FREQTABLE[index] = 9259; 1228 | 1229 | } else if ( fftMode == "old" ) { 1230 | 1231 | FREQTABLE[index] = 5120; 1232 | 1233 | } else if ( fftMode == "custom" ) { 1234 | 1235 | FREQTABLE[index] = 10000; 1236 | 1237 | } 1238 | } 1239 | } 1240 | 1241 | 1242 | // remove all FFT analysis 1243 | function removeFFT() 1244 | { 1245 | root.modules.soundCard.parameters.fftAnalysis.removeAll(); 1246 | } 1247 | 1248 | /* 1249 | 1250 | WLED Specifics 1251 | 1252 | */ 1253 | 1254 | // This one should be always executed. If replay is true we had taken data from file. 1255 | function udpAudioSyncV1(replay) 1256 | { 1257 | /* 1258 | #define UDP_SYNC_HEADER "00001" 1259 | struct audioSyncPacket { 1260 | char header[6] = UDP_SYNC_HEADER; 1261 | uint8_t myVals[32]; // 32 Bytes 1262 | int sampleAgc; // 04 Bytes 1263 | int sampleRaw; // 04 Bytes 1264 | float sampleAvg; // 04 Bytes 1265 | bool samplePeak; // 01 Bytes 1266 | uint8_t fftResult[16]; // 16 Bytes - FFT results, one byte per GEQ channel 1267 | double FFT_Magnitude; // 08 Bytes 1268 | double FFT_MajorPeak; // 08 Bytes 1269 | }; 1270 | ---------------------------------------------------- 1271 | 1272 | // update samples for effects 1273 | volumeSmth = fmaxf(receivedPacket->sampleAgc, 0.0f); 1274 | volumeRaw = volumeSmth; // V1 format does not have "raw" AGC sample 1275 | // update internal samples 1276 | sampleRaw = fmaxf(receivedPacket->sampleRaw, 0.0f); 1277 | sampleAvg = fmaxf(receivedPacket->sampleAvg, 0.0f);; 1278 | sampleAgc = volumeSmth; 1279 | rawSampleAgc = volumeRaw; 1280 | multAgc = 1.0f; 1281 | 1282 | ----------------------------------------------------- 1283 | 1284 | bool newReading = MSGEQ7.read(MSGEQ7_INTERVAL); 1285 | if (newReading) { 1286 | audioSyncPacket transmitData; 1287 | 1288 | for (int b = 0; b < 14; b = b + 2) { 1289 | int val = MSGEQ7.get((b / 2)); 1290 | val = mapNoise(val); 1291 | Serial.printf("%u ", val); 1292 | transmitData.fftResult[b] = val; 1293 | transmitData.fftResult[(b + 1)] = val; 1294 | } 1295 | 1296 | ------------------------------------------------------ 1297 | 1298 | int v = map(MSGEQ7.getVolume(), 0, MSGEQ7_OUT_MAX, 0, 1023); // TO DO: not sure this is right 1299 | transmitData.sampleRaw = v; // Current sample 1300 | 1301 | ------------------------------------------------------ 1302 | 1303 | 1304 | */ 1305 | 1306 | // save audio data to file 1307 | if (snapshot) 1308 | { 1309 | script.log("Take snapshot"); 1310 | 1311 | var soundFileName = homeDIR + moduleDIR + "Snapshot_" + util.getTimestamp() + ".csv"; 1312 | var data = wledVol + ";" + wledPeak + ";" + wledMag + ";" + wledFreq; 1313 | for (var i = 0; i < 16; i+=1) 1314 | { 1315 | data = data + ";" + FFTWLED[i]; 1316 | } 1317 | data = data + ";" + fftMode; 1318 | 1319 | // write sound data to file 1320 | util.writeFile(soundFileName, data, false); 1321 | util.showMessageBox("Snapshot", "file name : " + soundFileName , "info", "Ok"); 1322 | 1323 | snapshot = false; 1324 | } 1325 | 1326 | 1327 | // FFT Max Freq / Magnitude 1328 | fftSoundMaxFreqMagnitude = 0; 1329 | fftSoundMaxFreqIndex = 0; 1330 | 1331 | if (replay === false && local.parameters.live.get() == 1) 1332 | { 1333 | 1334 | // sampleRaw 4 Bytes 1335 | wledVol = root.modules.soundCard.values.volume.get()*volMultiplier; 1336 | // samplePeak 1337 | wledPeak = root.modules.soundCard.values.pitchDetection.pitch.get(); 1338 | 1339 | // Calculate FFT Data 1340 | // Freq value 1341 | FFTWLED[0] = root.modules.soundCard.values.fftEnveloppes.analyzer1Value.get()*fftMultiplier; 1342 | FFTWLED[1] = root.modules.soundCard.values.fftEnveloppes.analyzer2Value.get()*fftMultiplier; 1343 | FFTWLED[2] = root.modules.soundCard.values.fftEnveloppes.analyzer3Value.get()*fftMultiplier; 1344 | FFTWLED[3] = root.modules.soundCard.values.fftEnveloppes.analyzer4Value.get()*fftMultiplier; 1345 | FFTWLED[4] = root.modules.soundCard.values.fftEnveloppes.analyzer5Value.get()*fftMultiplier; 1346 | FFTWLED[5] = root.modules.soundCard.values.fftEnveloppes.analyzer6Value.get()*fftMultiplier; 1347 | FFTWLED[6] = root.modules.soundCard.values.fftEnveloppes.analyzer7Value.get()*fftMultiplier; 1348 | FFTWLED[7] = root.modules.soundCard.values.fftEnveloppes.analyzer8Value.get()*fftMultiplier; 1349 | FFTWLED[8] = root.modules.soundCard.values.fftEnveloppes.analyzer9Value.get()*fftMultiplier; 1350 | FFTWLED[9] = root.modules.soundCard.values.fftEnveloppes.analyzer10Value.get()*fftMultiplier; 1351 | FFTWLED[10] = root.modules.soundCard.values.fftEnveloppes.analyzer11Value.get()*fftMultiplier; 1352 | FFTWLED[11] = root.modules.soundCard.values.fftEnveloppes.analyzer12Value.get()*fftMultiplier; 1353 | FFTWLED[12] = root.modules.soundCard.values.fftEnveloppes.analyzer13Value.get()*fftMultiplier; 1354 | FFTWLED[13] = root.modules.soundCard.values.fftEnveloppes.analyzer14Value.get()*fftMultiplier; 1355 | FFTWLED[14] = root.modules.soundCard.values.fftEnveloppes.analyzer15Value.get()*fftMultiplier; 1356 | FFTWLED[15] = root.modules.soundCard.values.fftEnveloppes.analyzer16Value.get()*fftMultiplier; 1357 | 1358 | 1359 | // retreive MaxFreq and Magnitude 1360 | for (var i = 0; i < 16; i +=1) 1361 | { 1362 | if (fftSoundMaxFreqMagnitude < FFTWLED[i]) 1363 | { 1364 | fftSoundMaxFreqMagnitude = FFTWLED[i]; 1365 | fftSoundMaxFreqIndex = FREQTABLE[i]; 1366 | } 1367 | } 1368 | 1369 | // FFT Magnitude 8 bytes 1370 | wledMag = fftSoundMaxFreqMagnitude; 1371 | // FFT Max Freq 8 bytes 1372 | wledFreq = fftSoundMaxFreqIndex; 1373 | 1374 | } else if (replay === false && local.parameters.live.get() == 0) { 1375 | 1376 | // set audio data 1377 | wledVol = 0; 1378 | wledPeak = 0; 1379 | wledMag = 0; 1380 | wledFreq = 0; 1381 | 1382 | for ( var i = 0; i < 16; i += 1) 1383 | { 1384 | FFTWLED[i] = 0; 1385 | } 1386 | 1387 | } 1388 | 1389 | // 1390 | // create UDP data 1391 | // 1392 | var intArray = createIntArray(util.floatToHexSeq(wledVol,true)); 1393 | 1394 | if (wledPeak !=0) 1395 | { 1396 | var samplePeak = 1; 1397 | 1398 | } else { 1399 | 1400 | var samplePeak = 0; 1401 | } 1402 | 1403 | var fftMagArray = createIntArray(util.doubleToHexSeq(wledMag,true)); 1404 | var fftFreqArray = createIntArray(util.doubleToHexSeq(wledFreq,true)); 1405 | 1406 | // Header v1 1407 | UDP_AUDIO_SYNC[0] = 48; 1408 | UDP_AUDIO_SYNC[1] = 48; 1409 | UDP_AUDIO_SYNC[2] = 48; 1410 | UDP_AUDIO_SYNC[3] = 48; 1411 | UDP_AUDIO_SYNC[4] = 49; 1412 | UDP_AUDIO_SYNC[5] = 0; 1413 | // uint8_t myVals[32]; 1414 | // Used to store a pile of samples because WLED frame rate and WLED sample rate are not synchronized. Frame rate is too low. 1415 | UDP_AUDIO_SYNC[6] = wledVol; 1416 | UDP_AUDIO_SYNC[7] = wledVol; 1417 | UDP_AUDIO_SYNC[8] = wledVol; 1418 | UDP_AUDIO_SYNC[9] = wledVol; 1419 | UDP_AUDIO_SYNC[10] = wledVol; 1420 | UDP_AUDIO_SYNC[11] = wledVol; 1421 | UDP_AUDIO_SYNC[12] = wledVol; 1422 | UDP_AUDIO_SYNC[13] = wledVol; 1423 | UDP_AUDIO_SYNC[14] = wledVol; 1424 | UDP_AUDIO_SYNC[15] = wledVol; 1425 | UDP_AUDIO_SYNC[16] = wledVol; 1426 | UDP_AUDIO_SYNC[17] = wledVol; 1427 | UDP_AUDIO_SYNC[18] = wledVol; 1428 | UDP_AUDIO_SYNC[19] = wledVol; 1429 | UDP_AUDIO_SYNC[20] = wledVol; 1430 | UDP_AUDIO_SYNC[21] = wledVol; 1431 | UDP_AUDIO_SYNC[22] = wledVol; 1432 | UDP_AUDIO_SYNC[23] = wledVol; 1433 | UDP_AUDIO_SYNC[24] = wledVol; 1434 | UDP_AUDIO_SYNC[25] = wledVol; 1435 | UDP_AUDIO_SYNC[26] = wledVol; 1436 | UDP_AUDIO_SYNC[27] = wledVol; 1437 | UDP_AUDIO_SYNC[28] = wledVol; 1438 | UDP_AUDIO_SYNC[29] = wledVol; 1439 | UDP_AUDIO_SYNC[30] = wledVol; 1440 | UDP_AUDIO_SYNC[31] = wledVol; 1441 | UDP_AUDIO_SYNC[32] = wledVol; 1442 | UDP_AUDIO_SYNC[33] = wledVol; 1443 | UDP_AUDIO_SYNC[34] = wledVol; 1444 | UDP_AUDIO_SYNC[35] = wledVol; 1445 | UDP_AUDIO_SYNC[36] = wledVol; 1446 | UDP_AUDIO_SYNC[37] = wledVol; 1447 | // Filler 1448 | UDP_AUDIO_SYNC[38] = 0; 1449 | UDP_AUDIO_SYNC[39] = 0; 1450 | // int sampleAgc; // 04 Bytes 1451 | // volumeSmth = fmaxf(receivedPacket->sampleSmth, 0.0f); 1452 | UDP_AUDIO_SYNC[40] = intArray[3]; 1453 | UDP_AUDIO_SYNC[41] = intArray[2]; 1454 | UDP_AUDIO_SYNC[42] = intArray[1]; 1455 | UDP_AUDIO_SYNC[43] = intArray[0]; 1456 | // int sampleRaw; // 04 Bytes 1457 | // fmaxf(receivedPacket->sampleRaw, 0.0f); 1458 | UDP_AUDIO_SYNC[44] = intArray[3]; 1459 | UDP_AUDIO_SYNC[45] = intArray[2]; 1460 | UDP_AUDIO_SYNC[46] = intArray[1]; 1461 | UDP_AUDIO_SYNC[47] = intArray[0]; 1462 | // float sampleAvg; // 04 Bytes 1463 | // volumeSmth = fmaxf(receivedPacket->sampleSmth, 0.0f); 1464 | UDP_AUDIO_SYNC[48] = intArray[3]; 1465 | UDP_AUDIO_SYNC[49] = intArray[2]; 1466 | UDP_AUDIO_SYNC[50] = intArray[1]; 1467 | UDP_AUDIO_SYNC[51] = intArray[0]; 1468 | // bool samplePeak; // 01 Bytes 1469 | // Boolean flag for peak. Responding routine must reset this flag 1470 | UDP_AUDIO_SYNC[52] = samplePeak; 1471 | // uint8_t fftResult[16]; // 16 Bytes - FFT results, one byte per GEQ channel 1472 | UDP_AUDIO_SYNC[53] = FFTWLED[0]; 1473 | UDP_AUDIO_SYNC[54] = FFTWLED[1]; 1474 | UDP_AUDIO_SYNC[55] = FFTWLED[2]; 1475 | UDP_AUDIO_SYNC[56] = FFTWLED[3]; 1476 | UDP_AUDIO_SYNC[57] = FFTWLED[4]; 1477 | UDP_AUDIO_SYNC[58] = FFTWLED[5]; 1478 | UDP_AUDIO_SYNC[59] = FFTWLED[6]; 1479 | UDP_AUDIO_SYNC[60] = FFTWLED[7]; 1480 | UDP_AUDIO_SYNC[61] = FFTWLED[8]; 1481 | UDP_AUDIO_SYNC[62] = FFTWLED[9]; 1482 | UDP_AUDIO_SYNC[63] = FFTWLED[10]; 1483 | UDP_AUDIO_SYNC[64] = FFTWLED[11]; 1484 | UDP_AUDIO_SYNC[65] = FFTWLED[12]; 1485 | UDP_AUDIO_SYNC[66] = FFTWLED[13]; 1486 | UDP_AUDIO_SYNC[67] = FFTWLED[14]; 1487 | UDP_AUDIO_SYNC[68] = FFTWLED[15]; 1488 | // Filler 1489 | UDP_AUDIO_SYNC[69] = 0; 1490 | UDP_AUDIO_SYNC[70] = 0; 1491 | UDP_AUDIO_SYNC[71] = 0; 1492 | // double FFT_Magnitude; // 08 Bytes 1493 | // float FFT_Magnitude = 0.0f; // FFT: volume (magnitude) of peak frequency 1494 | // my_magnitude = fmaxf(receivedPacket->FFT_Magnitude, 0.0f); 1495 | UDP_AUDIO_SYNC[72] = fftMagArray[7]; 1496 | UDP_AUDIO_SYNC[73] = fftMagArray[6]; 1497 | UDP_AUDIO_SYNC[74] = fftMagArray[5]; 1498 | UDP_AUDIO_SYNC[75] = fftMagArray[4]; 1499 | UDP_AUDIO_SYNC[76] = fftMagArray[3]; 1500 | UDP_AUDIO_SYNC[77] = fftMagArray[2]; 1501 | UDP_AUDIO_SYNC[78] = fftMagArray[1]; 1502 | UDP_AUDIO_SYNC[79] = fftMagArray[0]; 1503 | // double FFT_MajorPeak; // 08 Bytes 1504 | // float FFT_MajorPeak = 1.0f; // FFT: strongest (peak) frequency 1505 | // FFT_MajorPeak = constrain(receivedPacket->FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects 1506 | UDP_AUDIO_SYNC[80] = fftFreqArray[7]; 1507 | UDP_AUDIO_SYNC[81] = fftFreqArray[6]; 1508 | UDP_AUDIO_SYNC[82] = fftFreqArray[5]; 1509 | UDP_AUDIO_SYNC[83] = fftFreqArray[4]; 1510 | UDP_AUDIO_SYNC[84] = fftFreqArray[3]; 1511 | UDP_AUDIO_SYNC[85] = fftFreqArray[2]; 1512 | UDP_AUDIO_SYNC[86] = fftFreqArray[1]; 1513 | UDP_AUDIO_SYNC[87] = fftFreqArray[0]; 1514 | 1515 | 1516 | return UDP_AUDIO_SYNC; 1517 | } 1518 | 1519 | // v2 message , new format 1520 | function udpAudioSyncV2(udpdataV1) 1521 | { 1522 | /* 1523 | // new "V2" audiosync struct - 40 bytes - from WLED 0.14xx 1524 | 1525 | struct audioSyncPacket { 1526 | char header[6]; // 06 Bytes 1527 | float sampleRaw; // 04 Bytes - either "sampleRaw" or "rawSampleAgc" depending on soundAgc setting 1528 | float sampleSmth; // 04 Bytes - either "sampleAvg" or "sampleAgc" depending on soundAgc setting 1529 | uint8_t samplePeak; // 01 Bytes - 0 no peak; >=1 peak detected. In future, this will also provide peak Magnitude 1530 | uint8_t reserved1; // 01 Bytes - for future extensions - not used yet 1531 | uint8_t fftResult[16]; // 16 Bytes 1532 | float FFT_Magnitude; // 04 Bytes 1533 | float FFT_MajorPeak; // 04 Bytes 1534 | 1535 | */ 1536 | 1537 | // FFT Magnitude 4 bytes 1538 | var fftMagArray = createIntArray(util.floatToHexSeq(wledMag,true)); 1539 | 1540 | // FFT Max Freq 4 bytes 1541 | var fftFreqArray = createIntArray(util.floatToHexSeq(wledFreq,true)); 1542 | 1543 | // Header 1544 | UDP_AUDIO_SYNC_V2[0] = 48; 1545 | UDP_AUDIO_SYNC_V2[1] = 48; 1546 | UDP_AUDIO_SYNC_V2[2] = 48; 1547 | UDP_AUDIO_SYNC_V2[3] = 48; 1548 | UDP_AUDIO_SYNC_V2[4] = 50; 1549 | UDP_AUDIO_SYNC_V2[5] = 0; 1550 | // Filler 1551 | UDP_AUDIO_SYNC_V2[6] = 0; 1552 | UDP_AUDIO_SYNC_V2[7] = 0; 1553 | // sampleRaw 1554 | UDP_AUDIO_SYNC_V2[8] = udpdataV1[44]; 1555 | UDP_AUDIO_SYNC_V2[9] = udpdataV1[45]; 1556 | UDP_AUDIO_SYNC_V2[10] = udpdataV1[46]; 1557 | UDP_AUDIO_SYNC_V2[11] = udpdataV1[47]; 1558 | // sampleSmth 1559 | UDP_AUDIO_SYNC_V2[12] = udpdataV1[44]; 1560 | UDP_AUDIO_SYNC_V2[13] = udpdataV1[45]; 1561 | UDP_AUDIO_SYNC_V2[14] = udpdataV1[46]; 1562 | UDP_AUDIO_SYNC_V2[15] = udpdataV1[47]; 1563 | // samplePeak 1564 | UDP_AUDIO_SYNC_V2[16] = udpdataV1[52]; 1565 | //for future extensions - not used yet 1566 | UDP_AUDIO_SYNC_V2[17] = 0; 1567 | // FFT 1568 | UDP_AUDIO_SYNC_V2[18] = udpdataV1[53]; 1569 | UDP_AUDIO_SYNC_V2[19] = udpdataV1[54]; 1570 | UDP_AUDIO_SYNC_V2[20] = udpdataV1[55]; 1571 | UDP_AUDIO_SYNC_V2[21] = udpdataV1[56]; 1572 | UDP_AUDIO_SYNC_V2[22] = udpdataV1[57]; 1573 | UDP_AUDIO_SYNC_V2[23] = udpdataV1[58]; 1574 | UDP_AUDIO_SYNC_V2[24] = udpdataV1[59]; 1575 | UDP_AUDIO_SYNC_V2[25] = udpdataV1[60]; 1576 | UDP_AUDIO_SYNC_V2[26] = udpdataV1[61]; 1577 | UDP_AUDIO_SYNC_V2[27] = udpdataV1[62]; 1578 | UDP_AUDIO_SYNC_V2[28] = udpdataV1[63]; 1579 | UDP_AUDIO_SYNC_V2[29] = udpdataV1[64]; 1580 | UDP_AUDIO_SYNC_V2[30] = udpdataV1[65]; 1581 | UDP_AUDIO_SYNC_V2[31] = udpdataV1[66]; 1582 | UDP_AUDIO_SYNC_V2[32] = udpdataV1[67]; 1583 | UDP_AUDIO_SYNC_V2[33] = udpdataV1[68]; 1584 | // Filler 1585 | UDP_AUDIO_SYNC_V2[34] = 0; 1586 | UDP_AUDIO_SYNC_V2[35] = 0; 1587 | // FFT_Magnitude 1588 | UDP_AUDIO_SYNC_V2[36] = fftMagArray[3]; 1589 | UDP_AUDIO_SYNC_V2[37] = fftMagArray[2]; 1590 | UDP_AUDIO_SYNC_V2[38] = fftMagArray[1]; 1591 | UDP_AUDIO_SYNC_V2[39] = fftMagArray[0]; 1592 | // FFT_MajorPeak 1593 | UDP_AUDIO_SYNC_V2[40] = fftFreqArray[3]; 1594 | UDP_AUDIO_SYNC_V2[41] = fftFreqArray[2]; 1595 | UDP_AUDIO_SYNC_V2[42] = fftFreqArray[1]; 1596 | UDP_AUDIO_SYNC_V2[43] = fftFreqArray[0]; 1597 | 1598 | return UDP_AUDIO_SYNC_V2; 1599 | } 1600 | 1601 | /* 1602 | 1603 | OSC Module 1604 | 1605 | */ 1606 | 1607 | function addOSCScript(scriptName) 1608 | { 1609 | OSCModule = root.modules.getItemWithName("OSC"); 1610 | // create module if not exist 1611 | if (OSCModule.name == "undefined" ) 1612 | { 1613 | script.log("Create OSC"); 1614 | OSCModule = root.modules.addItem("OSC"); 1615 | } 1616 | 1617 | var localTest = ''; 1618 | if (scriptName == "OSCBPM") 1619 | { 1620 | localTest = local.parameters.getChild("Beat Params"); 1621 | 1622 | } else if (scriptName == "OSCRTMGC") { 1623 | 1624 | localTest = local.parameters.getChild("RTMGC Params"); 1625 | 1626 | } else if (scriptName == "OSCRTMMD") { 1627 | 1628 | localTest = local.parameters.getChild("RTMMD Params"); 1629 | 1630 | } else { 1631 | 1632 | script.log('unknown script'); 1633 | return; 1634 | } 1635 | 1636 | 1637 | var testScript = OSCModule.scripts.getChild(scriptName); 1638 | if (testScript.name == "undefined") 1639 | { 1640 | var mysc = OSCModule.scripts.addItem(); 1641 | 1642 | if (localTest.scriptFile.get() == scriptName + ".js") 1643 | { 1644 | mysc.filePath.set(homeDIR + moduleDIR + scriptName+".js"); 1645 | 1646 | } else { 1647 | 1648 | mysc.filePath.set(localTest.scriptFile.get()); 1649 | } 1650 | } 1651 | 1652 | } 1653 | 1654 | 1655 | /* 1656 | 1657 | Utilities 1658 | 1659 | */ 1660 | 1661 | // Convert Sequence of Hex Char values ( from 00 to FF ) to int Array 1662 | function createIntArray(hexSequence) 1663 | { 1664 | var intArray = []; 1665 | var j = 0; 1666 | 1667 | for ( var i = 0; i < hexSequence.length; i+=2 ) 1668 | { 1669 | intArray[j] = util.hexStringToInt(hexSequence.substring(i,i+1) + hexSequence.substring(i+1,i+2)); 1670 | j +=1; 1671 | } 1672 | 1673 | return intArray; 1674 | } 1675 | 1676 | // Will bind to UDP port on specified IP address and join the MulticastGroup 1677 | // On 10/03/2023: Multicast do not work as expected on Chataigne, mainly when more than one network card 1678 | function testMultiCast() 1679 | { 1680 | myIP = local.parameters.ipAddressToBind.getKey(); 1681 | script.log(myIP , multicastIP , uDPPort); 1682 | 1683 | var multiExeCmd = homeDIR + moduleDIR + multicastCmdName; 1684 | if (util.fileExists(multiExeCmd)) 1685 | { 1686 | script.log("multicastCmdName Ok"); 1687 | var multiOptions = " --ip " + myIP + " --group " + multicastIP + " --port " + uDPPort; 1688 | var exeCMD = multiExeCmd + multiOptions; 1689 | script.log('command to run : '+ exeCMD); 1690 | // we execute the cmd 1691 | var launchresult = root.modules.os.launchProcess(exeCMD, false); 1692 | 1693 | } else { 1694 | 1695 | script.log('multicmd not found'); 1696 | } 1697 | } 1698 | 1699 | // replay audio data from snapshot file 1700 | function runReplay(fileName, myduration) 1701 | { 1702 | duration = myduration; 1703 | 1704 | // if same file for replay, avoid to read it again and again 1705 | if (fileName != previousFile) 1706 | { 1707 | script.log("File Name : " + fileName); 1708 | if (fileName == ""){return;} 1709 | SOUNDDATA = []; 1710 | SOUNDDATA = util.readFile(fileName).split(";"); 1711 | previousFile = fileName; 1712 | } 1713 | 1714 | // set audio datas 1715 | wledVol = SOUNDDATA[0]; 1716 | wledPeak = SOUNDDATA[1]; 1717 | wledMag = SOUNDDATA[2]; 1718 | wledFreq = SOUNDDATA[3]; 1719 | 1720 | for ( var i = 0; i < 16; i += 1 ) 1721 | { 1722 | FFTWLED[i] = SOUNDDATA[4+i]; 1723 | } 1724 | 1725 | replay = true; 1726 | script.setUpdateRate(10); 1727 | } 1728 | 1729 | // Find Audio input device name 1730 | function audioFindInput() 1731 | { 1732 | var audioInput = ""; 1733 | 1734 | var JSONobj = root.modules.soundCard.getJSONData(); 1735 | var JSONdata = JSON.stringify(JSONobj.audioSettings); 1736 | var audioSettings = JSONdata.split("="); 1737 | 1738 | for ( var i = 0; i < audioSettings.length ; i++) 1739 | { 1740 | if (audioSettings[i].contains("audioInputDeviceName")) 1741 | { 1742 | audioInput = audioSettings[i+1].split('"')[1]; 1743 | break; 1744 | } 1745 | } 1746 | 1747 | audioInput = audioInput.substring(0,audioInput.length-1); 1748 | 1749 | return audioInput; 1750 | } 1751 | 1752 | // retreive temp location 1753 | function findTMP () 1754 | { 1755 | script.log("Retreive temp folder"); 1756 | // TMP, TMPDIR, and TEMP environment variables 1757 | var pathTMP = util.getEnvironmentVariable("TMP"); 1758 | var pathTMPDIR = util.getEnvironmentVariable("TMPDIR"); 1759 | var pathTEMP = util.getEnvironmentVariable("TEMP"); 1760 | 1761 | if (pathTMP != "") 1762 | { 1763 | tempDIR = pathTMP; 1764 | return tempDIR; 1765 | 1766 | } else if (pathTMPDIR != ""){ 1767 | tempDIR = pathTMPDIR; 1768 | return tempDIR; 1769 | 1770 | } else if (pathTEMP != ""){ 1771 | tempDIR = pathTEMP; 1772 | return tempDIR; 1773 | } 1774 | 1775 | script.log('ERROR temp directory not found'); 1776 | 1777 | return tempDIR; 1778 | } 1779 | 1780 | // retreive devices list from aubio 1781 | function aubioDevicesList() 1782 | { 1783 | var fileTmp = findTMP() + "/aubioDevicesList.tmp"; 1784 | var command = homeDIR + moduleDIR + aubioCmdName + " list >" + fileTmp; 1785 | var result = root.modules.os.launchCommand(command, false); 1786 | var devicesList = util.readFile(fileTmp).split("\n"); 1787 | 1788 | local.parameters.beatParams.inputAudio.removeOptions(); 1789 | 1790 | for ( var i = 0; i < devicesList.length ; i ++) 1791 | { 1792 | if (devicesList[i].startsWith("[")) 1793 | { 1794 | local.parameters.beatParams.inputAudio.addOption(devicesList[i].replace("\n","").replace("\r",""),devicesList[i].substring(1,2)); 1795 | } 1796 | } 1797 | } 1798 | 1799 | // Deactivate FFT 1800 | 1801 | // bass 1802 | function bassFFT(onOff) 1803 | { 1804 | if (onOff) 1805 | { 1806 | root.modules.soundCard.parameters.fftAnalysis.analyzer1.enabled.set(1); 1807 | root.modules.soundCard.parameters.fftAnalysis.analyzer2.enabled.set(1); 1808 | root.modules.soundCard.parameters.fftAnalysis.analyzer3.enabled.set(1); 1809 | root.modules.soundCard.parameters.fftAnalysis.analyzer4.enabled.set(1); 1810 | 1811 | } else { 1812 | root.modules.soundCard.parameters.fftAnalysis.analyzer1.enabled.set(0); 1813 | root.modules.soundCard.parameters.fftAnalysis.analyzer2.enabled.set(0); 1814 | root.modules.soundCard.parameters.fftAnalysis.analyzer3.enabled.set(0); 1815 | root.modules.soundCard.parameters.fftAnalysis.analyzer4.enabled.set(0); 1816 | } 1817 | } 1818 | // midrange 1819 | function midFFT(onOff) 1820 | { 1821 | if (onOff) 1822 | { 1823 | root.modules.soundCard.parameters.fftAnalysis.analyzer5.enabled.set(1); 1824 | root.modules.soundCard.parameters.fftAnalysis.analyzer6.enabled.set(1); 1825 | root.modules.soundCard.parameters.fftAnalysis.analyzer7.enabled.set(1); 1826 | root.modules.soundCard.parameters.fftAnalysis.analyzer8.enabled.set(1); 1827 | root.modules.soundCard.parameters.fftAnalysis.analyzer9.enabled.set(1); 1828 | root.modules.soundCard.parameters.fftAnalysis.analyzer10.enabled.set(1); 1829 | root.modules.soundCard.parameters.fftAnalysis.analyzer11.enabled.set(1); 1830 | 1831 | } else { 1832 | root.modules.soundCard.parameters.fftAnalysis.analyzer5.enabled.set(0); 1833 | root.modules.soundCard.parameters.fftAnalysis.analyzer6.enabled.set(0); 1834 | root.modules.soundCard.parameters.fftAnalysis.analyzer7.enabled.set(0); 1835 | root.modules.soundCard.parameters.fftAnalysis.analyzer8.enabled.set(0); 1836 | root.modules.soundCard.parameters.fftAnalysis.analyzer9.enabled.set(0); 1837 | root.modules.soundCard.parameters.fftAnalysis.analyzer10.enabled.set(0); 1838 | root.modules.soundCard.parameters.fftAnalysis.analyzer11.enabled.set(0); 1839 | } 1840 | } 1841 | // high 1842 | function highFFT(onOff) 1843 | { 1844 | if (onOff) 1845 | { 1846 | root.modules.soundCard.parameters.fftAnalysis.analyzer12.enabled.set(1); 1847 | root.modules.soundCard.parameters.fftAnalysis.analyzer13.enabled.set(1); 1848 | root.modules.soundCard.parameters.fftAnalysis.analyzer14.enabled.set(1); 1849 | root.modules.soundCard.parameters.fftAnalysis.analyzer15.enabled.set(1); 1850 | root.modules.soundCard.parameters.fftAnalysis.analyzer16.enabled.set(1); 1851 | 1852 | } else { 1853 | root.modules.soundCard.parameters.fftAnalysis.analyzer12.enabled.set(0); 1854 | root.modules.soundCard.parameters.fftAnalysis.analyzer13.enabled.set(0); 1855 | root.modules.soundCard.parameters.fftAnalysis.analyzer14.enabled.set(0); 1856 | root.modules.soundCard.parameters.fftAnalysis.analyzer15.enabled.set(0); 1857 | root.modules.soundCard.parameters.fftAnalysis.analyzer16.enabled.set(0); 1858 | } 1859 | } 1860 | // reset volume & magnitude multiplier 1861 | function resetVolMag() 1862 | { 1863 | local.parameters.volumeMultiplier.set(512); 1864 | local.parameters.frequencyMagnitudeMultiplier.set(254); 1865 | } 1866 | 1867 | // true if module exist 1868 | function checkModuleExist (moduleName) 1869 | { 1870 | var moduleExist = root.modules.getItemWithName(moduleName); 1871 | var result = false; 1872 | if (moduleExist.name != "undefined") 1873 | { 1874 | result = true; 1875 | } 1876 | return result; 1877 | } 1878 | 1879 | // just for some test 1880 | function test() 1881 | { 1882 | 1883 | } -------------------------------------------------------------------------------- /WLEDAudioSync30.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zak-45/WLEDAudioSync-Chataigne-Module/3e8532314b8522d15b41c9bb088677810ca87eeb/WLEDAudioSync30.ico -------------------------------------------------------------------------------- /aubio.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem this is the cmd file for aubio-beat-osc 3 | Rem need to be adapted depend on the running OS, this one is for Win 4 | Rem will receive these parameters on entry " beat -c " + OSCIP + " " + root.modules.osc.parameters.oscInput.localPort.get() + ' "/WLEDAudioSync/beat/BPM"' + 5 | Rem " -d " + aubioDevices[i].value + 6 | Rem " -b " + aubioBuffer; 7 | Rem which will give " beat -c 127.0.0.1 12000 /WLEDAudioSync/beat/BPM -d 1 -b 128" for example 8 | 9 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTBeat\" GOTO :folder 10 | 11 | %USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTBeat-Windows.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 12 | 13 | GOTO :end 14 | 15 | :folder 16 | 17 | %USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTBeat\WLEDAudioSyncRTBeat-Windows.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 18 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTBeat-Windows.exe" del "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTBeat-Windows.exe" 19 | 20 | GOTO :end 21 | 22 | :end 23 | 24 | exit -------------------------------------------------------------------------------- /friture.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem this is the cmd file for Friture 3 | Rem need to be adapted depend on the running OS, this one is for Win 4 | 5 | start /D "%USERPROFILE%\Documents\Chataigne\Python\WPy64-39100\Friture\" friture.exe /B 6 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zak-45/WLEDAudioSync-Chataigne-Module/3e8532314b8522d15b41c9bb088677810ca87eeb/icon.png -------------------------------------------------------------------------------- /labels.txt: -------------------------------------------------------------------------------- 1 | "Blues---Boogie Woogie", 2 | "Blues---Chicago Blues", 3 | "Blues---Country Blues", 4 | "Blues---Delta Blues", 5 | "Blues---Electric Blues", 6 | "Blues---Harmonica Blues", 7 | "Blues---Jump Blues", 8 | "Blues---Louisiana Blues", 9 | "Blues---Modern Electric Blues", 10 | "Blues---Piano Blues", 11 | "Blues---Rhythm & Blues", 12 | "Blues---Texas Blues", 13 | "Children's---Educational", 14 | "Children's---Nursery Rhymes", 15 | "Children's---Story", 16 | "Classical---Baroque", 17 | "Classical---Choral", 18 | "Classical---Classical", 19 | "Classical---Contemporary", 20 | "Classical---Impressionist", 21 | "Classical---Medieval", 22 | "Classical---Modern", 23 | "Classical---Neo-Classical", 24 | "Classical---Neo-Romantic", 25 | "Classical---Opera", 26 | "Classical---Post-Modern", 27 | "Classical---Renaissance", 28 | "Classical---Romantic", 29 | "Electronic---Abstract", 30 | "Electronic---Acid", 31 | "Electronic---Acid House", 32 | "Electronic---Acid Jazz", 33 | "Electronic---Ambient", 34 | "Electronic---Bassline", 35 | "Electronic---Beatdown", 36 | "Electronic---Berlin-School", 37 | "Electronic---Big Beat", 38 | "Electronic---Bleep", 39 | "Electronic---Breakbeat", 40 | "Electronic---Breakcore", 41 | "Electronic---Breaks", 42 | "Electronic---Broken Beat", 43 | "Electronic---Chillwave", 44 | "Electronic---Chiptune", 45 | "Electronic---Dance-pop", 46 | "Electronic---Dark Ambient", 47 | "Electronic---Darkwave", 48 | "Electronic---Deep House", 49 | "Electronic---Deep Techno", 50 | "Electronic---Disco", 51 | "Electronic---Disco Polo", 52 | "Electronic---Donk", 53 | "Electronic---Downtempo", 54 | "Electronic---Drone", 55 | "Electronic---Drum n Bass", 56 | "Electronic---Dub", 57 | "Electronic---Dub Techno", 58 | "Electronic---Dubstep", 59 | "Electronic---Dungeon Synth", 60 | "Electronic---EBM", 61 | "Electronic---Electro", 62 | "Electronic---Electro House", 63 | "Electronic---Electroclash", 64 | "Electronic---Euro House", 65 | "Electronic---Euro-Disco", 66 | "Electronic---Eurobeat", 67 | "Electronic---Eurodance", 68 | "Electronic---Experimental", 69 | "Electronic---Freestyle", 70 | "Electronic---Future Jazz", 71 | "Electronic---Gabber", 72 | "Electronic---Garage House", 73 | "Electronic---Ghetto", 74 | "Electronic---Ghetto House", 75 | "Electronic---Glitch", 76 | "Electronic---Goa Trance", 77 | "Electronic---Grime", 78 | "Electronic---Halftime", 79 | "Electronic---Hands Up", 80 | "Electronic---Happy Hardcore", 81 | "Electronic---Hard House", 82 | "Electronic---Hard Techno", 83 | "Electronic---Hard Trance", 84 | "Electronic---Hardcore", 85 | "Electronic---Hardstyle", 86 | "Electronic---Hi NRG", 87 | "Electronic---Hip Hop", 88 | "Electronic---Hip-House", 89 | "Electronic---House", 90 | "Electronic---IDM", 91 | "Electronic---Illbient", 92 | "Electronic---Industrial", 93 | "Electronic---Italo House", 94 | "Electronic---Italo-Disco", 95 | "Electronic---Italodance", 96 | "Electronic---Jazzdance", 97 | "Electronic---Juke", 98 | "Electronic---Jumpstyle", 99 | "Electronic---Jungle", 100 | "Electronic---Latin", 101 | "Electronic---Leftfield", 102 | "Electronic---Makina", 103 | "Electronic---Minimal", 104 | "Electronic---Minimal Techno", 105 | "Electronic---Modern Classical", 106 | "Electronic---Musique Concrète", 107 | "Electronic---Neo Trance", 108 | "Electronic---Neofolk", 109 | "Electronic---New Age", 110 | "Electronic---New Beat", 111 | "Electronic---New Wave", 112 | "Electronic---Noise", 113 | "Electronic---Nu-Disco", 114 | "Electronic---Power Electronics", 115 | "Electronic---Progressive Breaks", 116 | "Electronic---Progressive House", 117 | "Electronic---Progressive Trance", 118 | "Electronic---Psy-Trance", 119 | "Electronic---Rhythmic Noise", 120 | "Electronic---Schranz", 121 | "Electronic---Sound Collage", 122 | "Electronic---Speed Garage", 123 | "Electronic---Speedcore", 124 | "Electronic---Synth-pop", 125 | "Electronic---Synthwave", 126 | "Electronic---Tech House", 127 | "Electronic---Tech Trance", 128 | "Electronic---Techno", 129 | "Electronic---Trance", 130 | "Electronic---Tribal", 131 | "Electronic---Tribal House", 132 | "Electronic---Trip Hop", 133 | "Electronic---Tropical House", 134 | "Electronic---UK Garage", 135 | "Electronic---Vaporwave", 136 | "Folk, World, & Country---African", 137 | "Folk, World, & Country---Bluegrass", 138 | "Folk, World, & Country---Cajun", 139 | "Folk, World, & Country---Canzone Napoletana", 140 | "Folk, World, & Country---Celtic", 141 | "Folk, World, & Country---Country", 142 | "Folk, World, & Country---Fado", 143 | "Folk, World, & Country---Flamenco", 144 | "Folk, World, & Country---Folk", 145 | "Folk, World, & Country---Gamelan", 146 | "Folk, World, & Country---Gospel", 147 | "Folk, World, & Country---Hawaiian", 148 | "Folk, World, & Country---Highlife", 149 | "Folk, World, & Country---Hillbilly", 150 | "Folk, World, & Country---Hindustani", 151 | "Folk, World, & Country---Honky Tonk", 152 | "Folk, World, & Country---Indian Classical", 153 | "Folk, World, & Country---Klezmer", 154 | "Folk, World, & Country---Laïkó", 155 | "Folk, World, & Country---Nordic", 156 | "Folk, World, & Country---Pacific", 157 | "Folk, World, & Country---Polka", 158 | "Folk, World, & Country---Raï", 159 | "Folk, World, & Country---Romani", 160 | "Folk, World, & Country---Soukous", 161 | "Folk, World, & Country---Séga", 162 | "Folk, World, & Country---Volksmusik", 163 | "Folk, World, & Country---Zouk", 164 | "Folk, World, & Country---Éntekhno", 165 | "Funk / Soul---Afrobeat", 166 | "Funk / Soul---Bayou Funk", 167 | "Funk / Soul---Boogie", 168 | "Funk / Soul---Contemporary R&B", 169 | "Funk / Soul---Disco", 170 | "Funk / Soul---Free Funk", 171 | "Funk / Soul---Funk", 172 | "Funk / Soul---Gospel", 173 | "Funk / Soul---Neo Soul", 174 | "Funk / Soul---New Jack Swing", 175 | "Funk / Soul---P.Funk", 176 | "Funk / Soul---Psychedelic", 177 | "Funk / Soul---Rhythm & Blues", 178 | "Funk / Soul---Soul", 179 | "Funk / Soul---Swingbeat", 180 | "Funk / Soul---UK Street Soul", 181 | "Hip Hop---Bass Music", 182 | "Hip Hop---Boom Bap", 183 | "Hip Hop---Bounce", 184 | "Hip Hop---Britcore", 185 | "Hip Hop---Cloud Rap", 186 | "Hip Hop---Conscious", 187 | "Hip Hop---Crunk", 188 | "Hip Hop---Cut-up/DJ", 189 | "Hip Hop---DJ Battle Tool", 190 | "Hip Hop---Electro", 191 | "Hip Hop---G-Funk", 192 | "Hip Hop---Gangsta", 193 | "Hip Hop---Grime", 194 | "Hip Hop---Hardcore Hip-Hop", 195 | "Hip Hop---Horrorcore", 196 | "Hip Hop---Instrumental", 197 | "Hip Hop---Jazzy Hip-Hop", 198 | "Hip Hop---Miami Bass", 199 | "Hip Hop---Pop Rap", 200 | "Hip Hop---Ragga HipHop", 201 | "Hip Hop---RnB/Swing", 202 | "Hip Hop---Screw", 203 | "Hip Hop---Thug Rap", 204 | "Hip Hop---Trap", 205 | "Hip Hop---Trip Hop", 206 | "Hip Hop---Turntablism", 207 | "Jazz---Afro-Cuban Jazz", 208 | "Jazz---Afrobeat", 209 | "Jazz---Avant-garde Jazz", 210 | "Jazz---Big Band", 211 | "Jazz---Bop", 212 | "Jazz---Bossa Nova", 213 | "Jazz---Contemporary Jazz", 214 | "Jazz---Cool Jazz", 215 | "Jazz---Dixieland", 216 | "Jazz---Easy Listening", 217 | "Jazz---Free Improvisation", 218 | "Jazz---Free Jazz", 219 | "Jazz---Fusion", 220 | "Jazz---Gypsy Jazz", 221 | "Jazz---Hard Bop", 222 | "Jazz---Jazz-Funk", 223 | "Jazz---Jazz-Rock", 224 | "Jazz---Latin Jazz", 225 | "Jazz---Modal", 226 | "Jazz---Post Bop", 227 | "Jazz---Ragtime", 228 | "Jazz---Smooth Jazz", 229 | "Jazz---Soul-Jazz", 230 | "Jazz---Space-Age", 231 | "Jazz---Swing", 232 | "Latin---Afro-Cuban", 233 | "Latin---Baião", 234 | "Latin---Batucada", 235 | "Latin---Beguine", 236 | "Latin---Bolero", 237 | "Latin---Boogaloo", 238 | "Latin---Bossanova", 239 | "Latin---Cha-Cha", 240 | "Latin---Charanga", 241 | "Latin---Compas", 242 | "Latin---Cubano", 243 | "Latin---Cumbia", 244 | "Latin---Descarga", 245 | "Latin---Forró", 246 | "Latin---Guaguancó", 247 | "Latin---Guajira", 248 | "Latin---Guaracha", 249 | "Latin---MPB", 250 | "Latin---Mambo", 251 | "Latin---Mariachi", 252 | "Latin---Merengue", 253 | "Latin---Nueva Cancion", 254 | "Latin---Pachanga", 255 | "Latin---Porro", 256 | "Latin---Ranchera", 257 | "Latin---Reggaeton", 258 | "Latin---Rumba", 259 | "Latin---Salsa", 260 | "Latin---Samba", 261 | "Latin---Son", 262 | "Latin---Son Montuno", 263 | "Latin---Tango", 264 | "Latin---Tejano", 265 | "Latin---Vallenato", 266 | "Non-Music---Comedy", 267 | "Non-Music---Dialogue", 268 | "Non-Music---Education", 269 | "Non-Music---Field Recording", 270 | "Non-Music---Interview", 271 | "Non-Music---Monolog", 272 | "Non-Music---Poetry", 273 | "Non-Music---Political", 274 | "Non-Music---Promotional", 275 | "Non-Music---Radioplay", 276 | "Non-Music---Religious", 277 | "Non-Music---Speech", 278 | "Non-Music---Spoken Word", 279 | "Pop---Ballad", 280 | "Pop---Bollywood", 281 | "Pop---Bubblegum", 282 | "Pop---Chanson", 283 | "Pop---City Pop", 284 | "Pop---Europop", 285 | "Pop---Indie Pop", 286 | "Pop---J-pop", 287 | "Pop---K-pop", 288 | "Pop---Kayōkyoku", 289 | "Pop---Light Music", 290 | "Pop---Music Hall", 291 | "Pop---Novelty", 292 | "Pop---Parody", 293 | "Pop---Schlager", 294 | "Pop---Vocal", 295 | "Reggae---Calypso", 296 | "Reggae---Dancehall", 297 | "Reggae---Dub", 298 | "Reggae---Dub Poetry", 299 | "Reggae---Lovers Rock", 300 | "Reggae---Ragga", 301 | "Reggae---Reggae", 302 | "Reggae---Reggae-Pop", 303 | "Reggae---Rocksteady", 304 | "Reggae---Roots Reggae", 305 | "Reggae---Ska", 306 | "Reggae---Soca", 307 | "Rock---AOR", 308 | "Rock---Acid Rock", 309 | "Rock---Acoustic", 310 | "Rock---Alternative Rock", 311 | "Rock---Arena Rock", 312 | "Rock---Art Rock", 313 | "Rock---Atmospheric Black Metal", 314 | "Rock---Avantgarde", 315 | "Rock---Beat", 316 | "Rock---Black Metal", 317 | "Rock---Blues Rock", 318 | "Rock---Brit Pop", 319 | "Rock---Classic Rock", 320 | "Rock---Coldwave", 321 | "Rock---Country Rock", 322 | "Rock---Crust", 323 | "Rock---Death Metal", 324 | "Rock---Deathcore", 325 | "Rock---Deathrock", 326 | "Rock---Doo Wop", 327 | "Rock---Doom Metal", 328 | "Rock---Dream Pop", 329 | "Rock---Emo", 330 | "Rock---Ethereal", 331 | "Rock---Experimental", 332 | "Rock---Folk Metal", 333 | "Rock---Folk Rock", 334 | "Rock---Funeral Doom Metal", 335 | "Rock---Funk Metal", 336 | "Rock---Garage Rock", 337 | "Rock---Glam", 338 | "Rock---Goregrind", 339 | "Rock---Goth Rock", 340 | "Rock---Gothic Metal", 341 | "Rock---Grindcore", 342 | "Rock---Grunge", 343 | "Rock---Hard Rock", 344 | "Rock---Hardcore", 345 | "Rock---Heavy Metal", 346 | "Rock---Indie Rock", 347 | "Rock---Industrial", 348 | "Rock---Krautrock", 349 | "Rock---Lo-Fi", 350 | "Rock---Lounge", 351 | "Rock---Math Rock", 352 | "Rock---Melodic Death Metal", 353 | "Rock---Melodic Hardcore", 354 | "Rock---Metalcore", 355 | "Rock---Mod", 356 | "Rock---Neofolk", 357 | "Rock---New Wave", 358 | "Rock---No Wave", 359 | "Rock---Noise", 360 | "Rock---Noisecore", 361 | "Rock---Nu Metal", 362 | "Rock---Oi", 363 | "Rock---Parody", 364 | "Rock---Pop Punk", 365 | "Rock---Pop Rock", 366 | "Rock---Pornogrind", 367 | "Rock---Post Rock", 368 | "Rock---Post-Hardcore", 369 | "Rock---Post-Metal", 370 | "Rock---Post-Punk", 371 | "Rock---Power Metal", 372 | "Rock---Power Pop", 373 | "Rock---Power Violence", 374 | "Rock---Prog Rock", 375 | "Rock---Progressive Metal", 376 | "Rock---Psychedelic Rock", 377 | "Rock---Psychobilly", 378 | "Rock---Pub Rock", 379 | "Rock---Punk", 380 | "Rock---Rock & Roll", 381 | "Rock---Rockabilly", 382 | "Rock---Shoegaze", 383 | "Rock---Ska", 384 | "Rock---Sludge Metal", 385 | "Rock---Soft Rock", 386 | "Rock---Southern Rock", 387 | "Rock---Space Rock", 388 | "Rock---Speed Metal", 389 | "Rock---Stoner Rock", 390 | "Rock---Surf", 391 | "Rock---Symphonic Rock", 392 | "Rock---Technical Death Metal", 393 | "Rock---Thrash", 394 | "Rock---Twist", 395 | "Rock---Viking Metal", 396 | "Rock---Yé-Yé", 397 | "Stage & Screen---Musical", 398 | "Stage & Screen---Score", 399 | "Stage & Screen---Soundtrack", 400 | "Stage & Screen---Theme" 401 | -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WLEDAudioSync", 3 | "type": "UDP", 4 | "path": "Protocol", 5 | "version": "2.1.1", 6 | "description": "Stream Sound data to your WLED Sound Reactive", 7 | "url":"", 8 | "downloadURL": "", 9 | "hasInput": false, 10 | "hasOutput": true, 11 | "hideDefaultCommands": false, 12 | "hideDefaultParameters": [ 13 | "protocol", 14 | "autoAdd", 15 | "messageStructure", 16 | "firstValueIsTheName", 17 | "input" 18 | ], 19 | 20 | "defaults": { 21 | "input":{ 22 | "enabled": false 23 | }, 24 | "autoAdd" : false, 25 | "protocol" : "Raw", 26 | "output":{ 27 | "local": false, 28 | "remoteHost": "239.0.0.1", 29 | "remotePort" : 11988 30 | }, 31 | "multicastMode": true 32 | }, 33 | "parameters": { 34 | "IP Address to bind": { 35 | "type": "Enum", 36 | "description": "Bind Port to this IP address and send a test message. 37 | Used if you're in trouble to send to the Multicast Group", 38 | "default": "127.0.0.1", 39 | "readOnly": false, 40 | "options": { 41 | "127.0.0.1":"127.0.0.1" 42 | } 43 | }, 44 | "Send Test Message": { 45 | "type": "Trigger", 46 | "description": "Click to send test message to the Multicast Group", 47 | }, 48 | "Live": { 49 | "type": "Boolean", 50 | "description": "Use live audio datas", 51 | "default": true 52 | }, 53 | "Visualize live audio": { 54 | "type": "Trigger", 55 | "description": "Friture is a real-time audio analyzer. 56 | It works on Windows, macOS and Linux. It is free and open source.", 57 | }, 58 | "Audio V1": { 59 | "type": "Boolean", 60 | "description": "V1 message structure", 61 | "default": false 62 | }, 63 | "Audio V2": { 64 | "type": "Boolean", 65 | "description": "V2 message structure", 66 | "default": true 67 | }, 68 | "Delay": { 69 | "type": "Integer", 70 | "description": "Delay to send audio data (ms) : max 256. 71 | Audio datas during the delay are lost", 72 | "default": 0, 73 | "min": 0, 74 | "max": 256 75 | }, 76 | "Volume Multiplier": { 77 | "type": "Float", 78 | "description": "Volume level multiplier", 79 | "default": 512, 80 | "min":0, 81 | "max":5120 82 | }, 83 | "Frequency Magnitude Multiplier": { 84 | "type": "Float", 85 | "description": "Frequency magnitude level multiplier", 86 | "default": 254, 87 | "min":0, 88 | "max":2540 89 | }, 90 | "Take Snapshot": { 91 | "type": "Trigger", 92 | "description": "Take a snapshot of audio data for replay", 93 | }, 94 | "Beat Params":{ 95 | "type": "Container", 96 | "description":"Aubio Beat BPM parameters", 97 | "collapsed": true, 98 | "Use BPM": { 99 | "type": "Boolean", 100 | "description": "Checked, will use custom Live BPM calculation received via OSC ", 101 | "default": false 102 | }, 103 | "Aubio Buffer": { 104 | "type": "Integer", 105 | "description": "Select the size of the buffer used for beat detection. 106 | A larger buffer is more accurate, but also more sluggish. 107 | Refer to the aubio documentation of the tempo module for more details. 108 | Example: -b 128", 109 | "default": 512, 110 | "min": 1, 111 | "max": 1024 112 | }, 113 | "Input audio": { 114 | "type": "Enum", 115 | "description": "Choose audio device name for input (first 9 only). 116 | Appear only if you click in Use BPM. 117 | You need to use it only if you want to bypass Chataigne's input audio or have some trouble.", 118 | "readOnly": false, 119 | "options" : {} 120 | }, 121 | "Force reload": { 122 | "type": "Trigger", 123 | "description": "Re run the BPM calculation process with 'Input audio' data", 124 | "readOnly": false 125 | }, 126 | "Script file": { 127 | "type": "File", 128 | "description": "OSC Script file name", 129 | "readOnly": false, 130 | "default" : "OSCBPM.js" 131 | }, 132 | "Sync to beat": { 133 | "type":"Boolean", 134 | "description":" Check it to send UDP message synchronized to beat", 135 | "default":false 136 | }, 137 | "Beat type": { 138 | "type": "Enum", 139 | "description": "Select odd, even, or both to send frame", 140 | "readOnly": false, 141 | "options" : { 142 | "Both":0, 143 | "Even":1, 144 | "Odd":2 145 | }, 146 | "default":"Both" 147 | } 148 | }, 149 | "RTMGC Params":{ 150 | "type": "Container", 151 | "description":"Real Time Music Genre Classification parameters", 152 | "collapsed": true, 153 | "Use RTMGC": { 154 | "type": "Boolean", 155 | "description": "Checked, will use RTMGC 156 | Real Time Music Genre Classification", 157 | "default": false 158 | }, 159 | "Include All Predictions": { 160 | "type": "Boolean", 161 | "description": "Check to include all prediction datas to determine the Most Probale Genre. 162 | Otherwise, only the first one (with 1.0 score) will be selected.", 163 | "default": false 164 | }, 165 | "Include BPM Data": { 166 | "type": "Boolean", 167 | "description": "Check to include probable genre from BPM to determine the Most Probale Genre ", 168 | "default": false 169 | }, 170 | "Server Port": { 171 | "type": "Integer", 172 | "description": "NodeJs server port : max 65536", 173 | "default": 8000, 174 | "min": 1, 175 | "max": 65536 176 | }, 177 | "Script file": { 178 | "type": "File", 179 | "description": "OSC Script file name", 180 | "readOnly": false, 181 | "default" : "OSCRTMGC.js" 182 | } 183 | }, 184 | "RTMMD Params":{ 185 | "type": "Container", 186 | "description":"Real Time Music Mood Detection parameters", 187 | "collapsed": true, 188 | "Use RTMMD": { 189 | "type": "Boolean", 190 | "description": "Checked, will use RTMMD: 191 | Real Time Music Mood Detection", 192 | "default": false 193 | }, 194 | "Show Screen": { 195 | "type": "Boolean", 196 | "description": "Show Emotion Color Map Screen", 197 | "default": true 198 | }, 199 | "Verbose": { 200 | "type": "Boolean", 201 | "description": "Show verbose informations", 202 | "default": false 203 | }, 204 | "Script file": { 205 | "type": "File", 206 | "description": "OSC Script file name", 207 | "readOnly": false, 208 | "default" : "OSCRTMMD.js" 209 | } 210 | } 211 | }, 212 | 213 | "values": { 214 | 215 | "beat":{ 216 | 217 | "type":"Boolean", 218 | "description":"Value true of false at each beat.", 219 | "readOnly":true, 220 | "default":false 221 | } 222 | }, 223 | 224 | "scripts": [ 225 | "WLEDAudioSync.js" 226 | ], 227 | 228 | "commands": { 229 | 230 | "Snapshot": 231 | { 232 | "menu":"Replay", 233 | "callback":"runReplay", 234 | "parameters":{ 235 | "File name":{ 236 | "type":"File", 237 | "description": "Select audio data file to replay" 238 | }, 239 | "Duration": { 240 | "type": "Integer", 241 | "description": "How many time for replay (ms) max 1500", 242 | "readOnly": false, 243 | "min": 1, 244 | "max": 1500 245 | } 246 | } 247 | }, 248 | "WLED": 249 | { 250 | "menu":"FFT", 251 | "callback":"createWLEDFFT", 252 | "parameters":{ 253 | "Old Style":{ 254 | "type":"Boolean", 255 | "description": "Select old style FFT, otherwise new one", 256 | "default": false 257 | } 258 | } 259 | }, 260 | "Custom": 261 | { 262 | "menu":"FFT", 263 | "callback":"createFFT", 264 | "parameters":{ 265 | "Size": { 266 | "type": "Float", 267 | "description": "Select FFT size", 268 | "readOnly": false, 269 | "min": 0.01, 270 | "max": 1 271 | } 272 | } 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /multicast.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem this is the cmd file for multicast 3 | Rem need to be adapted depend on the running OS, this one is for Win 4 | Rem will receive these parameters on entry " --ip " + myIP + " --group " + multicastIP + " --port " + uDPPort 5 | Rem which will give " --ip 127.0.0.1 --group 239.0.0.1 --port 19899" for example 6 | 7 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncMCast\" GOTO :folder 8 | 9 | %USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncMCast-Windows.exe %1 %2 %3 %4 %5 %6 10 | 11 | GOTO :end 12 | 13 | :folder 14 | 15 | %USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncMCast\WLEDAudioSyncMCast-Windows.exe %1 %2 %3 %4 %5 %6 16 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncMCast-Windows.exe " del "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncMCast-Windows.exe" 17 | 18 | GOTO :end 19 | 20 | :end 21 | 22 | exit -------------------------------------------------------------------------------- /rtmgc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem this is the cmd file for WrtmgcSRV 3 | Rem need to be adapted depend on the running OS, this one is for Win 4 | Rem 3 optionals params: 1 for server PORT, 2 for OSC server ip address, 3 for OSC server port 5 | 6 | if "%1"=="kill" GOTO :kill 7 | 8 | set SRVPORT=%1 9 | set OSCADDR=%2 10 | set OSCPORT=%3 11 | 12 | set NODE_ENV=production 13 | start "Node JS server for RTMGC" /MIN /D "%USERPROFILE%\Documents\Chataigne\xtra\" WrtmgcSRV-win.exe /B /I 14 | 15 | IF "%~1" == "" set SRVPORT=8000 16 | start chrome "https://localhost:%SRVPORT%/WLEDAudioSyncRTMGC/" 17 | 18 | GOTO end 19 | 20 | :kill 21 | 22 | taskkill /F /FI "WINDOWTITLE eq Node JS server for RTMGC" 23 | 24 | :end 25 | exit 26 | -------------------------------------------------------------------------------- /rtmmd.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem this is the cmd file for RTMMD 3 | Rem need to be adapted depend on the running OS, this one is for Win 4 | Rem will receive these parameters on entry " "+showScreen+" " + verbose or 'kill' 5 | Rem which will give " Y Y" for example 6 | 7 | if "%1"=="kill" GOTO :kill 8 | 9 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTMood\" GOTO :folder 10 | 11 | start "WLEDAudioSyncRTMood from Chataigne" /HIGH /D "%USERPROFILE%\Documents\Chataigne\xtra\" WLEDAudioSyncRTMood-Windows.exe -sc %1 -v %2 12 | 13 | GOTO :end 14 | 15 | :folder 16 | 17 | start "WLEDAudioSyncRTMood from Chataigne" /HIGH /D "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTMood\" WLEDAudioSyncRTMood-Windows.exe -sc %1 -v %2 18 | if exist "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTMood-Windows.exe" del "%USERPROFILE%\Documents\Chataigne\xtra\WLEDAudioSyncRTMood-Windows.exe" 19 | 20 | GOTO :end 21 | 22 | :kill 23 | 24 | taskkill /F /FI "WINDOWTITLE eq WLEDAudioSyncRTMood from Chataigne" 25 | 26 | :end 27 | 28 | exit --------------------------------------------------------------------------------