Monday, November 30, 2009

Reverse Echo

Just updated reverse echo effect. I have audio samples coming as soon as I export them from Ardour.

My TODO list for reverse echo:
1) Volume swell where reverse array pointer crosses recent-old boundary in delay buffer. Right now you hear the discontinuous blip every time the playback loops around. With the current code, the work-around is a long delay time so you get a natural string swell from the natural note decay. No good on short delay times. It sounds worse and worse the more you shorten it up.

2) Update GUI. I don't think I have yet seen a reverse delay FX pedal nor plugin that lets you crossfade between forward and reverse delays. This is precisely the operation of the GUI slider. The more you slide it to the maximum, the more of the reverse you'll hear in the playback. Either extreme is full reverse or full forward. Pretty nifty, hey? I'm anxious to try it.

Otherwise it's pretty much done. See list of links below:

Here are links to the current code. My recent change of directory broke the links in prior blogs...I will try to fix them later.

http://transmogrifox.webs.com/Rakahacks/APhaser.C
http://transmogrifox.webs.com/Rakahacks/APhaser.h
http://transmogrifox.webs.com/Rakahacks/Compressor.C
http://transmogrifox.webs.com/Rakahacks/Compressor.h
http://transmogrifox.webs.com/Rakahacks/compressor.m
http://transmogrifox.webs.com/Rakahacks/Echo.C
http://transmogrifox.webs.com/Rakahacks/Echo.h
http://transmogrifox.webs.com/Rakahacks/Phaser.C
http://transmogrifox.webs.com/Rakahacks/Phaser.h
http://transmogrifox.webs.com/Rakahacks/rakarrack.cxx
http://transmogrifox.webs.com/Rakahacks/rakarrack.h
http://transmogrifox.webs.com/Rakahacks/PhaserSamples.tar.gz

Tuesday, November 17, 2009

Analog Phaser committed to Rakarrack CVS

Analog Phaser committed to Rakarrack CVS as new effect.

Since this technically is no longer a hack, I will defer any code seekers directly to CVS:
http://rakarrack.cvs.sourceforge.net/viewvc/rakarrack/rakarrack2/src/

Leave comments if there are questions about what some of the parameters are meant to control.
***********************************************
As an update to this, here are links to some experimental code implementing envelope control. Since there is no control parameter on the Rakarrack GUI, a different control may need to be hijacked to test it. I have hi-jacked the distortion parameter, so the distortion amount must increase as your envelope deviation increases.
See line 116:
envpct = distortion; //This is a Hack to hijack distortion slider for ef control.

Here's the code.
And you'll need APhaser.h

Friday, November 6, 2009

Tube Modeling diversion

This has nothing to do with Rakarrack hacking, but just thought I'd put it out there:

undefined muse reason = none;
undefined muse insanity = reason - insanity_threshold;

undefined muse model_tube_amp()
{

if (insanity > reason)
return 0;

...and my thoughts about amp modeling:
It seems the most reliable way is to use convolution for frequency response and a look-up table for nonlinearities.

These can be measured directly from the tube amp. Most of the pre-amp filtering & tone controls can be accurately modeled with regular digital 1rst order filters.

It gets the most sticky when you are dealing with output power amp stage to the speakers. It's hard to decouple the impulse response from the nonlinear effects of transformer saturation, so the lookup table + convolution solution is only an approximation. A fair mathematical model requires a noteworthy DSP engine to process in real time.

Though, honestly, the sounds I love from my tube amp come from the preamp. I rarely turn it up to the point where power amp + transformer become notably nonlinear, and I don't actually prefer the resulting loose and mushy sound. One could make a fine FOSS tube preamp with some accurately modeled tone/frequency shaping filters and a look-up table generated from a trace of a 12AX7 tube.

Convolution with a good cabinet IR would be the final stage, simply ignoring nonlinear effects in the power amp & transformer stage. This is reasonable, since higher-end amps are designed to be rather hi-fidelity on the power amp stage. It's funny how the analog engineers are trying to minimize these kinds of distortion and the DSP engineers are trying introduce it into the system.

The result may not produce a perfect replica of amp "X", but it could produce the same nice interactive characteristic. It all depends whether the goal is a good sound, or a convincing model of something specific.

In the FOSS world, there's much more flexibility since you don't have pressure from a marketing department to produce a sound that sells. You can apply some creativity to the software development process and create something that sets its own precedent.

Most of my complaint about tube amp simulators is not so much how well the amp is simulated, but it's about what amps are modeled. I have a Peavey Duel 212, and have modified the circuitry to my taste. Line6 has yet to produce a product that behaves in any way like my amp, even though their modeling algorithms are perfectly capable. Only, I can't open up the hood on a POD and change a few capacitor and resistor values...

So you say, "well they have the DSP development kit for the ToneCore docks". They don't give you their proprietary amp modeling algorithms to tweak...so you have to develop your own, and here's what I have to say about that:
insanity++;
model_tube_amp();
}

