Community Forums Archive

Go Back

Subject:Scripting Bugs
Posted by: Ghent
Date:6/4/2005 2:22:39 PM

I'm still trying out SoundForge 8.0a Trial.
While doing some scripting I found and documented several bugs. Perhaps these could be fixed in the next patch.

Here is the script, it's written in VBScript: **********************

Imports System
Imports System.IO
Imports System.Windows.Forms
Imports SoundForge

Public Class EntryPoint
Public Function Begin(app as IScriptableApp)
'begin here
Dim FileFormat As New SfWaveFormat(UInt32.Parse("44100"), UInt32.Parse("16"), UInt32.Parse("2"), false)
If App.Files.Count < 1 then
App.NewFile(FileFormat, False)
Else
App.CurrentFile.CropAudio(1, 1)
End If
App.DoEffect("Simple Synthesis", "[Sys] 1 kHz sync tone (5 seconds)", EffectOptions.EffectOnly + EffectOptions.WaitForDoneOrCancel)
App.DoEffect("Insert Silence", "[Sys] 1 second at start of file", EffectOptions.EffectOnly + EffectOptions.WaitForDoneOrCancel)

Dim SelFile As New SfAudioSelection(45346, 1, UInt32.Parse("0"))

App.Outputtext("Bug 1")
App.Outputtext("Using OverwriteAudio method starts at sample 1 instead of sample 0.")
App.Outputtext("This means that all samples are off by 1 when using the OverwriteAudio method.")
App.Outputtext("Below I inserted a sample at sample 2 notice how it actually inserted it at sample 1, which is wrong.")
App.CurrentFile.OverwriteAudio(2, UInt32.Parse("0"), App.CurrentFile, SelFile)
Dim SelChan As New SfAudioSelection(45346, 1, UInt32.Parse("1"))
App.CurrentFile.OverwriteAudio(6, UInt32.Parse("1"), App.CurrentFile, SelChan)
App.CurrentFile.CropAudio(1, 6)

App.Outputtext(" ")
App.Outputtext("Bug 2")
App.Outputtext("See how the left channel only shows a single sample that is not muted.")
App.Outputtext("This is because the GetSample method has its channels reversed.")
App.Outputtext("1 should be the Left channel, and 2 should be the right channel.")
App.Outputtext("However, using the GetSample method the left channel is 2 and the right channel is 1, which is wrong.")
Dim x as Integer
For x = 0 to 5
App.Outputtext(x & " - Left Channel = " & App.CurrentFile.GetSample(x, UInt32.Parse("1")))
Next x

App.Outputtext(" ")
App.Outputtext("Bug 3")
App.Outputtext("See how the right channel is off by one sample.")
App.Outputtext("Notice how the left channel has the sample at 1 and the right channel has the sample at 0.")
App.Outputtext("The left and right channels start at a different number.")
App.Outputtext("The left channel starts at 0 while the right channel starts at 1, which is wrong.")
For x = 0 to 5
App.Outputtext(x & " - Right Channel = " & App.CurrentFile.GetSample(x, UInt32.Parse("2")))
Next x

App.Outputtext("Notice how above we placed the sample at 6 but now we are reading the sample and it is at sample 4 (see above).")
App.Outputtext("This is because both methods (OverwriteAudio and GetSample) are off by 1, thus compounded together makes the final value off by 2.")


App.CurrentFile.Window.SetCursorAndScroll(1, 1)
End Function

Function FromSoundForge(app as IScriptableApp)
ForgeApp = app
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name))
Begin(app)
app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name))
End Function
Public ForgeApp as IScriptableApp
Public Function DPF(sz)
ForgeApp.OutputText(sz)
End Function
Public Function DPF(sz,o)
ForgeApp.OutputText(System.String.Format(sz,o))
End Function
Public Function DPF(sz,o,o2)
ForgeApp.OutputText(System.String.Format(sz,o,o2))
End Function
Public Function DPF(sz,o,o2,o3)
ForgeApp.OutputText(System.String.Format(sz,o,o2,o3))
End Function

End Class 'EntryPoint

****************

This script produces the following results:

