Goniometer Algorithm

DSP, Plugin and Host development discussion.
Topic Starter
1 posts since 25 Jan, 2017

Post Wed Jan 25, 2017 3:56 am

I'm currently trying to create a goniometer - like the one in the Waves PAZ package.


However I can't seem to find any algorithm that describes how to get from the samples to the angles.
I'd guess that the angles would be something like this:
   -45 = Left
    45 = Right
      0 = Centre/mono
  <45 = Out of phase
 >-45 = Out of phase

I've already got an FFT component working that provides the amplitude for each sample.
Any help would be greatly appreciated!


User avatar
2919 posts since 10 Nov, 2013 from Germany

Post Wed Jan 25, 2017 4:32 am

REAPER comes with a JS-script goniometer which you could check.

I think it's included in the reaplugs-package.

It's not FFT based (already did some local mods to the script).

User avatar
503 posts since 1 May, 2006 from lancaster, pa

Post Wed Jan 25, 2017 4:33 am

This page (http://dsp.stackexchange.com/questions/ ... hase-meter) has some good information about figuring out the information needed to graph.

564 posts since 1 Jan, 2013 from Denmark

Post Wed Jan 25, 2017 4:40 am

Usually you obtain the phase of the input pair (x,y) using the arctangent. If you're plotting a standard XY scope, you'll wan't to use atan2(y, x), otherwise use atan(y / x). atan()'s output range is only a half circle as you see (-pi/2 .. pi / 2), where atan2() can produce the full circle.

The length of the line is usually just max(|x|, |y|). You may need to additionally to 2d-rotate the values -pi/2, such that an angle of pi/2 on a unit circle appears to be "in phase" as the example UI depicts.

User avatar
73 posts since 18 Feb, 2016

Post Fri Jan 27, 2017 2:45 pm

I recently made a simple goniometer for my first Juce project. Here is some of my C++ code and comments, showing how I convert input sample data from cartesian to polar coordinates, rotate it 45 degrees, then convert back to cartesian coordinates ready to be plotted on a graph. This is my first audio plugin and C++ project so it is possible my approach is naive, but hopefully it is helpful!

Code: Select all

double x = points[i].second; // Right channel is mapped to x axis
double y = points[i].first; // Left channel is mapped to y axis

// Convert cartesian to polar coordinate
// @see https://www.mathsisfun.com/polar-cartesian-coordinates.html
double radius = sqrt((x * x) + (y * y));
double angle = atan(y/x);

// atan() returns wrong value if either value is negative.
// Correct for this by rotating 180 or 360 degrees depending on which
// quadrant of the x/y graph the cartesian coordinate is in.
if ((x < 0 && y > 0) || (x < 0 && y < 0)) {
    angle += 3.14159265; // Pi radians = 180 degrees
} else if (x > 0 && y < 0) {
    angle += 6.28318530; // 2Pi radians = 360 degrees

// atan() will return zero if either of our coordinates is zero.
// Correct for this by manually setting the angle.
if (x == 0) {
    angle = y > 0 ? 1.57079633 : 4.71238898; // 90 or 270 degrees
} else if (y == 0) {
    angle = x > 0 ? 0 : 3.14159265; // 0 or 180 degrees

// Rotate coordinate by 45 degrees counter clockwise
angle += 0.78539816;
// Convert polar coordinate back to cartesian coordinate.
double xRotated = radius * cos(angle);
double yRotated = radius * sin(angle);
Oblivion Sound Lab
Synthesizer soundsets and audio plugins

1 posts since 1 Dec, 2016

Post Sun Jan 29, 2017 12:01 pm

Fantastic example code - I'm starting to work on a Goniometer currently, I've already implemented a compressor with an fft using WDL-OL.

I'll have a look at your code with what i've been writing, i'm pretty new to C++ and i'm having fun figuring it out :D

Return to “DSP and Plugin Development”