Sunday, November 1, 2009

Phaser Files

You can find the source code two blogs down with instructions to compile it into your current version of Rakarrack. I keep it up to date with my current work.

Here is a zip archive of Audio samples recorded from a jam session playing with my rakarrack and the analog phaser model.

Sound Files

The zip file is a tar.gz, and the audio files are .ogg format. If either is a problem, leave a comment and I may feel inclined to submit a regular .zip full of .mp3 format files. I figure if you aren't using Linux, then Rakarrack is probably of little interest for you.

Recording setup is:
Vox V810 overdrive Pedal (modified) --> Peavey Duel 212 --> EFX loop send--> Behringer UCA202 in (left)--> Rakarrack --> Ardour --UCA202 out --> EFX loop return --> Power Amp.

Any distortion sounds come from either the Vox OD pedal or the tube preamp, or a combination of the two. Sorry I can't claim the sweet chunky sounds are coming from rakarrack.

My todo list is now down to this:
1) Change names of hi-jacked parameters to names more appropriate to what they're controlling. For example, "Panning" actually adjusts the amount of JFET distortion level, where -64 corresponds to 0. This produces a subtle effect even at maximum (which seems reasonable, since the real Analog phaser doesn't make the signal outright fuzzy).
2) Model component mismatches. JFET's vary drastically in manufacturing process. Even hand-matched units can be different by 5%. My working hypothesis is this increases the "swirl" as this causes the bandwidth of the phase cancellation notches to become wider, even though the cancellation depth may not be as great. Particularly narrow notches are not quite as audible. This will probably provided as a slider that makes the variance between stages adjustable from perfect to abysmal.
3) Rename files to Phaser_Analog.C (and .h) and integrate as a separate selectable effect into Rakarrack.

Thursday, October 29, 2009

Phaser modulation

It appears my math for the modulation function on the all-pass filter is not the best model for a JFET phaser. I spent a good couple hours with my guitar trying different settings on this phaser. There are certainly some nice sounds available, but it simply did not behave as expected.

I sat down and computed the bilinear transform myself, to better understand the sources I was reading, as well as doing my own analysis on small-signal resistance characteristic of a JFET. After 3 pages of algebra, I came to this conclusion:

R = 250/(1.0114 - sqrt(Vm));

This constrains the range of resistance to 250 to 22k-ohms. The constants 1.0114 and 250 include effects of parameters derived from 2N5458 JFET datasheet, also taking into account the parallel 22k resistor found in the MXR phase90 circuit.

You may notice that when put into the 1/2*pi*R*C equation for center frequency, we have an approximately linear frequency sweep up until the last bit. That explains some of the nature of the analog phaser. To give it a little bit of an exponential feel, we could do this:
R = 250/(lfo^2 + .0114);
or
R = 250/(0.5*(lfo + lfo^2) + .0114); ...to naturalize it a little bit. These are less accurate approximations, but are also less CPU intensive calculations than sqrt().

The final equation for "gain" in the difference equation (gl and gr in rakarrack code) is this:

g = [2*fs*C - (1.0114 - sqrt(Vm))/250 ] / [2*fs*C - (1.0114 - sqrt(Vm))/250 ]