Bug 1
Using OverwriteAudio method starts at sample 1 instead of sample 0.
This means that all samples are off by 1 when using the OverwriteAudio method.
Below I inserted a sample at sample 2 notice how it actually inserted it at sample 1, which is wrong.

Bug 2
See how the left channel only shows a single sample that is not muted.
This is because the GetSample method has its channels reversed.
1 should be the Left channel, and 2 should be the right channel.
However, using the GetSample method the left channel is 2 and the right channel is 1, which is wrong.
0 - Left Channel = 0
1 - Left Channel = 0.249455749988556
2 - Left Channel = 0
3 - Left Channel = 0
4 - Left Channel = 0
5 - Left Channel = 0

Bug 3
See how the right channel is off by one sample.
Notice how the left channel has the sample at 1 and the right channel has the sample at 0.
The left and right channels start at a different number.
The left channel starts at 0 while the right channel starts at 1, which is wrong.
0 - Right Channel = 0.249455749988556
1 - Right Channel = 0
2 - Right Channel = 0
3 - Right Channel = 0
4 - Right Channel = 0.249455749988556
5 - Right Channel = 0
Notice how above we placed the sample at 6 but now we are reading the sample and it is at sample 4 (see above).
This is because both methods (OverwriteAudio and GetSample) are off by 1, thus compounded together makes the final value off by 2.

Have Fun!

-Ghent

Message last edited on6/4/2005 2:24:29 PM byGhent.
Subject:RE: Scripting Bugs
Reply by: _TJ
Date:6/4/2005 5:15:13 PM

I'll have to look a little more closely at bug 1, thats one of the wierd boundary conditions that we may have gotten wrong. We SHOULD be throwing an exception here - as your input is invalid. The fact that we don't may indicate a real problem.

But bug 2 is certainly not a bug. and Bug 3 is again invalid input that we aren't reporting correctly.

The issue here is that GetSample() can only return a single sample, so it's second parameter is NOT a bitmask of selected channels. It's second parameter is a channel INDEX. That is, you should pass 0 for left, and 1 for right in this case. When you pass a 2, Sound Forge SHOULD be throwning and Invalid Argument exception, but instead, it appears that we use it as a mod(2) channel index. That is, we give you the left channel, but with a +1 position bias. Our bad, we'll get this fixed, but it isn't going to get in your way except in the sense that it will make bugs in your code harder to find.

Incidently, as for Bug1. I'm not certain that this script really does what you mean it to do. You are passing 0 as the source selection channel mask, which means ALL CHANNELS, but then you are trying to overwrite only the left (and later the right) channel. In other words, you are asking us to mix both of the source channels together and then overwrite it onto the left channel. This is an illegal operation for OverwriteAudio(), and we ought to be throwing an exception.

If you want to overwrite from only a single channel of the source you should be setting selFile to (45346, 1, 1); for the first OverwriteAudio call, and (45346, 1, 2) for the second. Or you could use a mono file for the source.

tj



Message last edited on6/4/2005 5:17:45 PM by_TJ.
Subject:RE: Scripting Bugs
Reply by: Ghent
Date:6/5/2005 7:55:44 PM

"I'll have to look a little more closely at bug 1, thats one of the wierd boundary conditions that we may have gotten wrong. We SHOULD be throwing an exception here - as your input is invalid. The fact that we don't may indicate a real problem."

Perhaps you didn't look at the code closely enough (Numbers are really easy to mix up).

I do not select both channels then paste only one of the two channels. If I try to paste a stereo source into one channel the code WILL throw an exception.

In the first selection, line 18;
Dim SelFile as New SFAudioSelection(45346, 1, UInt32.Parse("0"))
UInt32.Parse("0") is ALL CHANNELS selected

is used on line 24;
App.CurrentFile.OverwriteAudio(2, UInt32.Parse("0"), App.CurrentFile, SelFile)
UInt32.Parse("0") is ALL CHANNELS pasted

But I make a NEW selection on line 25;
Dim SelChan As New SfAudioSelection(45346, 1, UInt32.Parse("1"))
UInt32.Parse("1") is one channel selected

which is then used to paste into one channel at a time. The point here is that I pasted into sample 6, see line 25:
App.CurrentFile.OverwriteAudio(6, UInt32.Parse("1"), App.CurrentFile, SelChan)
UInt32.Parse("1") is one channel pasted

