Community Forums Archive

Go Back

Subject:Auto Markers at fixed intervals
Posted by: WalkCycle
Date:1/13/2015 4:56:52 PM

I am not very familiar with sound forge scripting api.
I would like to create a script which would auto generate markers at a set time interval across the sound file. (In samples).
Also, all the markers should ideally be snapping to zero crossing points - even though it would offset a little from the initial time interval set.

Not sure if this is possible. Any advices on how I could achieve this?


Message last edited on1/13/2015 4:57:34 PM byWalkCycle.
Subject:RE: Auto Markers at fixed intervals
Reply by: CharlesK
Date:1/14/2015 12:10:50 AM

This is based on the Add Markers script that comes with SF11. I haven't tested it on any other version. Set the zero crossing slope in Preferences -> Editing before running the script.

1. Run Sound Forge's script editor (View -> Script editor).

2. Copy and paste the code below (excluding the Code Block) into the script editor window.

3. Save the file as Add Markers At Zero Points.cs.

4. Change the interval. Save, then run the script. You can remove all the added markers by clicking Sound Forge's undo button.

5. Once the script works, save it and close the script editor. You can add a button on the toolbar to run this script without running the script editor.

/* =======================================================================================================
* Script Name: Add Markers At Zero Points
* Description: This script will add markers at fixed intervals throughout
* the length of the open file, snapping to the next zero point.
* Initial State: Run with one file open and (optionally) the Regions List visible.
* (Menu: View > Regions List)
* Parameters (Args):
* Step - the interval at which to set markers - DEFAULT: one marker every 10 seconds
* Prefix - the first part of the marker name - DEFAULT: no prefix
* Suffix - the last part of the marker name - DEFAULT: no suffix
* Output: None
* ==================================================================================================== */

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

//Run with one file open and the Region Lists visible (Menu: View, Regions List)
//Sets markers at set intervals, creating names in this format: prefix+time+suffix
//NOTE: Look for MODIFY HERE to quickly update the Script Args with your own preferences
//TIP: Uses an undo wrapper, so that you can undo all markers in one step

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

//start MODIFY HERE --------------------------------------
double step = GETARG("Step", 10); //change from every 10 seconds to something else
string szPre = GETARG("Prefix", ""); //first part of the marker name. Type "" to leave blank
string szPost = GETARG("Suffix", ""); //last part of the marker name. Type "" to leave blank

// GETARG is a function that defines the default script settings. You can use the Script Args field to over-ride
// the values within GETARG().
// Example: To over-ride GETARG(Key, valueA), type Key=valueB in the Script Args field.
// Use an ampersand (&) to separate different Script Args: KeyOne=valueB&KeyTwo=valueC

//sample Script Args: Step=4

//end MODIFY HERE ----------------------------------------

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

Int64 ccLength = file.Length;
Int64 ccStep = file.SecondsToPosition(step);
if (ccLength < ccStep)
return "File is shorter than marker spacing - no markers created.";

// create an undo wrapper, so we don't end up with an undo for every marker that we create...
string szUndo = String.Format("Create Markers every {0:g} seconds", step);
int idUndo = file.BeginUndo(szUndo);
// Position the cursor at the beginning.
app.ActiveWindow.Cursor = 0;
for (Int64 ccPos = ccStep; ccPos < ccLength; ccPos += ccStep)
// Position cursor first.
wnd.Cursor = ccPos;
// Snap to next zero crossing.
// This honors the 'Snap to zero crossing-slope' setting in Preferences -> Editing
// Add marker.
SfAudioMarker mk = new SfAudioMarker(app.ActiveWindow.Cursor);
// Name the marker.
string name = String.Format("{0} {1:###.##} {2}", szPre, file.PositionToSeconds(ccPos), szPost);
mk.Name = name.Trim();
// Return cursor to beginning of file.
// close the undo wrapper, and tell it to keep the changes.
file.EndUndo(idUndo, false);

return null;

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
string szMessage = Begin(app);
app.SetStatusText((szMessage != null) ? szMessage : String.Format("Script '{0}' is done.", Script.Name));
public static IScriptableApp ForgeApp = null;
public static void Do(string cmd) { ForgeApp.DoMenuAndWait(cmd,false); }
public static void Do(string cmd, bool fUseLastPreset) { ForgeApp.DoMenuAndWait(cmd,fUseLastPreset); }
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)); }
public static string GETARG(string k, string d) { string val = Script.Args.ValueOf(k); if (val == null || val.Length == 0) val = d; return val; }
public static int GETARG(string k, int d) { string s = Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d; else return Script.Args.AsInt(k); }
public static bool GETARG(string k, bool d) { string s = Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d; else return Script.Args.AsBool(k); }
public static double GETARG(string k, double d) {
string s = Script.Args.ValueOf(k);
if (s == null || s.Length == 0)
return d;
try { d = double.Parse(s); } catch {}
return d;
} //EntryPoint

Message last edited on1/14/2015 12:04:50 PM byCharlesK.

Go Back