Community Forums Archive

Go Back

Subject:Deinterleave
Posted by: tpeda
Date:11/21/2005 11:41:44 PM

Is there a way to deInterleave stereo file to separate mono. I found the DeInterleaveTest c# script but it crashes sound forge.

Message last edited on11/21/2005 11:42:43 PM bytpeda.
Subject:RE: Deinterleave
Reply by: _TJ
Date:11/22/2005 9:34:24 PM

Sorry. I'm not sure what you mean. A non-interleaved .wav file would just be
an invalid file.

The main reason for de-interleaving is so that you can run DSP algorithms on each channel separately.

tj

Subject:RE: Deinterleave
Reply by: tpeda
Date:11/23/2005 10:17:54 AM

What I want to do is:
get a stereo file de-interlv add 600 samples to the end of the left channel and cut same amount of samples from the beginning of the right. then put back in stereo.

Subject:RE: Deinterleave
Reply by: _TJ
Date:11/26/2005 10:47:07 PM

I understand. I'm guessing that you are trying to do that by loading the whole file into one big array and then shifting the data and writing it back. And Sound Forge is crashing because the file is too large to read into memory all at once, right?

To do what you are trying to do, there's no real advantage to de-interleaving the data. You can what you want merely by reading only the channel that you want to shift into memory and then writing it back. (ReadAudio() will read data from a single channel if you pass the right channel mask in the SfAudioSelection).

But there is a much easier and faster way. Cut and paste with a channel mask.

It is quicker and easier to get Sound Forge to move the data for you. The trick is to use a temp file to hold a copy of the data, mute the left channel in the original file, and then copy from the temp file back into the left channel, but with an offset.

Using this technique, we can take advantage of Sound Forge's non-destructive editing primatives so that the edit is nearly instantaneous.

Here's the technique...

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

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

Int64 ccToShift = -600; // amount to shift the left channel relative to the right.

ISfFileHost file = app.CurrentFile;
if (null == file)
return; // "This script operates on the currently open file";
if (0 == ccToShift)
return; // nothing to do.

// create a temporary file that contains a copy of the file data
ISfFileHost fileT = file.NewFile(new SfAudioSelection(0,file.Length));

// this is a multi-step edit, so wrap it up into a single undo with a meaningful name.
int idUndo = file.BeginUndo(String.Format("Shift Left Channel by {0}", ccToShift));

// mute the left channel in the original file.
SfAudioSelection aselLeft = new SfAudioSelection(0, file.Length, 1);
file.MuteAudio(aselLeft);

// if shifting right, insert some extra silence at the end,
// otherwise, insert some extra at the beginning. Then copy the left
// channel data back from the temp file over the (muted) left channel
//
if (ccToShift > 0)
{
file.InsertSilence(file.Length, ccToShift);
file.OverwriteAudio(ccToShift, 1, fileT, aselLeft);
}
else if (ccToShift < 0)
{
file.InsertSilence(0, -ccToShift);
file.OverwriteAudio(0, 1, fileT, aselLeft);
}

// close out the undo.
file.EndUndo(idUndo, false);

fileT.Close(CloseOptions.DiscardChanges);
}

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


tj



Message last edited on11/26/2005 10:56:31 PM by_TJ.

Go Back