Community Forums Archive

Go Back

Subject:Normalize Regions Individually
Posted by: Flea-circus
Date:10/8/2015 11:36:56 PM

I feel that this should be easy, but I can't get it.

I need to go through files, region by region, select the data in each region, and normalize to the last preset.

I've only gotten it to normalize the entire file, over and over again, but not each region separately.

Can anyone help? I can pay if need be.

Thanks!


Subject:RE: Normalize Regions Individually
Reply by: roblesinge
Date:10/9/2015 9:28:33 AM

Can you post the code you have so far?

You'd need to loop through the regions as SfAudioSelection objects and normalize each one individually.

-Rob.

Subject:RE: Normalize Regions Individually
Reply by: Flea-circus
Date:10/9/2015 1:08:44 PM

Thank you so much for responding.
Behold my simpleton ways.
I cobbled this together more-or-less by guessing.
It works, up to the point I described, but doesn't select each region... yet.
Thanks again for considering this.

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

//BEHAVIOR:
//- Normalizes Each Region To Last Preset

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

ISfFileHost file = app.CurrentFile;
if (null == file)
return;

app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));

foreach (SfAudioMarker mk in file.Markers)

{
if (mk.Length <= 0)
continue;

Do("Process.Normalize", true);


app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));

}
}

public static void Do(string cmd) { ForgeApp.DoMenuAndWait(cmd,true); }
public static void Do(string cmd, bool fUseLastPreset) { ForgeApp.DoMenuAndWait(cmd,fUseLastPreset); }

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(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)); }
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); }
} //EntryPoint

Subject:RE: Normalize Regions Individually
Reply by: Flea-circus
Date:10/10/2015 2:30:57 PM

This is my latest version.
It now creates a new file for each region, then normalizes it.
Better, but not what I need.
I feel like I'm closing in on it though.

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

//BEHAVIOR:
//- Normalizes Each Region To Last Preset

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

ISfFileHost file = app.CurrentFile;
if (null == file)
return;

app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));

foreach (SfAudioMarker mk in file.Markers)

{

if (mk.Length <= 0)
continue;

ISfFileHost fileT = file.NewFile(new SfAudioSelection(mk.Start, mk.Length));

if (null == fileT)
break;

Do("Process.Normalize", true);

app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));

}
}

public static void Do(string cmd) { ForgeApp.DoMenuAndWait(cmd,true); }
public static void Do(string cmd, bool fUseLastPreset) { ForgeApp.DoMenuAndWait(cmd,fUseLastPreset); }

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(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)); }
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); }
} //EntryPoint

Subject:RE: Normalize Regions Individually
Reply by: roblesinge
Date:10/11/2015 9:29:41 AM

Try replacing

ISfFileHost fileT = file.NewFile(new SfAudioSelection(mk.Start, mk.Length));


with

ISfAudioSelection asel = new SfAudioSelection(mk.Start, mk.Length);


You'll also need to change or remove the null check of fileT below this line. I haven't tested this but it should do what you're asking.

For reference I pulled this from another script I wrote a while back that allows you to specify a folder of files and then applies the Normalization preset you choose to each file in that folder by region.


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

public class EntryPoint
{
public void Begin(IScriptableApp app)
{
//gets the folder where the files are located.
string strFolder = SfHelpers.ChooseDirectory("Choose the folder where your files are", @"C:\");

//Creates and populates a string array with the filenames of files to be processed.
string[] fileNames;
fileNames = Directory.GetFiles(strFolder, "*.wav");

//Create output directory for processed files.
DirectoryInfo activeDir = new DirectoryInfo(strFolder);
string newPath = System.IO.Path.Combine(activeDir.Parent.FullName.ToString(), "Output");
System.IO.Directory.CreateDirectory(newPath);
DPF(newPath);

//opens a dialog so you can choose the Normalize preset you want to use.
ISfGenericEffect fx = app.FindEffect("Normalize");
ISfGenericPreset normPreset = fx.ChoosePreset(IntPtr.Zero, 0);

//cycle through each file in the folder to be processed.
foreach (string file in fileNames)
{
ISfFileHost toProcess = app.OpenFile(file, false, true);

//cycle through the regions in this file.
foreach (SfAudioMarker mk in toProcess.Markers)
{
SfAudioSelection range = new SfAudioSelection(mk.Start, mk.Length);
toProcess.DoEffect("Normalize", normPreset, range, EffectOptions.EffectOnly | EffectOptions.WaitForDoneOrCancel);
}

string savePath = Path.Combine(newPath, Path.GetFileName(file));

//save the processed file.
toProcess.SaveAs(savePath, toProcess.SaveFormat.Guid, "Default Template", RenderOptions.WaitForDoneOrCancel);

//close file.
toProcess.Close(CloseOptions.SaveChanges);
}
}

public void FromSoundForge(IScriptableApp app)
{
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(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, params object[] args) { ForgeApp.OutputText(String.Format(fmt, args)); }
} //EntryPoint


R.

Subject:RE: Normalize Regions Individually
Reply by: Flea-circus
Date:10/11/2015 10:40:12 PM

Thanks for the advice.

I replaced what you said I should, but it tells me:

The type or namespace name 'ISfAudioSelection' could not be found (are you missing a using directive or an assembly reference?)

Not sure what to do with that.

Subject:RE: Normalize Regions Individually
Reply by: roblesinge
Date:10/12/2015 10:06:16 AM

That's my fault. There's a typo in the line I told you to swap with. The class name is actuall SfAudioSelection, not ISfAudioSelection. Try that instead.

-Rob.

Subject:RE: Normalize Regions Individually
Reply by: Flea-circus
Date:10/12/2015 1:28:58 PM

Hmmm.
I tried that, and it still only normalizes the whole file, once for each region that exists
(e.g.: 2 regions per file = 2 normalizations, 5 regions per file = 5 normalizations, etc.).

Here is what I have:

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

//BEHAVIOR:
//- Normalizes Each Region To Last Preset

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

ISfFileHost file = app.CurrentFile;
if (null == file)
return;

app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));

foreach (SfAudioMarker mk in file.Markers)

{

if (mk.Length <= 0)
continue;

SfAudioSelection asel = new SfAudioSelection(mk.Start, mk.Length);

if (null == asel)
break;

Do("Process.Normalize", true);

app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));

}
}

public static void Do(string cmd) { ForgeApp.DoMenuAndWait(cmd,true); }
public static void Do(string cmd, bool fUseLastPreset) { ForgeApp.DoMenuAndWait(cmd,fUseLastPreset); }

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(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)); }
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); }
} //EntryPoint

Subject:RE: Normalize Regions Individually
Reply by: roblesinge
Date:10/13/2015 9:12:28 AM

I think you'll need to use DoEffect(), which takes a range parameter. That should apply the Normalize to only that range. There is an example of this in the code I posted. You call DoEffect() on the ISfFileHost object, passing in "Normalize", a preset (which I think you can just pass in null, not sure) and a range (or the SfAudioSelection).

-Rob.

Subject:RE: Normalize Regions Individually
Reply by: Flea-circus
Date:10/13/2015 2:09:29 PM

It works!
Spectacular fantastic.
Slowly I am catching on.
Thank you so much.

This is what I ended up with:

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

//BEHAVIOR:
//- Normalizes Each Region To Last Preset

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

ISfFileHost file = app.CurrentFile;
if (null == file)
return;

ISfGenericEffect fx = app.FindEffect("Normalize");
ISfGenericPreset normPreset = fx.ChoosePreset(IntPtr.Zero, 0);

app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));

foreach (SfAudioMarker mk in file.Markers)

{

if (mk.Length <= 0)
continue;

SfAudioSelection range = new SfAudioSelection(mk.Start, mk.Length);

if (null == range)
break;

file.DoEffect("Normalize", normPreset, range, EffectOptions.EffectOnly | EffectOptions.WaitForDoneOrCancel);

app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));

}
}

public static void Do(string cmd) { ForgeApp.DoMenuAndWait(cmd,true); }
public static void Do(string cmd, bool fUseLastPreset) { ForgeApp.DoMenuAndWait(cmd,fUseLastPreset); }

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(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)); }
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); }
} //EntryPoint

Go Back