Skip to content

Instantly share code, notes, and snippets.

@Ravarcheon
Last active May 29, 2024 19:08
Show Gist options
  • Save Ravarcheon/3a97266c0a0ed8ce33a96f1e556ed4e5 to your computer and use it in GitHub Desktop.
Save Ravarcheon/3a97266c0a0ed8ce33a96f1e556ed4e5 to your computer and use it in GitHub Desktop.
rotates an audio file by 90 degrees in the spectrum while being a reversible process with minimal loss (only floating point errors which are like -150 dB but thats literally silence ahaha~)
import numpy as np
import soundfile as sf
from scipy.fftpack import fft, ifft
def rotateSignal(signal,flip):
if flip:
signal = signal[::-1]
x = np.concatenate((signal, signal[1:][::-1])) # concatenating the array with a reverse of itself makes it such that the fourier transform doesn't layer over a reversed version of itself in the inverse fft
rotSig = ifft(x)
# delete the second half of the array cus fft does that thing where it also has a reversed spectrum after the regular one
rotSig = rotSig[:len(rotSig) // 2 + 1] #cheeky little plus 1 here
# this thing is quite important cus the output is usually really quiet, so this conserves the energy that the input has
energyRatio = np.sqrt(np.sum(np.abs(signal)**2) / np.sum(np.abs(rotSig)**2))
rotSig *= energyRatio
return rotSig
def skibidi(input, output,flip=True):
signal, sampleRate = sf.read(input, dtype='float64')
if signal.ndim == 1: # mono
rotSig = rotateSignal(signal,flip)
else: # stereo
rotSig = np.column_stack((rotateSignal(signal[:, 0],flip), rotateSignal(signal[:, 1],flip)))
sf.write(output, rotSig.astype(np.float64), sampleRate, format='WAV', subtype='FLOAT')
print(f"saved {output}")
# this is a 32 bit float wav, meaning that clipping isn't an issue, but DO keep in mind that you probably will get a file that has amplitudes over 0dB
if __name__ == "__main__":
inputFile = input()
skibidi(inputFile, 'rotated.wav') # this is a 90 degree clockwise rotation where the beginning will be at nyquist frequency and the end be at 0hz
skibidi(inputFile, 'swapped.wav',False) # this is a swap of the time and frequency axiis, this time the end of the sound is at nyquist and the beginning is at 0hz
skibidi('swapped.wav', 'inverted.wav') # this is a vertical flip of the input signal and reversed
# a 180 degree rotation can be achieved simply by reversing inverted.wav
# a 270 degree rotation can be achieved simply by reversing swapped.wav
skibidi('swapped.wav', 'restored.wav',False) # for comparing loss in reconstruction if you want, delete this line if you dont care about that lol
#i make music too so please check that out lolol https://ravarcheon.fanlink.tv/profiles https://linktr.ee/ravarcheon https://www.youtube.com/ravarcheon
@nkkls
Copy link

nkkls commented May 18, 2024

why is the function name skibidi 😭

@mynvs
Copy link

mynvs commented May 18, 2024

W

@LostMyselfInTheNowhere
Copy link

I'm grabbing this. <3

@alejosandu
Copy link

this escalated quickly xd

@calebcrossover
Copy link

very great ^^

@artemetra
Copy link

beautiful

@tzwel
Copy link

tzwel commented May 18, 2024

based skibidi toilet fan

@bogoblin
Copy link

just need to put this in a plugin now

@Minenik2
Copy link

truly great skibidi

@KaixoCode
Copy link

I turned this spectral rotation stuff into a VST plugin, download over here: https://github.com/KaixoCode/SpectralRotator

@LostMyselfInTheNowhere
Copy link

I turned this spectral rotation stuff into a VST plugin, download over here: https://github.com/KaixoCode/SpectralRotator

This is just SOOOOO cursed! And thank you

@Nirossen
Copy link

thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment