# Invert Musically

I’m trying to make the entire spectrum flip automatically, without having to rewrite the hertz rate to “2 / 44100”, “2 / 48000”, “2 / 32000”, it would be easier if I just have it auto-detect so I don’t have to keep changing it.

That is what I’m trying to do. This mutes the sound;

``````(hzosc (/ *sound-srate* 2))
``````

but why?

That will generate a tone with a frequency of half the sample rate. The starting phase for hzosc is as the signal crosses zero in the positive direction, thus the first sample is at zero.

See what you get if the generated frequency is a quarter of the sample rate:

At half the sample rate, if the waveform starts at zero, then every sample will be zero.

Note that HZOSC supports two optional parameters, “table” and “phase”. https://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html#index389

The default “table” is sine-table, so you can change the starting position (phase) of the waveform like this:

``````; Starting phase = 90 degrees
(hzosc 440 *sine-table* 90)
``````

See what you get with this code:

``````(hzosc (/ *sound-srate* 2) *sine-table* 90)
``````
``````(hzosc (/ *sound-srate* 4) *sine-table* 90)
``````

No, it gives me a normal sine wave, but what I’m trying to do is increase the frequency/ring so when it is maxed, the lower frequencies (like the reflection) is made into a reverse of the one above, but the normal one above is clipped out. If you look in the picture, I want to make all of the reflected spectrum in green, and the red being over the max sample wave of the sample rate with a ring modulator. If your telling me that it would repeat the cycle of the wave at the same point, that is why I sampled down to half, so it goes up and down once every sample, and the ring modulator reflection will take the maximum frequency and swap it with the minimum.

Like in this picture, halfway up, the frequencies above 0 is increased, and frequencies below 0 is reflected. I want to have all the frequencies reflected at max, flipping the original spectrum upside down (flipping vertically, not turning 180 degrees).

What about this; I double the sample-rate without changing the speed, take that, put a ring sine wave at a quarter of that, and half the sample-rate back without changing the speed?

If the value is 15Hz in 30Hz, change to 60Hz, ring at 15Hz, and change to 30Hz to 15Hz, making 15 = 0 or 1 and 0 or 1 = 15?

Perhaps this is what you want:

``````(mult *track* (hzosc (/ *sound-srate* 2) *sine-table* 90))
``````

Try this plug-in:
FlipSound.ny (631 Bytes)

Think I got it, great, but while on the ‘‘Invert’’ subject, Is there a Nyquist version of Kontrast? Could I convert it from DLL to NY? I have DLL, but I wanted to add that to this effect, in Nyquist. I ‘‘reversed’’ the spectrum volume and I’d like to add it to this.

When I applied Kontrast twice, I made the black and white in the spectrum almost reverse, both times set for;

Gain: 0db
Min: 0%
Max: 1%
Center: 0.5%

Don’t forget I had to do it twice. Doubling the value didn’t work.

I don’t know what “Kontrast” is, but no, it is not possible to convert a DLL into a NY.
If it is possible to implement “Kontrast” in Nyquist, you would have to write the appropriate Nyquist code by hand.

Do you or anyone know a plugin in Nyquist that reverses the spectrum volume, where silence becomes white noise, and tones are then subtracted from the noise? (Basically reverse the brightness of the grayscale spectrum…)

I think I might have discovered a bug.

The effect to flip frequencies worked on files sampled at 22050Hz, 44100Hz, and 48000Hz, but when I recently tried 30000Hz, it only moved the spectrum halfway up. What the heck just happened? You know, it’s funny; I thought I tested it, and thought it worked, and now when I claimed ‘‘It works’’, I find a bug. If it is programmed to work on certain levels of sample-rate, how do I make it work on any sample-rate setting?

Before I mess things further up, Do I need to set ‘‘Sine-Table’’ to 180? Do I need another line of code?

This is the current code I used…

``````;nyquist plug-in
;version 4
;type process
;name "Flip Sound"

