Community Forums Archive

Go Back

Subject:simple fm
Posted by: ForumAdmin
Date:10/14/2005 12:47:29 PM

A user from the main Forge forum wanted an example for writing his own fm synthesis algorithm. Just thought it belonged over here rather than there.


using System;
using System.IO;
using SoundForge;

public class EntryPoint
{
public void Begin(IScriptableApp app)
{
SfWaveFormat wfx = new SfWaveFormat(44100, 16, 1, false);
ISfFileHost file = app.NewFile(wfx, false);

int cSeconds = 10; // total length
float gc = 0.5f; // carrier amplitude
double fc = 440.0; // carrier freq in Hz
double fm = 1.0; // modulator freq in Hz
double fdelta = 50.0; // freq deviation in Hz
double norm = 2*Math.PI / file.SampleRate; // freq to rad helper

double fi = 0; // instantaneous frequency
double wt = 0; // spectral frequency

Int64 cTotal = cSeconds * file.SampleRate;
int cBuffer = 4096;
float[] data = new float[cBuffer * file.Channels];
ISfWriteAudioStream was = file.OpenWriteAudioStream(file.SampleType, file.Channels, 0);

for (Int64 cs = 0; cs < cTotal; cs += cBuffer)
{
if (cTotal < cs)
cBuffer -= (int)(cs - cTotal);

for (int ix = 0; ix < cBuffer; ++ix)
{
fi = fc + (fdelta * Math.Sin(norm*fm*(cs+ix))); // *instantaeous* frequency
wt += norm * fi; // integrate for spectral frequency
data[ix] = gc * (float)Math.Sin(wt); // fm signal
}

was.Append(data, 0, (int)(cTotal - cs), SfSampleType.WavFloat);
}

file.WriteAudio(file.Window.EditRegion, was);
}

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;

} //EntryPoint

J.

Message last edited on10/14/2005 2:23:53 PM byForumAdmin.
Subject:RE: simple fm
Reply by: GPD
Date:10/14/2005 1:57:00 PM

I get a compiler error when i try to run this.

Subject:RE: simple fm
Reply by: ForumAdmin
Date:10/14/2005 2:25:30 PM

Now fixed.

Subject:RE: simple fm
Reply by: GPD
Date:10/14/2005 2:51:30 PM

yup! Awesome.

I assume this specifies sample rate and bit depth:

SfWaveFormat wfx = new SfWaveFormat(44100, 16, 1, false);

So I could change it to:

SfWaveFormat wfx = new SfWaveFormat(96000, 24, 1, false);

How about if I wanted 32 or 64bit FP formats?

What is the "math resolution" of the program? I mean all all calcs done at 32bfp or 64bfp?

Are all "opperators" calcuated with the full resolution of the sample rate? (I mean, C-Sound and SupperCollider have the concept of Controler rate signals, whcih use some fraction of the sample rate to save resoures--sometimes people use the control rate fo the modulators.)

This is awesome. I like your code format also. It makes it very easy to change parameters.

Subject:RE: simple fm
Reply by: GPD
Date:10/14/2005 3:09:58 PM

It seems that first the first sample created in not 0. The end sample is (assuming fc, fm, and lenght are integers). The output still loops perfectly, but is there a way to make the first sample and not the last 0?

If nothing else, if the whole output file is reversed and then phase inverted this will acomplish the goal.

Subject:RE: simple fm
Reply by: ForumAdmin
Date:10/14/2005 3:14:53 PM

Sound Forge supports up to 192 kHz and 32 and 64-bit IEEE floats.

Most internal calculations are 64-bit and results are stored in that format until the file is rendered. The plug-in chainer is currently 32-bit float.

There's no c-sound controller equivalent in Sound Forge that I'm aware of.

Make sure you take a look at the included sample scripts and scripting SDK available in the Downloads section.

J.

Subject:RE: simple fm
Reply by: GPD
Date:10/16/2005 6:20:32 PM

Is it possible to modify this code to do the following:

1.) Produce a stereo file, where each channel (L&R) has an independant FM function with different parameters.

2.) Insert a "save.as" command, and script a name which is pulled from CONCATENATING something generic like "FM Wave" with the relavant paramters assigned to each channel, such that saved named becomes something like "FM Wave L255.1.16 R257.1.16.wav" (fc.fm.fdelta for both channels)

If yes, is it also possible to insert a file close command, and string a whole bunch of these together all with different parameters so that they all can be rendered, named, saved, and closed in batch with one command?

That would be truly awesome!

Go Back