Where fs is sampling frequency and C is value of capacitor (.05 uF).

The difference equation is this:
y[n] = g*(x[n] + y[n-1]) - x[n-1] where g is as noted above

Now a real JFET doesn't have a perfectly linear resistance characteristic, so we can introduce an input-dependent term that changes the "resistance" with signal amplitude:

Vm = lfo * (1-d*Vin^2) where constant "d" is amount of distortion to apply.

Vin is the input signal (smps[i]).

I think a realistic value for "d" is about 0.04 in this application. This can be a parameter that is possible to adjust from 0 to an insane number like .5 or .8 where there is some definite intermodulation available. This is not a rigorous account for the distortion added by the JFET, but I'm hoping it's a good enough approximation for acceptable sounding results while keeping CPU requirement at a minimum. The point is to add a small amount of harmonics at each phase stage to accentuate the "swoosh" heard from an analog phaser.

I see need to employ a look-up table for the LFO, so the phaser doesn't need to be interpolating it all the time.

Tuesday, October 27, 2009

Analog Phaser first pass -- Code

Here's something that seems to work reasonably well. It's modeled after the MXR Phase180 type circuit. Typical JFET phaser. I have not modeled the nonlinear effects yet, as I'm contemplating a CPU-friendly way to do this. The technically correct way would make this a cycle hog as it requires the math functions are applied to every sample in every phase stage.

Here's the code:
Phaser.C
Phaser.h

Download and replace your existing Phaser.C and Phaser.h files in your working Rakarrack source directory and

$ su
# make
# make install

or for those with sudo user:
sudo make
sudo make install

Please notice that L/R crossing is unused in this version, and I have also disabled panning. I need to figure out a way to implement these that does not negatively effect the intensity of the phasing effect.

Here is a more detailed description of what this model attempts to accomplish.

The basic operation is derived from a bilinear transformation of a FET all-pass stage similar to what is found in the MXR phase180 stompbox, and the feedback network matches this circuit topology, but with more extreme settings available. The Rakarrack Phaser (imported from Paul Octavian) employs positive and negative feedback, where a setting of 64 is zero feedback. This feature has been maintained in the analog model. Some more complex analog phasers implement this kind of flexibility.

The modulation characteristic employs math to approximate the transfer function between modulation voltage at the JFET gate to small-signal resistance seen between the source and drain.

In its present form I have not included any input-dependent modeling to approximate the effect of distortion introduced by the JFET's, nor effects of random variance between JFET's that normally cause each stage to vary somewhat from the ideal case when JFET's are meticulously matched.

I may end up modeling the old Ross Phaser tri/sine modulation waveform. It's pretty interesting --- it has the sine wave shape for the negative half of the cycle and the triangle wave shape for the positive half cycle. It was an OTA-based phaser, so the application of this to my phaser model will be entirely unique, but this phaser model isn't supposed to sound like any specific analog phaser. It's just modeled according to typical analog circuit blocks. Just the fact that the number of phase stages can be modified with a click of a mouse makes it unique.

Here are the features that make it most like an Analog Phaser:
a) Wet/Dry mix performs the phase cancellation, so that 50% wet/dry results in the deepest filtering.
b)Turning more to wet generates that classic vibrato sound when the speed is turned up, so it can create a little bit of a pitch shift.
c) Modulation sweep has that effect of dwelling at the low end of the sweep, and then creates a fast "swoosh" when it "comes up for air".

All in all I think this could be a nicely flavored addition to Rakarrack when I am done twiddling and tweaking.

Sunday, October 18, 2009

Analog phaser off to a good start

Indeed, my implementation of the phaser had problems with my treatment of the loop.

Now I got a good phasing effect happening. Now that's out of the way I need to perfect the modulation end of things and model some of the distortion inherent to analog JFET phasers. Any who read, be looking for some code soon.

Thursday, October 15, 2009

Phaser Matlab file

I did some more research and have this analog phaser model pretty well tuned in Matlab (actually FreeMat). Probably is fine in Octave, too.

