Skip to content

Instantly share code, notes, and snippets.

@unreadable
Created January 9, 2018 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unreadable/7c47abf61ea9df84c390e5bbfaae33e6 to your computer and use it in GitHub Desktop.
Save unreadable/7c47abf61ea9df84c390e5bbfaae33e6 to your computer and use it in GitHub Desktop.
import wave, struct
import numpy as np
from tkinter import *
from tkinter.filedialog import askopenfilename
import pygame
# =========================== INIT STUFFS ========================================
root = Tk()
root.title("Sound mixer")
pygame.init()
filename = askopenfilename(filetypes = (("WAV Files", "*.wav"), ("All files", "*.*")))
pygame.mixer.music.load(filename)
# ============================= LOAD SOUND STUFFS ================================
# sound = wave.open(filename, 'r')
# nchannels, sampwidth, framerate, nframes, _, _ = sound.getparams()
# out = wave.open('out.wav', 'w')
def pitch_sound( fr, volume, speed):
sound = wave.open(filename, 'r')
nchannels, sampwidth, framerate, nframes, _, _ = sound.getparams()
c = int(nframes/framerate * fr)
shift = 100//fr # shifting 100 Hz
out = wave.open('out.wav', 'w')
set_sound(out, speed, nchannels, framerate)
for _ in range(c):
data = np.fromstring(sound.readframes(framerate//fr), dtype="int16")
data = data * volume
l, r = np.fft.rfft(data[0::2]), np.fft.rfft(data[1::2])
l, r = np.roll(l, shift), np.roll(r, shift)
l[0:shift], r[0:shift] = 0, 0
arr = np.column_stack((np.fft.irfft(l), np.fft.irfft(r))).ravel().astype(np.int16)
out.writeframes(arr.tostring())
sound.close()
out.close()
return "out.wav"
def set_sound(input_wav, speed, nchannels, framerate):
input_wav.setnchannels(nchannels)
input_wav.setsampwidth(2) # By saying 2 we have 2 bytes per frame this means that we can store 1 short integer in a frame.
input_wav.setframerate(framerate * speed)
# =========================== GUI STUFFS ==========================================
fr, volume, speed = 1, 1, 1
def load_cb():
# print(fr, volume, speed)
name = pitch_sound(fr, volume, speed)
pygame.mixer.music.load(name)
# print("Done!")
def slide_volume_cb(val):
global volume
volume = float(int(val)/10)
def slide_pitch_cb(val):
global fr
fr = 201 - int(val)
def slide_speed_cb(val):
global speed
speed = int(val)
Button(root, text="Play sound", command=lambda: pygame.mixer.music.play()).grid(row=0, column=0)
Button(root, text="Pause", command=lambda: pygame.mixer.music.pause()).grid(row=0, column=1)
Button(root, text="Resume", command=lambda: pygame.mixer.music.unpause()).grid(row=0, column=2)
Button(root, text="Stop sound", command=lambda: pygame.mixer.music.stop()).grid(row=0, column=3)
Label(root, text="Change pitch").grid(row=3, column=0)
Scale(root, from_=0, to=200, orient=HORIZONTAL, command=slide_pitch_cb).grid(row=3, column=1)
Label(root, text="Change volume" ).grid(row=4, column=0)
Scale(root, from_=0, to=50, orient=HORIZONTAL, command=slide_volume_cb).grid(row=4, column=1)
Label(root, text="Change speed").grid(row=5, column=0)
Scale(root, from_=0, to=10, orient=HORIZONTAL, command=slide_speed_cb).grid(row=5, column=1)
Button(root, text="Apply settings", command=load_cb).grid(row = 4, column = 3)
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment