Channels ▼
RSS

JVM Languages

Music Components in Java: Effects


Phaser Effect

A phaser is one of the most popular effects to come out of the psychedelic 1960's. It provided the syrupy, liquidy, etherial sounds popular in rock music of the time and is still used extensively today. Most present day guitar players have a phaser or two in their pedal collections.

Sound example six (also available in the downloadable file bundle) illustrates what a phaser sounds like. Describing the sound of a phaser in words is difficult, so you should listen to this example.

You can consult the PhaserEffect class Javadocs in hte downloadable file bundle to see the details of the provided API; but basically, you have the ability to bypass the phaser effect, to control the dry/wet mix, and to set the sweep rate frequency, the sweep range, and the feedback level. In sound example six, the dry/wet mix is set at 60%, the sweep rate is set to two Hertz, the sweep range is set to seven octaves, and the feedback level to 50%.

The code snippet below shows how to couple the phaser effect into a typical signal chain.


		// Create a phaser effect
		PhaserEffect fe = new PhaserEffect();

		// Set the sample provider 
		fe.setSampleProvider(osc);
		fe.setDryWetMixPercent(60);
		fe.setSweepRate(2.0);
		fe.setSweepRangeInOctaves(7);
		fe.setFeedbackPercent(50);

		// The next component in the chain sets the phaser as its sample provider 

Unlike the aforementioned delay effect, there is plenty of DSP going on within the phaser effect (most of it being beyond the scope of this discussion). Instead of dwelling on details, I will focus on giving you an intuitive explanation of the phaser's operation. For those interested in a more vigorous explanation, please see my book Digital Audio with Java.

This phaser uses a cascade of four identical all-pass digital filters to color the sound. This design is meant to emulate old analog phasers, which had four all-pass filters implemented in hardware with resistors, capacitors, and FET transistors.

All-pass filters allow all frequencies to pass unattenuated, but modify the phase of signals passing through them in a frequency-dependent manner. When the signal that passed through the filters is mixed with the dry (unprocessed) signal, the frequencies that are out of phase will cancel — thus creating notches in the frequency response, which gives the phaser its characteristic sound. The frequency at which the phase change occurs and the amount of phase shift are controlled by a low frequency oscillator built into the phaser effect.

The core of the phaser effect code is shown in Listing Two. The getSamples method is exactly the same as described previously for the delay effect. Again, it is within the processSample method where phasing occurs. Here, the input sample is provided to the first of the all-pass filters; its output is then sent to the second all-pass filter; and so on. These digital filters require a single sample of prior history to calculate the current value, and once calculated ,the current value is saved away for use in the next sample. The angular frequency value, wp, controls the current cutoff frequency of the filters and is modified at every sample time to sweep the filters up and down.

Listing Two: The guts of the phaser effect from the PhaserEffect class.

	/**
	 * Perform initialization calculation based upon sweep rate and range.
	 */
	private void initialize() {
		
		wp = minWp = (2.0 * Math.PI * PHASER_BASE_FREQUENCY) / SamplePlayer.SAMPLE_RATE;
		
		// Convert octave range to freq range
		double freqRange = Math.pow(2.0, sweepRangeInOctaves);
		
		maxWp = minWp * freqRange;
		
		currentStep = step = 
			Math.pow(freqRange, sweepRate / (SamplePlayer.SAMPLE_RATE / 2.0));
	}

	/**
	 * Process a single sample through effect.
	 * 
	 * @param shortSample The input sample to process
	 * 
	 * @return Processed sample including wet and dry signal
	 */
	public short processSample(short shortSample) {
				
		if (bypassed) {
			return shortSample;
		}

		double sample = ((double) shortSample) / Short.MAX_VALUE;

		// Calculate A in difference equation
		double A = (1.0 - wp) / (1.0 + wp);
		
		double inSample = sample + ((feedbackPercent * thisOut4) / 100.0);
		
		// Do the first allpass filter
		thisOut1 = A * (inSample + thisOut1) - prevIn1;
		prevIn1 = inSample;
		
		// Do the second allpass filter
		thisOut2 = A * (thisOut1 + thisOut2) - prevIn2;
		prevIn2 = thisOut1;
		
		// Do the third allpass filter
		thisOut3 = A * (thisOut2 + thisOut3) - prevIn3;
		prevIn3 = thisOut2;
		
		// Do the forth allpass filter
		thisOut4 = A * (thisOut3 + thisOut4) - prevIn4;
		prevIn4 = thisOut3;
		
		// Calculate wet and dry contributions
		double dryLevel = ((100.0 - dryWetMixPercent) * sample) / 100.0;
		double wetLevel = (dryWetMixPercent * thisOut4) / 100.0;
		double outSample = dryLevel + wetLevel;
		
		if (outSample > 1.0) {
			outSample = 1.0;
		}	else if (outSample < -1.0)	{
			outSample = -1.0;
		}
					
		// Update sweep
		wp *= currentStep;		// Apply step value
		
		if(wp > maxWp) {		// Exceed max Wp ?
			currentStep = 1.0 / step;
		}	else if (wp < minWp) {	// Exceed min Wp ?
			currentStep = step;
		}
		return (short)(outSample * Short.MAX_VALUE);
	}

Anytime the sweep rate or sweep range values are modified via the API, new values of angular frequency and new angular frequency limits are calculated by the initialize method and are put to use immediately.

Conclusion

Delay and phaser are just two of many possible effects that can be part of a toolbox of electronic music components. Other possibilities include: reverb, pitch shifter, equalizer, compressor, etc. My book provides many effects with full Java code, which can be ported into the architecture presented in this series. In addition, the book presents code for encoding/decoding popular sound file formats, and tools for measuring and monitoring sample streams including a spectrum analyzer, oscilloscope, and others. Between the information presented in these articles and that presented in my book, you have all you need to tackle almost any audio project that presents itself.

I should also mention that my PSynth iPhone/iPod Touch app shows how all of the electronic music components I have discussed in this series can be coupled together into a complete software synthesizer application, thus providing a superset of MiniMoog functionality in the palm of your hand.

Resources

The code for the complete article series can be downloaded here. Source code, executable code, sound examples and javadocs and are all in this jar file.

The following books contain valuable information on electronic music production and digital signal processing.

  1. Computer Music: Synthesis, Composition and Performance, Charles Dodge, Thomas A. Jerse, 1985, 1997. Schirmer Books.
  2. Elements of Computer Music, F. Richard Moore, 1990, Prentice-Hall.
  3. A Programmers Guide To Sound, Tim Kientzle, 1998, Addison-Wesley.
  4. Digital Audio with Java, Craig A. Lindley, 2000, Prentice-Hall.
  5. PSynth – An iPhone/iPod Touch synthesizer app available from iTunes.

Craig Lindley is a hardware engineer who, until recently, had been writing large-scale Java applications.

Creating Music Components in Java (Part One in this series)

Music Components in Java: Creating Oscillators (Part Two in this series)

Music Components in Java: The Synthesizer Core (Part Three in this series)


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video