This is a simple script file, not really a function. It performs a frequency sweep on the filter and averages the output sort of reminiscent of the analog bench test signal generator police siren mode with an external trigger to trace the envelope outline. It's one way to get the job done.

I am hoping that porting the DSP phaser block to C++ will solve my phaser woes. This and the reverse delay will have to wait until my next free block of time to sit down and do some coding.

See below:

SR = 48000;
DUR = 4;
t = (1:1:DUR*SR);
tt = t/SR;
fmax = 12000;
fq = tt*fmax/DUR;
x = sin(2*pi*tt.*(1+fmax*tt/DUR));
%x = sin(2*pi*tt.*8000);
PER = length(x);

f3 = 2000;
C = 0.1e-6;
R = 1/(2*pi*C*f3)
b = 1/(2*SR*R*C);
att = (1 - b)/(b + 1)
IN =1;
output = x;
sta = 4;
CHARGE=0*(1:sta);
delta=CHARGE;
x1=delta;
i=1;
feedback = 0;
fb = 0;

for (k=1:PER);

j=0;

x(i) = x(i) + feedback;
b = 1/(2*SR*(.9*R + .1*R/(1 - x(i)*x(i)) )*C);
att = (1 - b)/(b + 1);

for stages = 1:sta
j = j+1;

CHARGE(j) = -x1(j) + att*(x(i) + CHARGE(j));
x1(j)=x(i);
x(i) = CHARGE(j);

end
feedback = x(i)*fb;
i=i+1;
end

output = .5*x + .5*output;
dbput = 20*log10(abs(output));

dcharge=0;
ddelta=0;
j=0;
att = .02;
for i=1:PER
j=j+1;
ddelta = dbput(j) - dcharge; %Low CPU interpolation
dcharge = dcharge + att*ddelta;
dbput(j) = dcharge;
end

%plot(tt,output,'r-',tt,x,'g-');
plot(fq,dbput,'r-');
CHARGE
max(output)

Tuesday, October 13, 2009

Analog Phaser Frustration

I have been attempting to model an analog phaser for rakarrack based upon the existing phaser (from ZynAddSubfx), since the only necessary changes lie within a few lines of code at the core of phaser.c.

I have modeled the algorithm in FreeMat (Matlab work-alike) and produced plots that agree with theory.

My inexperience with C and C++ must be causing me some problems in the way I am dealing with parameters...such as type casting int to float etc....or maybe I am just making a dumb "off by 1" mistake in the loop.

Argghhh. I have decided to take on a reverse delay feature request from the rakarrack forum. This seems a simple enough hack, starting with echo.c...and maybe port the functionality to MusicDelay.c.

If anyone reads this blog, here is the section of code modified. It is yet untested, but if the relevant parts are copy/pasted into echo.c, and make sure the extra variables are declared in echo.h, then I anticipate this will produce the reverse delay. I hope to compile and test this later this week. I have a bunch of meat to butcher, so my next couple of evenings are pretty well tied up with the joy of hunting season.

Comments are welcome:

