Community Forums Archive

Go Back

Subject:Marking a file as changed
Posted by: CharlesK
Date:3/18/2011 3:17:07 PM

I have a script that makes changes to a file. However, Sound Forge (10) is not aware that any changes have been made to the file, so when I close Sound Forge, I'm not prompted to save my changes. How do I tell Sound Forge that the file is 'dirty'?

Subject:RE: Marking a file as changed
Reply by: roblesinge
Date:3/28/2011 7:08:05 AM

Can you post your code in a
 
block? Otherwise, we're shooting in the dark as to what is happening in your script.

Rob.

Subject:RE: Marking a file as changed
Reply by: CharlesK
Date:4/1/2011 2:47:41 PM

I'd be glad to put it in a code block, but I'm not sure how. In the meantime, here's the script. What it does is create regions of 5 minutes in length throughout the open sound file. When all the regions are made and the script returns to Sound Forge, if I exit Sound Forge, none of my regions are saved.

Code Block:

/* =======================================================================================================
* Script Name: Add Tracks To CD
* Description: This script will add regions at fixed intervals throughout
* the length of the open file
*
* Initial State: Run with one file open
*
* Parameters (Args):
* Step - the interval at which to set markers - DEFAULT: one marker as set below
* Prefix - the first part of the marker name - DEFAULT: as set below
* 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 with your own preferences
//NOTE: 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", 300); //The length of each track in seconds.
string szPre = GETARG("Prefix", "M"); //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 ccSampleRate = (int)step*file.SampleRate;
Int64 ccLength = file.Length;
Int64 ccStep = file.SecondsToPosition(step);
Int64 ccLastPos = 0;

if (ccLength < ccStep)
{
// File is shorter than one minute.
MessageBox.Show("Your file is shorter than one track in length. No regions have been created.");
return "File is shorter than marker spacing - no regions created.";
}

if (ccLength > 74 * 60)
{
// File is too long.
MessageBox.Show("Your file is longer than 74 minutes in length which is the limit of one CD. You will have to split the file across multiple CDs. No regions have been created.");
return "File is longer than a CD - no regions 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);

// Delete any existing markers and regions.
SfAudioMarkerList Markers = file.Markers;
int cMarkers = Markers.Count;
if (cMarkers > 0)
{
int cRemoved = 0;
for (int ii= cMarkers-1; ii >= 0; --ii)
{
SfAudioMarker mk = Markers[ii];
file.Markers.Remove(mk);
++cRemoved;
}
}

// Create regions spaced every minute with a length of one minute.
for (Int64 ccPos = 0; ccPos+ccSampleRate < ccLength; ccPos += ccStep)
{
SfAudioMarker mk = new SfAudioMarker(ccPos,ccSampleRate);
string name = String.Format("{0}{1:###.##} {2}", szPre, 1+file.PositionToSeconds(ccPos)/ccStep, szPost);
mk.Name = name.Trim();
file.Markers.Add(mk);

ccLastPos = ccPos;
}
// Add the last region and try to make it the length of the remaining data.
{
SfAudioMarker mk = new SfAudioMarker(ccLastPos+ccStep,ccLength-ccLastPos-ccSampleRate);
string name = String.Format("{0}{1:###.##} {2}", szPre, 1+file.PositionToSeconds(ccLastPos)/ccStep, szPost);
mk.Name = name.Trim();
file.Markers.Add(mk);
}
// Close the undo wrapper, and tell it to keep the changes.
//
file.EndUndo(idUndo, false);
app.ActiveWindow.SetCursorAndScroll(app.ActiveWindow.File.Length, DataWndScrollTo.Nearest);
MessageBox.Show("Your file has been updated but has not been saved. Be sure to check the last track to see if it's too short. If it is, delete the last region and extend the end point of the (new) last region. To write the file to a CD, click the 'Make CD Tracks From Regions' button and follow the directons.");
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)); }
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;
else
try { d = double.Parse(s); } catch {}
return d;
}
} //EntryPoint

Subject:RE: Marking a file as changed
Reply by: CharlesK
Date:4/4/2011 12:40:05 PM

I should point out that the comment in the code that reads
// Create regions spaced every minute with a length of one minute.
hasn't been updated to read every 5 minutes. In addtion, the message box that reads in part "To write the file to a CD, click the 'Make CD Tracks From Regions' button and follow the directons" is referring to a script button that converts the regions into CD tracks and then writes a disc-at-once audio CD.

Subject:RE: Marking a file as changed
Reply by: roblesinge
Date:4/5/2011 9:04:07 PM

It appears that placement of the marker clearing is key with this. The only way I can get the file to show up as modified after running the script is if I move the file.Markers.clear(); statement outside of the undo wrapper. I also made some other changes to your script to simplify what it seems like you're trying to do. I didn't add in the text formatting you had for each marker, but you can add that back in if you like.

BTW, to put code blocks around your code in a forum post, simply type "open square bracket" code "closed square bracket" (note that I'm having to literally type "bracket" because otherwise it would start a code block. Replace "bracket" with an actual "[" or "]") To close the block, put a "/" in front of code (again inside brackets).


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)
{
long maxLength;
long stepSize;

ISfDataWnd wnd = app.ActiveWindow;

if (null == wnd)
{
MessageBox.Show("Open a file before running this script");
}

ISfFileHost file = app.CurrentFile;


maxLength = (74 * 60) * file.SampleRate;
stepSize = 300 * file.SampleRate;

if (file.Length < stepSize)
{
MessageBox.Show("Your file is shorter than one track in length. No regions have been created.");
}

if (file.Length > maxLength)
{
MessageBox.Show("Your file is longer than 74 minutes in length, which is the limit of one CD. You will have to split the file across multiple CDs. No regions have been created.");
}

//Delete any existing markers and regions.
file.Markers.Clear();

//Create undo wrapper
string szUndo = String.Format("Create Markers every 5 minutes");
int idUndo = file.BeginUndo(szUndo);

long spacer = 0;
int offset = 1;
int inc = 1;

//Find out how many markers we need
long markNum = file.Length / stepSize;

//Add markers to all but the last segment
for (int x = 0; x < (markNum - offset); x++)
{
file.Markers.AddRegion(spacer, stepSize, "Track_" + (x+1));
spacer += stepSize;
inc++;
}

//Deals with the last segment
long leftOver = file.Length - spacer;
file.Markers.AddRegion(spacer, leftOver, "Track_" + inc);

//Close undo wrapper
file.EndUndo(idUndo, false);

MessageBox.Show("Your file has been updated but has not been saved. To write the file to a CD, click the 'Make CD Tracks From Regions' button and follow the directions.");

}

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


Hope this works for you.

Rob.

Subject:RE: Marking a file as changed
Reply by: CharlesK
Date:4/7/2011 12:25:29 PM

Thank you so much for digging into the script and improving it and discovering why the file was not being marked as changed. I have absolutely zero knowledge regarding C programming, so I'm sure my techniques were a bit non-standard.

What still puzzles me a little bit is why creating a marker does not flag the file as changed. I guess I could always add then delete a marker (outside of the undo wrapper) to do this.

Thanks again.

Subject:RE: Marking a file as changed
Reply by: roblesinge
Date:4/7/2011 2:21:13 PM

Yeah, I'm not completely sure why it works that way. However, moving the marker clearance seemed to work, and it only adds one undo step in the sequence.

I too am not exactly a C# guru, but scripting in SF is helping me improve those skills. The SDK and this forum make it pretty accessible for us non-programmers.

Rob.

Go Back