;control text "Spectrum Or Waveform?"
;control md "Select Method" choice "Spectrum,Waveform" 0
;control text "We currently do not support different scales, reverse, time-and-frequency swapping, or frequency-analysis (yet)."
;control text "This plugin was a pain-in-the-butt to make, took all night, and was forced to get help from the developer later that morning. The sun was up when I got help around Ten AM. Please, enjoy it."
;control text ""
;control text "This plugin can't..."
;control text "1. Flip pitch, like Frequency Spectrum, except frequencies are set in musical notes"
;control text "2. Flip time, play in reverse"
;control text "3. Swap time and frequency, turn spectrum so Horizontal and Vertical is swapped"
;control text "4. Flip frequency analysis, turn spectrum in negative"
;control text ""
;control text "This plugin can..."
;control text "1. Flip frequency, reversing bass and treble linearly"
;control text "2. Flip wave, making the speaker vibrate with an inverted phase"

(if (= md 0)
(mult *track* (hzosc (/ *sound-srate* 2) *sine-table* 90))
(mult *track* -1))
``````

Does the ‘‘sine-table’’ or ‘‘sound-srate’’ have anything to do with it? The pictures show what worked and what I discovered didn’t.

What does the debug message say?

“Warning: osc frequency reduced by 1 octaves from 15000 to 7500 hz to avoid aliasing.”

Anyway to bypass that?

I think it thought it was over the max frequency at half the sample rate, so it halved again. This made it quarter the sample rate, because at 30000Hz, 15000Hz was too high, which it shouldn’t because it worked with a number of other sample rates; 48000Hz successfully wrote a 24000Hz wave.

Yes, that’s right.

The problem is due to the difficulty in testing “equality” with floating point numbers.

What’s happening within Nyquist:

Within the Nyquist code that defines HZOSC, the “frequency” argument is converted to “steps” (similar to MIDI Note numbers), and passed to the OSC function. HZOSC is a convenient, high level function for generating waveforms, but under the covers it uses OSC.

OSC is also written in Nyquist / Lisp. After some error checking and calculating the necessary parameters, it uses the low level function SND-OSC (written in C) to generate the waveform.

SND-OSC requires the frequency in Hz, so the OSC code converts its “steps” parameter back to Hz.
Unfortunately, although floating point numbers have a high level of precision, they are not exact, and the small amount of imprecision can cause some surprising results.

Consider this code:

``````(setf hz 30000)
(setf steps (hz-to-step hz))
(setf hz2 (step-to-hz steps)) ; round trip conversion

(if (= hz hz2)
(print "hz2 = hz")
(if (> hz hz2)
(print "hz > hz2")
;else
(print "hz2 > hz")))
``````

You would probably expect the above code to print “hz2 = hz”, because hz2 is just “hz” converted to steps and back to hz.
Run the code yourself, and notice that due to rounding errors, “hz2” is actually a bit bigger than hz.

Thus HZOSC is unreliable for the case where the requested frequency is equal to the sample rate.

Probably the best solution is to write a new function to handle the special case of generating a sine tone at the Nyquist frequency with a 90 degree phase. Something like this:

``````(defun ny-hzosc ()
;;; Generate a wave at the Nyquist frequency with 90 degrees phase
(let ((sound *SINE-TABLE*)
(hz (/ *SOUND-SRATE* 2)))
(snd-osc (car sound) (cadr sound) *SOUND-SRATE* hz 0 1 90)))
``````

Here’s a new version of my “Flip Sound” plug-in, using the NY-HZOSC function from my previous post:
FlipSound.ny (933 Bytes)

Here’s a macro that you may find interesting.
Try applying it to a mono track that is no more than 1 second duration.
Spectral Invert.txt (325 Bytes)

A better version here: Spectral Invert

So it rounds up the frequency to something else? In that case…

Is it possible to have the NY file convert to a different sample-rate, apply the effect and convert back? Like, for example; convert 30000Hz to 48000Hz, add sine-ring, and convert 48000Hz back to previous value 30000Hz?