but, it pastes it into sample 5 instead.


As for Bug2:
"The issue here is that GetSample() can only return a single sample, so it's second parameter is NOT a bitmask of selected channels. It's second parameter is a channel INDEX. That is, you should pass 0 for left, and 1 for right in this case."
I tried this out and you are right (Thanks for fixing that bug in our script!). I did a little more testing and found that Sound Forge WILL throw an exeption if I use a channel index value of 3 or greater. But it will NOT throw and Invalid Argument exception for the value 2. The documentation isn't the clearest on this.

And now I can see how bug3 was related to bug2.

Thanks for fix are script, and your prompt reply.

-Ghent

Message last edited on6/5/2005 8:00:14 PM byGhent.
Subject:RE: Scripting Bugs
Reply by: _TJ
Date:6/5/2005 9:28:59 PM

My mistake. I see now that first you copy stereo to stereo at position 2, and later left channel to left channel at position 6.

Then you Crop at 1 with a length of 6. This has the effect of deleting the first
sample. So when you print out the sample values later, they are 'off by 1'.

Try running your script again. Then Undo the Crop operation and zoom in at the start of the file. You will see that the data is correct; Left and Right have non-zero samples at position 2, and left has one at position 6 as well.

Or change your App.CurrentFile.CropAudio(1, 6) to CropAudio(0, 6).

BTW, I'm pleased to see that someone is using the Audio direct access functions. If it wouldn't compromise your business, I'd love to know that you intend to do with them.


tj


Subject:RE: Scripting Bugs
Reply by: Ghent
Date:6/5/2005 11:50:35 PM

Well, it's near midnight so I won't go and try the scipt out tonight, but here is what I already do with Sound Forge and how scripting in 8 is effecting me.

I run a http://www.GraceBaptist.ws/ Sermons page for my church. I own Sound Forge 7 and use it to clean up and prepare sermons for webcasting and MP3 Download. I run a several process (EQ, Channel Converter, Normalize, etc) on each sermon, and then save them in both WMA9 (for streaming) and MP3. Since the files are a lot longer than a 3 minute music file they take quite a while to run. Usually I run one... wait... wait..., run the next one, wait... etc. (Saving it to WMA9 takes quite a while too!). Oh, and I found out that my digital recorder records the left and right channels out of sync! (The left channel will be several samples ahead or behind the right channel). So I had to fix that while I'm at it. All in all preparing the sound file took quite a while. I would work on two sound files at a time to save a little time -- but it still took me qutie some time. (More than I had)

So when I found out Sound Forge 8 supported scripting (I know Visual Basic) I said "Wooohooo!"

I downloaded the trial and wrote a script that:
Scans the left and right channel for disalignment and realigns them(Heres where I ran into the GetSample() and OverWriteAudio() commands), runs all my process, then saves the file in both WMA9 and MP3 (and relables the file). At my church there are 3 sermons preached a week. Now I can open all three sermons, press a button and go have lunch. When I come back -- Vula! They're done! It really makes my work a snap! Now, all I have to do is trim the file and push a button -- Maybe I'll even have the script play my favorite song when it's done too :)

Oh, by the way. It seems to me that Channel Converter in 8.0a can invert one channel faster than the Flip/Invert process -- Is that just me or is Channel Converter really faster? I'm not on the computer with 8.0a but with version 7 on a 30 minute file I can Flip/Invert the right channel in 25.238 seconds, but the Channel Converter can do the same thing in 20.672 seconds.

Anyhow, if you are really curious I'd be more than happy to send you a copy of the script I use and a recording (so you can see the disaligned channels).
-Ghent
I will get back to you on how your suggestion worked.

Message last edited on2/10/2007 12:20:14 PM byGhent.
Subject:RE: Scripting Bugs
Reply by: _TJ
Date:6/6/2005 5:30:39 PM

Oh, by the way. It seems to me that Channel Converter in 8.0a can invert one channel faster than the Flip/Invert process -- Is that just me or is Channel Converter really faster?

It's probably really faster, It was written more recently than Flip/Invert and uses a different method for getting data off of disk. For simple operations like invert, the time spent reading and writing to the disk tends to dominate.

tj

Go Back