Created
September 17, 2018 17:31
-
-
Save rebane2001/5b5237be0f749a1e17f62ce3662827ee to your computer and use it in GitHub Desktop.
Made for: https://youtu.be/E3gf88rSzqo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## NOTE | |
## I'm only releasing this code for educational purposes | |
## Do not abuse it please | |
## And this is terrible code, so don't use this as a reference on how to code properly | |
## Made for: https://youtu.be/E3gf88rSzqo | |
from PIL import Image | |
from PIL import ImageFilter | |
import math | |
import wave | |
import struct | |
import time | |
import os | |
video_framerate = 30 #Framerate of the input image sequence, you can and should use floating point numbers here, if required | |
seq_folder_name = "sequence" #Name of the folder where your image sequence is in | |
wav_folder_name = "wavs" #Name of the folder where the wavs are going to go to | |
max_freq = 4500 #Max frequency your audio will go up to (if you set this too low the program will crash) | |
#Some weird audio stuff I don't understand | |
nchannels = 1 #Amount of channels in audio. Keep this at 1 | |
sampwidth = 2 | |
framerate = 44100 #Sample rate, you'll probably want to keep this as is | |
nframes = int(framerate/video_framerate) | |
comptype = "NONE" | |
compname = "not compressed" | |
audiodata = {} | |
def calculateHz(w): | |
out = 0 | |
outplus = 0 | |
for x in [(84,0,100)]: #insert segments in the following format (in pixels from start) -> (end of the current segment,start of the current segment,how many hz this segment represents) | |
out = convertToHz(x,w) #Have this thing give us the Hz | |
if out > -1: break #That thing figured out the Hz, break outta loop | |
outplus += x[2] #Add the Hz from this segment and move over to the next one | |
return out + outplus | |
def convertToHz(x,w): #Do quick maffs to figure out the Hz | |
a,b,c = x #To be fair, even I don't understand this part of the code anymore | |
d = a-b #But it should be self-explanatory | |
out = -1 #So I'm not going to comment on | |
if w < a: #What this part actually | |
out = (w-b)/d*c #does... | |
return round(out) #Round the Hz value so it's nice and smooth | |
def calculatedB(h): | |
db = ((h - 146) / 934) * -120 #146 is how many pixels from the top the audio visualization starts, 934 is how many pixels are there after that and -120 is the decibel range (in this case, from 0dB to -120dB) | |
return round(db) #Round the dB value so it's nice and smooth | |
for x in range(1, max_freq): | |
audiodata[x] = [] #Fill our dict with pretty much nothing | |
i = 0 | |
for img_file in os.listdir(seq_folder_name): #Go through all the image files | |
i+=1 | |
print(os.path.splitext(img_file)[0]) | |
im = Image.open(os.path.join(seq_folder_name,img_file)) | |
pix = im.load() | |
width, height = im.size | |
for w in range(width): #Go trough every pixel horizontally | |
for h in range(height): #Go trough every pixel vertically | |
if not pix[w,h] == (0,0,0): #Detect all pixels that aren't 100% black | |
#Uncomment the following line to see the Hz/dB output | |
#print(str(calculateHz(w)) + "hz : " + str(calculatedB(h)) + "db") | |
audiodata[calculateHz(w)].append(calculatedB(h)) #Calculate the data and add it to our dict | |
break #Don't look down vertically anymore, we aready have the data we need | |
for x in range(1,max_freq): #This part just fixes stuff but it might be broken, I'm not sure | |
if len(audiodata[x]) < i: audiodata[x].append(-120) | |
for sound,sounds in audiodata.items(): #Go through all the values stored in the dict | |
print(sound) | |
frequency = sound | |
wav_file = wave.open(wav_folder_name + "\\" + str(frequency) + 'hz.wav', 'w') | |
wav_file.setparams((nchannels, sampwidth, framerate, nframes, comptype, compname)) | |
for volume in sounds: | |
amplitude = 10**((100+volume)/20)# 100000 is max value; convert volume from dB to raw value | |
try: | |
for i in range(nframes): | |
#Honestly don't know what this for loop does, I just copy-pasted it from stackoverflow | |
#I mean, it creates sinewaves at the frequency and amplitude we chose, but I dunno how it works | |
#You don't actually need to know how this part works as the program still works regardless of if you understand how it works or not | |
sample = math.sin(2*math.pi*frequency*(float(i)/framerate))*amplitude/2 | |
wav_file.writeframes(struct.pack('h', int(sample))) | |
except: | |
print("Error at: " + sound) | |
wav_file.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment