header={ "recipe_version": "1.1834", "title": "Custom Audio Normalisation", "description": "Analyse and fix audio levels with custom settings", "tags": "default", "chef": "BeatRig", "instructions": "", "type": "default", "os": "windows,macOS", "palette": "Clean Slate", "spice": "BQ==:G+Hy36kJcnQQYYavb/JV2Il6eCYr6h4hRJHCF9rRbhX5BcazL6cuTgUMdz0xA50VWA5PmmV0Q7aWkiUtNFtbk991l+t0e8IBXMReMIT1GNjnZZDv7n2YRAo0xcSQbY0ixjG6LLH4wGKnspKAoA/v69iLn6N2IH0XzIZwTGdHSo4=", "flavour": "AsYL6vNeXefnrw5FVOSthXngFVwGeyQv5BZEbkPNWeFo9ffixWYCzroazhseEjgsQ2jHOJFgeEb2Jiu6DnZJjjOLxwuNLJg4npxiEq5Lw+NTmbOm23vrfAdU5E24DHZYlSAAa0ixT8lCORrhq20Y5G///iKvgh9Fv+EuVW4xdDo=", "time": 1723920732, "core_version": "0.6.4", "magnetron_version": "1.0.317", "functions": "main,onAbout", "uuid": "d1cd1324d3bb4a09be75f76d5971e657", "dependencies": "ffprobe,ffmpeg" }; // ============================================================================ // GLOBAL FILES VAR var files = []; // ============================================================================ // DEFAULTS var settings = { // "AdjustTargetType" : "Loudness", "AdjustTargetLevel" : -23.0, "AdjustTargetLevel_scale" : 'LUFS', // loudness settings "relativeGate" : true, "relativeGate_level" : -10.0, "dialogGate" : false, // limiter "peakLimit" : true, "peakLimit_type" : "TruePeak", "peakLimit_level" : -1.0, "lraLimit" : false, "lraLimit_level" : 18.0, // export path & name "export" : true, "exportMode" : "always", "exportRef_select" : "individual", "exportRef_reffile" : "", "tolerance" : true, "tolerance_val" : 0.5, "customFolder" : false, "customFolder_path" : "", "subFolder" : true, "subFolder_val" : "export", "nametag" : false, "nametag_val" : "-R128", //validate "validate" : true, }; // ============================================================================ // ALLOWED FILE TYPES var fileTypes = [ 'wav', 'aif', 'aiff', ]; // ============================================================================ function main() { // ----------------------------- // START THE MACHINE setProgress(0); // ----------------------------- // GET ALL FILES FROM THE APP files = getFiles(); // CHECK IF THERE ARE FILES FOR THE DIALOG var fileCount = 0; // a list containing all valid files for the reference combobox var fileList = []; // CHECK IF FFMPEG & FFPROBE ARE AVAILABLE FOR TRUE PEAK LIMITING settings = loadSettings(settings); // CHECK IF FFMPEG & FFPROBE ARE AVAILABLE FOR TRUE PEAK LIMITING settings.ffmpeg = !checkDependencies("ffprobe,ffmpeg"); // CHECK IF FFMPEG HAS SOX RESAMPLER BUILT IN // WILL BE TESTET THE FIRST TIME NEEDED settings.sox = "NOTDEFINED"; // loop all files for (var i=0; i < files.length; i++) { // CHECK IF FILE CAN BE CHECKED var path = getPathInfo(files[i]['path']); // if(files[i]['done']){ files[i]['skip'] = 1; } // else if(path.isfile && fileTypes.indexOf( toLowerCase(path.ext) ) != -1) { fProp(i, 'file_icon', 'Square'); fProp(i, 'file_icon_color', 'FFdddddd'); fProp(i, 'file_status'); // REMOVE fProp(i, 'file_tooltip'); // REMOVE files[i]['skip'] = 0; files[i]['wrn'] = 0; // DO NOT BLOAT THE SELECTBOX // IF YOU HAVE MORE FILES, JUST ADD THE REF FILE FIRST if(i<50){ fileList.push( i + ') ' + path.filename ); } // file can be checked fileCount++; } // IS NOT CHECKABLE else { fProp(i, 'file_icon', 'ExclamationCircle'); fProp(i, 'file_icon_color', 'FFFF0000'); fProp(i, 'file_status', 'U Can’t Check This'); fProp(i, 'file_tooltip', "Please add a WAV or AIFF file"); files[i]['skip'] = 1; files[i]['err'] = 1; files[i]['wrn'] = 0; } } // ------------------------------------ // IF NO FILES, WARN AND STOP if( fileCount == 0){ abort("Add some files first!"); } // ======================================================================== // DIALOG // ======================================================================== settings.customFolder_path = (settings.customFolder_path == "" ? folders.home : settings.customFolder_path ); settings.exportRef_reffile = fileList.join(','); // PREPARE DIALOG FIELDS var fields = dialogJSON(settings); var r = dialog(fields); if(r.cancel) { setFiles(files); break; }; // REPLACE VALUES ONE-BY-ONE for (var j = 0; j < getObjectSize(r); j++) { settings[getObjectKey(r, j)] = getObjectValue(r, j); } // STORE SETTINGS FOR THE NEXT TIME storeSettings(settings); // ======================================================================== // ANALYSE // ======================================================================== var maxLUFS = -99.; var maxPEAK = -99.; for (i=0;i settings.peakLimit_level ) { files[i]["enableLimiter"] = true; } if( settings.peakLimit_type == 'Peak' && levels.Peak + files[i]["adjust"] > settings.peakLimit_level ) { files[i]["enableLimiter"] = true; } } else{ // PREVENT FROM CLIPPING WHEN SAMPLE PEAK EXCEEDS 0dB if(levels.Peak + files[i]["adjust"] > 0.){ files[i]["adjust"] = 0 - levels.Peak; files[i]["clipPrevent"] = true; } } // ------------------------------------ // CHECK IF TOLERANCE IS ENABLED AND VALUE IS WITHIN TOLERANCE files[i]["enableTolerance"] = false; if( setting.tolerance && files[i]["adjust"] < settings.tolerance_val && files[i]["adjust"] < 0-settings.tolerance_val){ files[i]["enableTolerance"] = true; } // ------------------------------------ // KEEP TRACK OF MAX VALUES maxLUFS = (levels.LUFS > maxLUFS ? levels.LUFS : maxLUFS ); maxPEAK = (levels.Peak > maxPEAK ? levels.Peak : maxPEAK ); maxTP = (levels.TruePeak > maxTP ? levels.TruePeak : maxTP ); maxPPM = (levels.PPM_Max > maxPPM ? levels.PPM_Max : maxPPM ); // maxAdjust = (files[i]["adjust"] < maxAdjust ? files[i]["adjust"] : maxAdjust ); // maxClipPrevent = files[i]["clipPrevent"]; // if( files[i]["adjust"] < maxAdjust ){ // maxAdjust = files[i]["adjust"]; // maxClipPrevent = files[i]["clipPrevent"]; // } // ------------------------------------ msg.push('INPUT:'); msg.push('- Loudness I : '+toFixed(files[i]["LUFS"], 1)+ 'LUFS'); msg.push('- Sample Peak : '+toFixed(files[i]["Peak"], 1)+ 'dB'); msg.push('- True Peak : '+toFixed(files[i]["TruePeak"], 1)+ 'dBTP'); msg.push('- PPM : '+toFixed(files[i]["PPM"], 1)+ 'dB'); msg.push('\n'); // ------------------------------------ // SET OUTPUT PATH if(settings.customFolder == 1){ files[i]["output_path"] = settings.customFolder_path; } else{ files[i]["output_path"] = path.folder; } // output path should always have an traling slash files[i]["output_path"] = ( files[i]["output_path"].charAt(myString.length - 1) == gvar.pss ? files[i]["output_path"] : files[i]["output_path"]+gvar.pss ); // CHECK IF OUTPUT PATH IS VALID if( !fileExists(files[i]["output_path"]) ){ files[i]["skip"] = 1; err++; msg.push('Could not export to this path'); } // ------------------------------------ // subFolder_val if(settings.subFolder == 1){ var p = settings.subFolder_val; var l = settings.subFolder_val.length; files[i]["output_path"] = files[i]["output_path"] +( p.charAt( 0) == gvar.pss ? p.substr(1, l - 1) : p ) +( p.charAt( l-1) == gvar.pss ? '' : gvar.pss ); } // ------------------------------------ // OUTPUT FILE NAME // ALSO INCLUDE nametag_val IF SET if(settings.nametag == 1){ files[i]["output_name"] = path.basename+settings.nametag_val+'.'+path.ext; } else{ files[i]["output_name"] = path.filename; } // ------------------------------------ files[i]["output_file"] = files[i]["output_path"]+files[i]["output_name"]; // ------------------------------------ // CHECK IF SOURCE AND DEST FILE ARE THE SAME PATH if( files[i]['path'] == files[i]["output_file"] ){ if(settings.export){ err++; msg.push('Cannot overwrite source file'); } files[i]["skip"] = 1; } // CHECK IF FILE ALLREADY EXISTS if( fileExists(files[i]["output_file"]) ){ if(settings.export){ err++; msg.push('Could not export: file exists'); } files[i]["skip"] = 1; } // ------------------------------------ // UPDATE THE FILE LIST files[i]["err"] = (err > 0 ? true : false); // SET UI MESSAGE & CURRENT FILE ICON fProp(i, 'file_icon', 'Square'); fProp(i, 'file_icon_color', 'FFdddddd'); fProp(i, 'file_status', '.'); fProp(i, 'file_tooltip', msg.join('\n')); // ------------------------------------ } // ======================================================================== // PROCESSING // ======================================================================== // GROUP MODE REFERENCE FILE // USE THE ADJUSTMENT FROM 1 SPECIFIC FILE FOR ALL if(settings.exportRef_select == 'reference'){ var id = parseInt(settings.exportRef_reffile.split(") ")[0]); var refAdjust = files[id].adjust; var refClipPrecent = files[id].clipPrevent; } if(settings.export){ for (i=0;i> PROCESS USING FFMPEG LOUDNORM FOR TRUE PEAK OR LRA LIMITING else if( settings.AdjustTargetType == 'Loudness' && settings.ffmpeg && (files[i]["enableLimiter"] && settings.peakLimit_type == 'TruePeak') ){ // WE NEED THE SAMPLE RATE BECAUSE IT WILL UPSAMPLE THE FILE TO 192 FOR THE TRUE PEAK // FILTER AND WE NEE TO BRING IT BACK TO THE ORIGINAL SAMPLE RATE var ffprobe = cmd("ffprobe", [ '-v','error', '-select_streams','a:0', '-show_entries','format=size :stream=sample_rate,bits_per_sample,channels', '-of','default=noprint_wrappers=1', '-i',files[i]['path'] ]); var sample_rate = parseInt (searchRegEx(ffprobe, "(?:sample_rate=)(.*?)(?=[\n\r])", "o", 1)[0]); var channels = parseInt (searchRegEx(ffprobe, "(?:channels=)(.*?)(?=[\n\r])", "o", 1)[0]); // var bits_per_sample = parseInt (searchRegEx(ffprobe, "(?:bits_per_sample=)(.*?)(?=[\n\r])", "o", 1)[0]); // PREPARE THE FFMPEG CALL var specs = [ 'linear=true', 'I='+settings.AdjustTargetLevel, 'measured_I='+(Math.round(files[i]["LUFS"]*1000)/1000), // 'measured_thresh=-39.20', // NEED TO HAVE A LOOK AT THIS // 'offset=0.58', // NEED TO HAVE A LOOK AT THIS 'print_format=summary', ]; // ENABLE THE PEAK LIMITER if(settings.peakLimit){ concatArray(specs,[ 'TP='+(Math.round((settings.peakLimit_level-0.1)*1000)/1000), 'measured_TP='+(Math.round(files[i]["TruePeak"]*1000)/1000) ]); } // LRA LIMITER, NOT TESTED ENOUGH FOR NOW //if(settings.lraLimit){ // concatArray(specs,[ // 'LRA='+settings.lraLimit_level, // 'measured_LRA='+(Math.round(files[i]["LRA"]*100)/100) // ]); // } specs.push('print_format=summary'); specs = specs.join(':'); // TEST IF FFMPEG HAS SOX BUILT IN if(settings.ffmpeg && settings.sox == "NOTDEFINED"){ var ffmpeg = cmd("ffmpeg", ['-version']); settings.sox = containsString(ffmpeg, '--enable-libsoxr') ? true : false; } // IF SOX RESAMPLER IS PRESENT if(settings.sox){ var ffmpeg = cmd("ffmpeg", [ '-i',files[i]['path'], '-filter:a','loudnorm='+specs+',aresample=resampler=soxr:out_sample_rate='+sample_rate+':precision=28', '-ac',channels, files[i]["output_file"], ]); } // NO SOX IS PRESENT, FALLBACK TO DEFAULT else{ var ffmpeg = cmd("ffmpeg", [ '-i',files[i]['path'], '-filter:a','loudnorm='+specs, '-ar',sample_rate, files[i]["output_file"], ]); } } // ELSE >> PROCESSING USING BUILT IN PROCESSING WITH OR WITHOUT SAMPLE PEAK LIMITER else{ var properties = { "AdjustLevel_NoLimit" : files[i]["adjust"], "NeedLimiting" : files[i]["enableLimiter"], "LimitThresholddB" : settings.peakLimit_level, }; var rtn = levelFileProcess( files[i]['path'], files[i]["output_file"], properties ); } // ------------------------------------ msg.push('\nADJUST:'); msg.push('- Adjust : '+(files[i]["adjust"] > 0 ? '+' : '')+toFixed(files[i]["adjust"], 1)+ 'dB'); if( files[i]["clipPrevent"] ){ msg.push('- COULD NOT ADJUST WITHOUT CLIPPING'); } if(!settings.sox) { msg.push( '- Your FFMPEG does not contain the Sox Resampler'); } msg.push('\n'); // ------------------------------------ files[i]['done'] = 1; // ------------------------------------ // SET UI MESSAGE & CURRENT FILE ICON fProp(i, 'file_icon', 'Square'); fProp(i, 'file_icon_color', 'FFdddddd'); fProp(i, 'file_status', '..'); fProp(i, 'file_tooltip', files[i]["file_tooltip"]+msg.join('\n')); setFileIcon(files[i]['path'], files[i]['index'], "Square"); setFileIconColor(files[i]['path'], files[i]['index'], "FFdddddd"); } } // ======================================================================== // ======================================================================== // VALIDATE - AND FINAL RESULTS // ======================================================================== // ======================================================================== if( settings.validate ) { for (i=0;i (setting.tolerance ? settings.tolerance_val : 0.1) ) { err++; msg.push('Could not fix the file, loudness of processed file is not in range'); } } // VALIDATE SAMPLE PEAK LIMITER if(settings.peakLimit){ // SAMPLE PEAK if(settings.peakLimit_type == "Peak" && levels.Peak > settings.peakLimit_level + 0.1){ err++; msg.push('SamplePeak level exceeds limiter value'); } // TRUE PEAK if(settings.peakLimit_type == "TruePeak" && levels.TruePeak > settings.peakLimit_level + 0.1){ err++; msg.push('TruePeak level exceeds limiter value'); } } // ------------------------------------ else{ err++; msg.push('\nOUTPUT FILE WAS NOT CREATED'); } // ------------------------------------ } // ------------------------------------ // UPDATE THE FILE LIST files[i]["err"] = (files[i]["err"] + err > 0 ? true : false); files[i]["wrn"] = (files[i]["wrn"] + wrn > 0 ? true : false); fProp(i, 'file_tooltip', files[i]["file_tooltip"]+msg.join('\n')); // ------------------------------------ // IF THERE ARE ERRORS if(files[i]["err"]) { fProp(i, 'file_icon', 'ExclamationTriangle'); fProp(i, 'file_icon_color', 'FFFF0000'); fProp(i, 'file_status', 'Failed'); } else if(files[i]["wrn"]) { fProp(i, 'file_icon', 'Square'); fProp(i, 'file_icon_color', 'FFFF8800'); fProp(i, 'file_status', 'Finished with warnings'); } else { fProp(i, 'file_icon', 'CheckSquare'); fProp(i, 'file_icon_color', 'FF00aa00'); fProp(i, 'file_status', 'Done'); } } } setFiles(files); // DONE WITH IT ALL setMainMessage('Done'); } // ============================================================================= // HELPER FUNCTION FOR UPDATING THE FILELIST AND CHANGING THE FILES ARRAY AT THE // SAME TIME (THE FILE SHOULD BE PASSED AS OBJECT AND IS TREATED AS REFRENCE) function fProp(i, key, data) { var path = files[i]['path']; var index = files[i]['index']; if(typeof(data) === 'undefined'){ removeFileProperty(path, index, key); // removeProperty(file, key); } else{ setFileProperty(path, index, key, data); files[i][key] = data; // setObjectKey(file, getObjectKeyIndex(file, key), key); // setObjectValue(file, getObjectKeyIndex(file, key), data); } } // ============================================================================= // THE DIALOG FIELDS AND LAYOUT function dialogJSON(settings) { // CHECK OF ER EEN WARNING MOET KOMEN var warning = false; if(!settings.ffmpeg){ warning = "FFmpeg/FFprobe not installed. TruePeak Limiter is disabled."; } var spacer_size = 2; // return { // -------------------------------- "warning" : { "type" : "text", "label" : warning, "just" : "l", "visible" : (warning != false ? true : false), "bounds" : { "x": 0, "y" : 0, "w" : 600, }, }, // -------------------------------- "heading1" : { "type" : "text", "label" : "// ANALYSE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", "just" : "l", "bounds" : { "x": 0, "w" : 600, "h" : 25 }, }, // -------------------------------- "AdjustTargetLevel_label" : { "type" : "text", "label" : "target", "just" : "l", "bounds" : { "x": 20, "w" : 100, }, }, "AdjustTargetType" : { "type" : "combobox", "default" : settings.AdjustTargetType, "items" : "Loudness,TruePeak,Peak,PPM", "bounds" : { "y" : -1, "x": 180 , "w" : 120, }, "returns" : 0, }, "AdjustTargetLevel": { "type": "slider", "range" : { "min": -48, "max" : 12, "interval" : 1, "decimals" : 0 }, "bounds" : { "y" : -1, "x" : 305, "w" : 100, }, "value": settings.AdjustTargetLevel }, "AdjustTargetLevel_scale" : { "type" : "text", "label" : settings.AdjustTargetLevel_scale, "just" : "l", "bounds" : { "y" : -1, "x": 410, "w" : 200, }, }, // -------------------------------- "relativeGate_label" : { "type" : "text", "label" : "relative gate", "just" : "l", "bounds" : { "x": 20, "w" : 150, }, "enabled": true, }, "relativeGate": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "enabled": true, "toggle" : settings.relativeGate, }, "relativeGate_level": { "type": "slider", "range" : { "min": -48, "max" : 0, "interval" : 1, "decimals" : 0 }, "bounds" : { "y" : -1, "x" : 180, "w" : 100, }, "value": settings.relativeGate_level, "enabled": true, }, // -------------------------------- "dialogGate_label" : { "type" : "text", "label" : "dialog gate", "just" : "l", "bounds" : { "x": 20, "w" : 100, }, "enabled": true, }, "dialogGate": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "value" : settings.dialogGate, "enabled": true, "toggle" : false, }, // -------------------------------- "spacer1": { "type": "text", "label": "","just": "c", "bounds": { "x": 20, "w": 550, "h": spacer_size }, }, // -------------------------------- "heading2" : { "type" : "text", "label" : "// EXPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", "just" : "l", "bounds" : { "x": 0, "w" : 600, "h" : 25 }, }, // -------------------------------- "export_label" : { "type" : "text", "label" : "export", "just" : "l", "bounds" : { "x": 20, "w" : 100, }, }, "export": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.export }, "exportMode" : { "type" : "combobox", "default" : settings.exportMode, "items" : "always,modified", "bounds" : { "y" : -1, "x": 180, "w" : 120, }, "returns" : 0, }, // -------------------------------- "exportRef_label" : { "type" : "text", "label" : "mode", "just" : "l", "bounds" : { "x": 20, "w" : 100, }, }, "exportRef_select" : { "type" : "combobox", "default" : settings.exportRef_select, "items" : "individual,loudest,reference", "bounds" : { "y" : -1, "x": 180, "w" : 120, }, "returns" : 0, }, "exportRef_reffile" : { "type" : "combobox", "default" : 'LUFS', "items" : settings.exportRef_reffile, "bounds" : { "y" : -1, "x": 305, "w" : 290, }, "returns" : 0, "visible" : false }, // -------------------------------- "tolerance_label" : { "type" : "text", "label" : "tolerance", "just" : "l", "bounds" : { "x": 20, "w" : 100, }, }, "tolerance": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.tolerance }, "tolerance_val": { "type": "slider", "visible": true, "range" : { "min": 0, "max" : 6, "interval" : .1, "decimals" : 1 }, "bounds" : { "y" : -1, "x" : 180, "w" : 100, }, "value": settings.tolerance_val }, // -------------------------------- "peakLimit_label" : { "type" : "text", "label" : "peak limit", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "peakLimit": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.peakLimit }, "peakLimit_level": { "type": "slider", "visible": true, "range" : { "min": -99., "max" : 6, "interval" : .1, "decimals" : 1 }, "bounds" : { "y" : -1, "x" : 180, "w" : 100, }, "value": settings.peakLimit_level, }, "peakLimit_type" : { "type" : "combobox", "default" : settings.peakLimit_type, "items" : "Peak,TruePeak", "bounds" : { "y" : -1, "x": 300, "w" : 120, }, "returns" : 0, }, // -------------------------------- /* "lraLimit_label" : { "type" : "text", "label" : "lra limit", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "lraLimit": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.lraLimit }, "lraLimit_level": { "type": "slider", "visible": true, "range" : { "min": 0, "max" : 40, "interval" : 1, "decimals" : 0 }, "bounds" : { "y" : -1, "x" : 180, "w" : 100, }, "value": settings.lraLimit_level, }, } */ // -------------------------------- "spacer3": { "type": "text", "label": "","just": "c", "bounds": { "x": 20, "w": 550, "h": spacer_size }, }, // -------------------------------- "customFolder_label" : { "type" : "text", "label" : "custom folder", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "customFolder": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.customFolder }, "customFolder_path" : { "type" : "fileselect", "path" : settings.customFolder_path, "editable" : false, "dir" : true, "saving" : true, "label" : "empty", "bounds" : { "y": -1, "x": 180, "w" : 420, }, "visible": false, }, // -------------------------------- "subFolder_label" : { "type" : "text", "label" : "sub folder", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "subFolder": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.subFolder }, "subFolder_val": { "type": "texteditor", "bounds" : { "y": -1, "x" : 180, "w" : 350, }, "multiline" : false, "wordwrap" : false, "default" : settings.subFolder_val, "visible": true, }, // -------------------------------- "nametag_val_label" : { "type" : "text", "label" : "name tag", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "nametag": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.nametag }, "nametag_val": { "type": "texteditor", "bounds" : { "y": -1, "x" : 180, "w" : 420, }, "multiline" : false, "wordwrap" : false, "default" : settings.nametag_val, "visible": false, }, // -------------------------------- "spacer4": { "type": "text", "label": "","just": "c", "bounds": { "x": 20, "w": 550, "h": spacer_size }, }, // -------------------------------- "validate_label" : { "type" : "text", "label" : "validate", "just" : "l", "bounds" : { "x": 20, "w" : 160, }, }, "validate": { "type": "togglebox", "bounds" : { "y": -1, "x": 140, "w" : 25, }, "label" : "", "toggle" : settings.validate }, // -------------------------------- "spacer5": { "type": "text", "label": "","just": "c", "bounds": { "x": 20, "w": 550, "h": spacer_size }, }, // -------------------------------- "okay" : { "is_okay": true, "type" : "button", "label" : "ok", "bounds" : { "w" : 160, }, "returns" : 1, }, "cancel" : { "is_cancel": true, "type" : "button", "label" : "cancel", "bounds" : { "y": -1, "x": 180, "w" : 160 }, "returns" : 0, }, // -------------------------------- }; } // ============================================================================ // DIALOG CALLBACK function dialog_callback(props) { // ---------------- // UPDATE SETTINGS if (props["name"] == "exportMode") { settings['exportMode'] = props["text"]; } if (props["name"] == "exportRef_select") { settings['exportRef_select'] = props["text"]; } if (props["name"] == "exportRef_reffile") { settings['exportRef_reffile'] = props["text"]; } if (props["name"] == "peakLimit_type") { settings['peakLimit_type'] = props["text"]; } if (props["name"] == "export") { settings['export'] = props["toggle"]; } if (props["name"] == "customFolder") { settings['customFolder'] = props["toggle"]; } if (props["name"] == "nametag") { settings['nametag'] = props["toggle"]; } if (props["name"] == "subFolder") { settings['subFolder'] = props["toggle"]; } if (props["name"] == "peakLimit") { settings['peakLimit'] = props["toggle"]; } if (props["name"] == "lraLimit") { settings['lraLimit'] = props["toggle"]; } if (props["name"] == "tolerance") { settings['tolerance'] = props["toggle"]; } if (props["name"] == "relativeGate") { settings['relativeGate'] = props["toggle"]; } if (props["name"] == "AdjustTargetType"){ settings['AdjustTargetType'] = props["text"]; if(props["text"] == 'Loudness') { settings['AdjustTargetLevel_scale'] = "LUFS"; } else if(props["text"] == 'TruePeak') { settings['AdjustTargetLevel_scale'] = "dBTP"; } else if(props["text"] == 'Peak') { settings['AdjustTargetLevel_scale'] = "dBFS"; } else if(props["text"] == 'PPM') { settings['AdjustTargetLevel_scale'] = "PPM (0PPM = 0dBFS)"; } } // ---------------- // SHOW/HIDE WHEN EXPORT var exp = settings['export']; var ldn = settings['AdjustTargetType'] == "Loudness" ? 1 : 0; // ---------------- // UPDATE DIALOG var r = dialog({ "tolerance_label" : { "enabled" : exp }, "tolerance" : { "enabled" : exp }, "tolerance_val" : { "enabled" : exp, "visible" : settings['tolerance'] }, "exportMode" : { "enabled" : exp, "default" : settings.exportMode }, "exportMode_label" : { "enabled" : exp, }, "exportRef_label" : { "enabled" : exp, }, "exportRef_select" : { "enabled" : exp, "default" : settings.exportRef_select }, "exportRef_reffile" : { "enabled" : exp, "default" : settings.exportRef_reffile, "visible" : settings.exportRef_select == 'reference' ? 1 : 0 }, "peakLimit_label" : { "enabled" : exp && ldn}, "peakLimit" : { "enabled" : exp && ldn }, "peakLimit_level" : { "enabled" : exp && ldn, "visible" : settings['peakLimit'] }, "peakLimit_type" : { "enabled" : exp && ldn, "visible" : settings['peakLimit'] && settings.ffmpeg, "default" : settings.peakLimit_type }, "lraLimit_label" : { "enabled" : exp && ldn }, "lraLimit" : { "enabled" : exp && ldn }, "lraLimit_level" : { "enabled" : exp && ldn, "visible" : settings['lraLimit'] }, "lraLimit_type" : { "enabled" : exp && ldn, "visible" : settings['lraLimit'] }, "customFolder_label" : { "enabled" : exp }, "customFolder" : { "enabled" : exp }, "customFolder_path" : { "enabled" : exp, "visible" : exp && settings['customFolder'] }, "subFolder_label" : { "enabled" : exp }, "subFolder" : { "enabled" : exp }, "subFolder_val" : { "enabled" : exp, "visible" : exp && settings['subFolder'] }, "nametag_val_label" : { "enabled" : exp }, "nametag" : { "enabled" : exp }, "nametag_val" : { "enabled" : exp, "visible" : exp && settings['nametag'] }, "validate_label" : { "enabled" : exp }, "validate" : { "enabled" : exp }, "relativeGate_label" : { "enabled" : ldn }, "relativeGate" : { "enabled" : ldn } , "relativeGate_level" : { "enabled" : ldn, "visible" : settings['relativeGate'] } , "dialogGate_label" : { "enabled" : ldn }, "dialogGate" : { "enabled" : ldn } , "AdjustTargetLevel_scale" : { "label" : settings['AdjustTargetLevel_scale'] } }); // ---------------- } // ============================================================================= // LEVEL ANALYSE PROGRESS CALLBACK function LevelFileAnalyse_Progress(file, progress) { setProgress( progress * 100 ); } // ============================================================================= // LEVEL PROCESS PROGRESS CALLBACK function LevelFileProcess_Progress(file, progress) { setProgress( progress * 100 ); } // ============================================================================= // FFMPEG CALLBACK function cmd_callback() { setProgress(101); return { "terminate": isCanceled() }; } // ============================================================================= // ON ABOUT, SHOW POPUP WITH BUTTON TO OPEN WEBSITE function onAbout() { var args = { "info": { "type": "texteditor", "bounds" : { "y" : 70, "w" : 400, "h" : 150 }, "visible": true, "multiline" : true, "wordwrap" : true, "default" : header.description+'\n\nMore information on the recipes page on our website.', "enabled" : false }, "showpage" : { "type" : "button", "label" : "show page", "returns" : 1 }, "close" : { "type" : "button", "label" : "close", "returns" : 0 } }; var r = dialog(header.title, "" , "", args); if (r.showpage == 1) launchInBrowser('https://magnetron.app/recipes/uuid/'+header.uuid+'/'); } // ============================================================================= // STORE SETTINGS ON DRIVE function storeSettings(s){ // A FILE WITH DEFAULT VALUES var deffile = folders.content+gvar.pss+'default.txt'; // REMOVE BUTTONS ETC THAT SHOULD NOT BE STORED s = removeProperty(s, 'returns'); s = removeProperty(s, 'okay'); s = removeProperty(s, 'cancel'); s = removeProperty(s, 'exportRef_reffile'); // s = removeProperty(s, 'ffmpeg'); // WRITE THE FILE writeFile(deffile,objectToString(s)); } // ============================================================================= // LOAD DEFAULT VALUES function loadSettings(settings){ // A FILE WITH DEFAULT VALUES var deffile = folders.content+gvar.pss+'default.txt'; // ADD/UPDATE SETTINGS if ( fileExists(deffile) ){ // GET FILE var t = stringToObject( readFile(deffile) ); // REPLACE VALUES ONE-BY-ONE for (var j = 0; j < getObjectSize(t); j++) { settings[getObjectKey(t, j)] = getObjectValue(t, j); } } // RETURN THE VALUES return settings; } // =============================================================================