FMOD Automation | .JS Scripts

Disclaimer, the artwork for this posts thumbnail was generated by AI. If it infringes with anyone’s work, please let me know and I will remove it.

Over the last 3 years using FMOD I’ve always looked for ways to refine and improve my workflow. A part of how I was able to achieve this was creating custom automation scripts for various common tasks. Below I have listed a few of these so that anyone reading may improve their workflows similarly.

To install scripts to FMOD navigate to “C:\Users\%USERNAME%\AppData\Local\FMOD Studio\Scripts“. You can either download my full bundle, or create your own “[NAME].js” script in that folder, then paste one of the below examples.

Add Pitch Randomization to Selected Instruments

Handy script to quickly add ~1.5st of modulation to any instrument in an FMOD event. Saves a lot of time over the course of a project.

studio.menu.addMenuItem({ name: "Add Pitch Randomization to Selected Instruments",keySequence: "Ctrl+Alt+P", 
execute: function addPitchRandToSelected() {
    const pitchModAmt = 3;                                                                              //defining the amount of pitch modulation (USER SHOULD MODIFY THIS FOR PURPOSE)
    var selectedObjects = studio.window.editorSelection();                                              //getting all selected instruments
    for (var i = 0; i < selectedObjects.length; i++) {                                                  //itteration through all instruments
        AddRandomPitchMod(selectedObjects[i], pitchModAmt);                                             //adding pitch modulation with defined amount
    }
}});

function AddRandomPitchMod(selectedObject, pitch) {
    if (selectedObject.modulators != "undefined") {                                                     //checking that instruments do not have an existing modulator
        var randMod = selectedObject.addModulator("RandomizerModulator", "pitch")                       //adding pitch modulator to instrument
        randMod.amount = pitch;
        console.log("Pitch rand added to " + selectedObject);
    }
}

Export Events & Mixer Groups to CSV

More of an analysis tool. Exports the names, id’s and volume levels all events and mixer groups to be quickly viewed in a CSV.

studio.menu.addMenuItem({ name: "Export Events, Mixer Groups to CSV", execute: function exportEventsMixerGroupsToCSV() {
    const filePath = studio.project.filePath + "_EventMixerGroupTable.csv";                                                 //path to CSV file.
    const events = studio.project.model.Event.findInstances();                                                              //adds all events to array.
    const mixerGroups = studio.project.model.MixerGroup.findInstances();                                                    //adds all mixer groups to array.

    var file = studio.system.getFile(filePath);                                                                             //get path to CSV, creates new if doesn't exist.
    var dataLength;

    if(file.open(studio.system.openMode.WriteOnly)){                                                                        //sets csv to write only if exists, returns true if succeeded.
        console.log("File Opened")

        file.writeText("Event Name,Event ID,Event Vol,");                                                                   //setting up csv headings
        file.writeText("MixerGroup Name,MixerGroup ID,MixerGroup Vol,\n");

        if(events.length > mixerGroups.length){                                                                             //checks for longest dataset
            dataLength = events.length;
        }
        else{
            dataLength = mixerGroups.length;
        }

        for (var i = 0; i < dataLength; i++) {                                                                              //for loop for length of dataset
            try{
                file.writeText(events[i].name + "," + events[i].id + "," + events[i].masterTrack.mixerGroup.volume + ",");  //writes event data to csv
            }
            catch(e){
                file.writeText(" , , ,");                                                                                   //adds empty rows in case mixer group data exceeds event data 
                console.log("No more Event data")
            }
            try{
                file.writeText(mixerGroups[i].name + "," + mixerGroups[i].id + "," + mixerGroups[i].volume + ",\n");        //write mixergorup data to csv
            }
            catch(e){
                file.writeText("\n");                                                                                       //adds newline in event data exceeds mixergroup data
                console.log("No more MixerGroup data")
            }          
        }
        file.close();                                                                                                       //saving csv
        console.log("File saved")
    }
    else{
        console.log("File Failed to Open")
    }
    
}});

Normalize All Events to 0dB

Helpful script to quickly normalize all events to 0dB. Script increases the volume of every event equal to the amount below 0dB the loudest event is (If the loudest event is at or above 0dB nothing will happen). Useful for when you are mixing many events and the overall volume level drops as a result.

studio.menu.addMenuItem({ name: "Normalize All Events to 0dB", execute: function normalizeAllEvents() {
    const events = studio.project.model.Event.findInstances();                                          //Find all events, add to array.
    const eventVolumes = [];                                                                            //Create empty array for Volumes.

    for (var i = 0; i < events.length; i++) {                                                           //For each event in project, add volume to volumes array.
        eventVolumes.push(events[i].masterTrack.mixerGroup.volume);
    }

    var maxVolEvent = indexOfMaximumValue(eventVolumes);                                                //Find the array index of the highest volume event.
    
    var volumeIncreaseAmount = difference(events[maxVolEvent].masterTrack.mixerGroup.volume, 0);        //Find difference between max volume event and 0db.

    for (var i = 0; i < events.length; i++) {                                                           //For each event in project, increment volume.
        events[i].masterTrack.mixerGroup.volume += volumeIncreaseAmount;
    }
    alert("Normalized");
    }
});

function difference(num1, num2) {                                                                       //Function to calculate difference between two numbers.
    return Math.abs(num1 - num2);
}

function indexOfMaximumValue(my_array) {                                                                //Function to find the index of highest value item in array.
    if (my_array.length === 0) {
        return -1;
    }
    else{
      var maximumValue = my_array[0];
      var maxIndex = 0;
 
      for (var i = 1; i < my_array.length; i++) {
          if (my_array[i] > maximumValue) {
              maxIndex = i;
              maximumValue = my_array[i];
          }
      }
      return maxIndex;
    }
}

Assign Unassigned Events to Master Bank

Super simple script, quickly assigns all unassigned events tot he master bank. Useful for when you are first starting off a project and want to quickly get sounds into the game for implementation and prototyping.

studio.menu.addMenuItem({ name: "Assign Unassigned Events to Master Bank", execute: function assignEventsToMasterBank() {
    const events = studio.project.model.Event.findInstances();                                                                  // Find all events in the project.

    for (var i = 0; i < events.length; i++) {                                                                                   // Loop through each event.
        if (events[i].banks.length == 0) {                                                                                      // Check if the event is not assigned to a bank.
            events[i].relationships.banks.add(GetMasterBank());                                                                 // Assign the event to the Master bank.
        }
    }
    alert("All unassigned events have been assigned to the Master bank");
}});

function GetMasterBank() {                                                                                                      //Fucntion to get a reference to the master bank
    var banks = studio.project.model.Bank.findInstances();
    var masterBank = null;
    for (var i = 0; i < banks.length; i++) {
        if (banks[i].name == 'Master') {
            masterBank = banks[i];
            return masterBank;
        }
    }
}