Volume automation - Sound Forge 18 Pro

Paul-Fegan wrote on 5/24/2025, 7:46 AM

Is it possible to tie automation to a hotkey? I want to be able to select a breath-intake in voiceover audio, then press a key to lower the volume by, say, -8 dB. In REAPER, I can do this via user-defined actions, but I don't see a way to do it in Sound Forge and I'm not familiar with scripting. I have a hotkey tied to Mute, which is great, but I'd love to tie another hotkey to lower the volume, if needs be. Many thanks.

Comments

rraud wrote on 5/24/2025, 10:40 AM

Hi @Paul-Fegan, You can draw a volume envelope, however envelope points cannot be added automatically (like in Vegas). . To initiate the volume envelope plug-in, press the 'V' key. If you wish to save the volume envelope and continue later, save as an Sound Forge Pro Project file <.frg>. To write or overwrite the file, save as in your preferred format.
This volume envelope plug-in will only work in the timeline chainer mode (not 'Fx Favorites')

Paul-Fegan wrote on 5/24/2025, 11:36 AM

Thanks, Rick. I appreciate that's one way of doing it, but drawing envelope points for every breath might slow me down a bit. Since I last posted, I bound a hotkey to the Volume window. Everytime I open it, it remembers the last setting I used (I'm using the same volume drop for every breath), so at least it's just a two-click operation now: hotkey and then RETURN. Could be worse, so it'll do me for now. I was kind of hoping one key could do both... but maybe I just need to stop being lazy. 😄

Thanks a mill for your quick response.

SP. wrote on 5/24/2025, 11:39 AM

@Paul-Fegan This script calls a preset named Reduce Volume -8 dB in the Volume effect and applies it to a selection. If you save this in a text file with the file ending cs to your Sound Forge script folder and rescan the folder you can add a shortcut to this script inside the Customize Keyboard options. Then it's only a single button press instead of hotkey and Return.

For it to work, you need to save a preset with your desired settings and the name mentioned above in the Volume Effect. Of course, you can simply change the name in the script if you want to call it something different.

/* ==========================================================================
 *    Script Name: Reduce Volume -8 dB
 *    Description: This script takes a selection in an open file and applies the Volume effect preset named Reduce Volume -8 dB
 *
 *    Initial State: A file open with a selection
 *
 *    Output: Done with success or failure
 *
 * ========================================================================== */

using System;
using System.IO;
using System.Windows.Forms;
using SoundForge;

//BEHAVIOR: Takes a selection in an open file and applies the Volume effect preset named Reduce Volume -8 dB

public class EntryPoint {
public string Begin(IScriptableApp app) {

   ISfDataWnd wnd = app.ActiveWindow;
   if (null == wnd)
      return "Open a file before running this script.";

   SfAudioSelection asel = wnd.Selection;
   if (asel.ccLength == 0)
   {
      DPF("No selection in the active window - quitting");
      return "Choose a selection before running the script.";
   }

   ISfFileHost file = wnd.File;

   bool fCancel = false;
   int idUndo = file.BeginUndo("Reduce Volume -8 dB");

   file.DoEffect("Volume", "Reduce Volume -8 dB", new SfAudioSelection(wnd.Selection.ccStart, wnd.Selection.ccLength), EffectOptions.EffectOnly);
   
   SfStatus result = file.WaitForDoneOrCancel();
   if (result != SfStatus.Success)
      fCancel = true;   

   file.EndUndo(idUndo, fCancel);
   DPF("Done - {0}", fCancel ? "failed and rewound changes" : "success");
   if(fCancel)
      return "Script canceled.";
   else
      return null;
}

public void FromSoundForge(IScriptableApp app) {
   ForgeApp = app; //execution begins here
   app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
   string msg = Begin(app);
   app.SetStatusText(msg != null ? msg : String.Format("Script '{0}' is done.", Script.Name));
}
public static IScriptableApp ForgeApp = null;
public static void DPF(string sz) { ForgeApp.OutputText(sz); }
public static void DPF(string fmt, object o) { ForgeApp.OutputText(String.Format(fmt,o)); }
public static void DPF(string fmt, object o, object o2) { ForgeApp.OutputText(String.Format(fmt,o,o2)); }
public static void DPF(string fmt, object o, object o2, object o3) { ForgeApp.OutputText(String.Format(fmt,o,o2,o3)); }
} //EntryPoint