/*
* Effect output
*/
void
Echo::out (REALTYPE * smpsl, REALTYPE * smpsr)
{
int i;
int reverse = 1; //Notice this is hard-coded to reverse delay mode. This variable declaration will needed to be deleted from here, declared in echo.h, and controlled from the GUI.
REALTYPE l, r, ldl, rdl;

for (i = 0; i < PERIOD; i++)
{

ldl = ldelay[kl];
rdl = rdelay[kr];

l = ldl * (1.0 - lrcross) + rdl * lrcross;
r = rdl * (1.0 - lrcross) + ldl * lrcross;
ldl = l;
rdl = r;


ldl = smpsl[i] * panning - ldl * fb;
rdl = smpsr[i] * (1.0 - panning) - rdl * fb;

if(reverse) {
efxoutl[i] = ldelay[rvkl] * 2.0;
efxoutr[i] = rdelay[rvkr] * 2.0;
}
else {
efxoutl[i] = ldl * 2.0;
efxoutr[i] = rdl * 2.0;
}


//LowPass Filter
ldelay[kl] = ldl = ldl * hidamp + oldl * (1.0 - hidamp);
rdelay[kr] = rdl = rdl * hidamp + oldr * (1.0 - hidamp);
oldl = ldl;
oldr = rdl;

if (++kl >= dl)
kl = 0;
if (++kr >= dr)
kr = 0;

rvkl = dl - kl;
rvkr = dr - kr;
};

Sunday, September 27, 2009

First Hack - Compressor

This first hack adds a slider to adjust compressor knee -- nothing amazing. This is also the introduction of the finalized compressor fix.

The tarball may be downloaded here:
http://transmogrifox.webs.com/rakarrack2-clean.tar.gz

Should be able to extract, enter the top directory and
./configure.sh
make
make install

Please post a comment if there is a problem compiling. Be sure to install all dev packages relating to dependencies reported as missing in configure output, or make output. The README lists dependencies.

If you simply want to apply the compressor fix to a release of Rakarrack already compiled & installed on your computer, then do the following:
Enter the /src directory. Copy the following files into this directory, and select "ok" to replace the file of the same name:
Compressor.h
Compressor.C

go back into the source package main directory and
make
make install

This will re-compile the changed source files and install this to your system.

Tuesday, September 22, 2009

Development Computer

People often are interested in the development platform being used. Here is my current setup:

Debian GNU/Linux : Squeeze (Testing)
iBook G4 (14")
--1G RAM
--1.33 MHz CPU

I am a novice programmer, and my roots in programming are in my C and C++ classes in college, where we were instructed using a text editor like vi or nano and constructed our own make files, and compiling from the command line. My development tool has progressed from nano to Gedit. It has color mapping and brace/bracket/parentheses matching for most programming languages, which is all I need. I haven't yet attempted an SDK of any sort since my current commandline based environment has become comfortable.

Software most used (in no particular order):
qjackctl for control of jackd
Ardour
ZynAddSubFX
Fluidsynth
Hydrogen Drum Kit

...and of course
Rakarrack

Some people are afraid of switching to Linux because they have to sacrifice many familiar Windows applications. In my experience, I sacrificed little and gained much by switching to Linux.

RakaHack Welcome

I have recently taken interest to hacking Rakarrack ( http://rakarrack.sourceforge.net ) in the way of improving features or fixing/modifying the DSP algroithms within the source code.

My intent is to contribute any fruits of my labor back to the project, but also know that some things will not be included in any releases if the "hacks" do not fit into the project goals.

As a result, this blog will catalog my hacks, and provide instructions for modifying the source code for those who wish to have their own version of RakaHack.

For example, I got started with this when I determined the compressor doesn't behave as expected. I dug into the DSP algorithm within Compressor.C and found some faulty math. This fix has been submitted and included in CVS.

However, on the side I added a slider to the GUI to make the compressor knee user-adjustable. This feature was not added to the project CVS, so perhaps in my next blog I will provide instructions and/or rakarrack.cxx hacked file to add this feature to your own version of Rakarrack.

Now I have it in my mind to continue hacking the effects. Here are some ideas:
1) The distortion function needs up-sampling to reduce digital aliasing artifacts.
2) I want to add a compression-type distortion element (sort of a dynamic tube-like curve, but not really intended to be a tube emulator).
3) Model the phaser after an analog circuit.
4) Add a multiplyer cell for things like ring modulation -- many interesting things can be done here.
5) Split envelope detection to left channel only, so one can use external modulation sources to control the wah-wah. For example, a Crybaby can be used as a volume pedal by feeding high-pass filtered white noise into the Crybaby, then crybaby into the left channel. Guitar into the right channel. The compressor code is hacked to only detect input level on the left channel. Set compressor threshold quite low, and work the crybaby. As the filtered white noise changes in amplitude, the compressor modulates gain on the audio signal, and voila! a volume pedal. This same technique could be used to use your real Crybaby wah pedal to sweep the rakarrack wah.

See how much fun hacking can be?