moved modules to src folder
This commit is contained in:
parent
e7cc59846f
commit
ed4dae67af
Binary file not shown.
|
@ -0,0 +1,170 @@
|
|||
import requests
|
||||
import datetime
|
||||
from PIL import Image
|
||||
from PIL import ImageFont
|
||||
from PIL import ImageDraw
|
||||
import colorsys
|
||||
import json
|
||||
import numpy as np
|
||||
import imageio
|
||||
import random
|
||||
from math import floor
|
||||
import os
|
||||
import logzero
|
||||
from logzero import logger
|
||||
from logzero import setup_logger
|
||||
import random
|
||||
|
||||
|
||||
def generate_offsets(array_size, max_offset):
|
||||
periodicity = random.randint(1, 10)
|
||||
periodicity = random.random() * periodicity
|
||||
offsets = []
|
||||
for i in range(array_size):
|
||||
# print(floor(max_offset*np.sin(periodicity*(i*np.pi/180))))
|
||||
offsets.append(floor(max_offset*np.sin(periodicity*(i*np.pi/180))))
|
||||
return offsets
|
||||
|
||||
|
||||
def hueChange(img, offset):
|
||||
# https://stackoverflow.com/questions/27041559/rgb-to-hsv-python-change-hue-continuously/27042106
|
||||
# It's better to raise an exception than silently return None if img is not
|
||||
# an Image.
|
||||
img.load()
|
||||
r, g, b = img.split()
|
||||
r_data = []
|
||||
g_data = []
|
||||
b_data = []
|
||||
|
||||
offset = offset/100.
|
||||
for rd, gr, bl in zip(r.getdata(), g.getdata(), b.getdata()):
|
||||
h, s, v = colorsys.rgb_to_hsv(rd/255.0, bl/255.0, gr/255.0)
|
||||
# print(h, s, v)
|
||||
# print(rd, gr, bl)
|
||||
rgb = colorsys.hsv_to_rgb(h, s+offset, v)
|
||||
rd, bl, gr = [int(x*255.) for x in rgb]
|
||||
# print(rd, gr, bl)
|
||||
r_data.append(rd)
|
||||
g_data.append(gr)
|
||||
b_data.append(bl)
|
||||
|
||||
r.putdata(r_data)
|
||||
g.putdata(g_data)
|
||||
b.putdata(b_data)
|
||||
return Image.merge('RGB',(r,g,b))
|
||||
|
||||
def decision(probability):
|
||||
return random.random() < probability
|
||||
|
||||
def getImage(out_name="image.jpg"):
|
||||
now = datetime.datetime.now()
|
||||
dt_str = now.strftime("%Y-%m-%dT%H:%M:%Sz")
|
||||
newurl = url.format(WIDTH=3840, HEIGHT=2160, DATE=dt_str)
|
||||
r = requests.get(newurl)
|
||||
img_data = r.json()["batchrsp"]["items"][0]
|
||||
# ["ad"]["image_fullscreen_001_landscape"]["u"]
|
||||
img_url = json.loads(img_data["item"])["ad"]["image_fullscreen_001_landscape"]["u"]
|
||||
r = requests.get(img_url)
|
||||
with open(out_name, "wb") as f:
|
||||
f.write(r.content)
|
||||
|
||||
def mod_image_repeat_rows(imgname, chance_of_row_repeat=0, max_row_repeats=0, min_row_repeats=0, save=True, out_name="image.jpg"):
|
||||
img = Image.open(imgname)
|
||||
pixels = img.load()
|
||||
width, height = img.size
|
||||
|
||||
repeat = False
|
||||
num_repeats = 0
|
||||
times_to_repeat = 0
|
||||
row_to_repeat = []
|
||||
offsets = []
|
||||
for y in range(height):
|
||||
if not repeat and decision(chance_of_row_repeat):
|
||||
repeat = True
|
||||
times_to_repeat = random.randint(min_row_repeats, max_row_repeats)
|
||||
offsets = generate_offsets(times_to_repeat, random.randint(10, 50))
|
||||
for x in range(width):
|
||||
r, g, b = img.getpixel((x, y))
|
||||
|
||||
if repeat and len(row_to_repeat) != width:
|
||||
pixels[x, y] = (r, g, b)
|
||||
row_to_repeat.append((r, g, b))
|
||||
elif repeat:
|
||||
try:
|
||||
pixels[x, y] = row_to_repeat[x + offsets[num_repeats]]
|
||||
except Exception as e:
|
||||
pixels[x, y] = row_to_repeat[x - offsets[num_repeats]]
|
||||
else:
|
||||
pixels[x, y] = (r, g, b)
|
||||
|
||||
if repeat:
|
||||
num_repeats += 1
|
||||
if num_repeats >= times_to_repeat:
|
||||
repeat = False
|
||||
times_to_repeat = 0
|
||||
num_repeats = 0
|
||||
row_to_repeat = []
|
||||
offsets = []
|
||||
if save:
|
||||
img.save(out_name)
|
||||
|
||||
|
||||
def add_date(img_path, out_name="image.jpg", bottom_offset=0):
|
||||
date_obj = datetime.datetime.now()
|
||||
date_str_1 = date_obj.strftime("%p %H:%M")
|
||||
date_str_2 = date_obj.strftime("%b. %d %Y")
|
||||
corner_offset = 50
|
||||
img = Image.open(img_path)
|
||||
width, height = img.size
|
||||
draw = ImageDraw.Draw(img)
|
||||
font = ImageFont.truetype("src/VCR_OSD_MONO_1.001.ttf", 64)
|
||||
draw.text((corner_offset, (height-150-bottom_offset)), date_str_1, (255, 255, 255), font=font)
|
||||
draw.text((corner_offset, (height-75)-bottom_offset), date_str_2, (255, 255, 255), font=font)
|
||||
draw.text((corner_offset, 25), "|| PAUSE", (255, 255, 255), font=font)
|
||||
img.save(out_name)
|
||||
|
||||
def add_img_noise(imgpath, intensity=1, out_name="image.jpg"):
|
||||
img = imageio.imread(imgpath, pilmode='RGB')
|
||||
noise1 = img + intensity * img.std() * np.random.random(img.shape)
|
||||
imageio.imwrite(out_name, noise1)
|
||||
|
||||
def offset_hue(image, out_name="image.jpg"):
|
||||
if isinstance(image, str):
|
||||
image = Image.open(image)
|
||||
image = hueChange(image, 25)
|
||||
image.save(out_name)
|
||||
|
||||
def build_background(out_name, taskbar_offset):
|
||||
#getImage(out_name="start.jpg")
|
||||
offset_hue("start.jpg", out_name="saturated.jpg")
|
||||
mod_image_repeat_rows("saturated.jpg", 0.012, 50, 10, out_name="shifted.jpg")
|
||||
add_img_noise("shifted.jpg", out_name="noisy.jpg")
|
||||
add_date("noisy.jpg", out_name=out_name, bottom_offset=taskbar_offset)
|
||||
|
||||
"""
|
||||
if __name__ == "__main__":
|
||||
build_background("bkg.jpg", 25)
|
||||
"""
|
||||
|
||||
def generateVHSStyle(infile, outfile):
|
||||
cut_rows = bool(random.getrandbits(1))
|
||||
offset = random.choice([0,5,10,15,20,25])
|
||||
logger.info("Saturating the image")
|
||||
offset_hue(infile,"saturated.jpg")
|
||||
if cut_rows:
|
||||
logger.info("Shifting the image")
|
||||
mod_image_repeat_rows("saturated.jpg", 0.012, 50, 10, True, "shifted.jpg")
|
||||
else:
|
||||
logger.info("Not applying lines effect")
|
||||
mod_image_repeat_rows("saturated.jpg", 0, 0, 0, True, "shifted.jpg")
|
||||
logger.info("Adding noise")
|
||||
add_date("shifted.jpg","noisy.jpg")
|
||||
logger.info("Adding text")
|
||||
add_date("noisy.jpg",outfile, bottom_offset=offset)
|
||||
logger.info("Generated Image: out.jpg")
|
||||
logger.info("Removing residual files")
|
||||
os.remove("shifted.jpg")
|
||||
os.remove("saturated.jpg")
|
||||
os.remove("noisy.jpg")
|
||||
|
||||
#generateVHSStyle("s.jpg","o.jpg")
|
|
@ -0,0 +1,182 @@
|
|||
import os
|
||||
import subprocess
|
||||
import re
|
||||
from random import randint
|
||||
|
||||
import logzero
|
||||
from logzero import logger
|
||||
from logzero import setup_logger
|
||||
|
||||
CONFIDENCE_THRESH = 0.02
|
||||
|
||||
class VaporSong:
|
||||
|
||||
# Slows down Track
|
||||
|
||||
def slow_down(src, rate, dest):
|
||||
cmd = "sox -G -D " + src + " " + dest + " speed " + str(rate)
|
||||
os.system(cmd)
|
||||
return dest
|
||||
|
||||
# Adds Reverb
|
||||
|
||||
def reverbize(src, dest):
|
||||
cmd = "sox -G -D " + src + " " + dest + " reverb 100 fade 5 -0 7" # idk what this does tbh, https://stackoverflow.com/a/57767238/8386344
|
||||
os.system(cmd)
|
||||
return dest
|
||||
|
||||
|
||||
# Crops "src" from "start" plus "start + dur" and return it in "dest"
|
||||
def crop(src,dest,start,dur):
|
||||
cmd = "sox " + src + " " + dest + " trim " + " " + str(start) + " " + str(dur)
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
# Randomly crops a part of the song of at most max_sec_len.
|
||||
def random_crop(src, max_sec_len, dest):
|
||||
out = subprocess.check_output(["soxi","-D",src]).rstrip()
|
||||
f_len = int(float(out))
|
||||
if (f_len <= max_sec_len):
|
||||
os.system("cp " + src + " " + dest)
|
||||
return
|
||||
else:
|
||||
start_region = f_len - max_sec_len
|
||||
start = randint(0,start_region)
|
||||
VaporSong.crop(src,dest,start,max_sec_len)
|
||||
|
||||
|
||||
# Given a file, returns a list of [beats, confidence], executable based on audibo's test-beattracking.c
|
||||
# TODO: Move away from executable and use aubio's Python module
|
||||
def fetchbeats(src):
|
||||
beat_matrix = []
|
||||
if os.name == 'posix':
|
||||
beats = subprocess.check_output(["noah", "get-beats",src]).rstrip()
|
||||
else:
|
||||
beats = subprocess.check_output(["get-beats",src]).rstrip()
|
||||
beats_ary = beats.splitlines()
|
||||
for i in beats_ary:
|
||||
record = i.split()
|
||||
record[0] = float(record[0])/1000.0
|
||||
record[1] = float(record[1])
|
||||
beat_matrix.append(record)
|
||||
return beat_matrix
|
||||
|
||||
# Splits an audio file into beats according to beat_matrix list
|
||||
|
||||
def split_beat(src,beat_matrix):
|
||||
split_files = []
|
||||
for i in range(0,len(beat_matrix)-1):
|
||||
|
||||
if(beat_matrix[i][1] > CONFIDENCE_THRESH):
|
||||
dur = (beat_matrix[i+1][0] - beat_matrix[i][0])
|
||||
out = src.split(".")[0]+str(i)+".wav"
|
||||
VaporSong.crop(src,out,beat_matrix[i][0],dur)
|
||||
split_files.append(out)
|
||||
return split_files
|
||||
|
||||
# Combines a list of sections
|
||||
|
||||
def combine(sections,dest):
|
||||
tocomb = []
|
||||
tocomb.append("sox")
|
||||
tocomb.append("-G")
|
||||
for section in sections:
|
||||
for sample in section:
|
||||
tocomb.append(sample)
|
||||
tocomb.append(dest)
|
||||
tmpFileLimit = len(tocomb) + 256 # in case the program messes up, it does not actually frick up your system
|
||||
n = str(tmpFileLimit)
|
||||
#logger.info("Setting file limit to ", n)
|
||||
os.system("ulimit -n " + n)
|
||||
subprocess.check_output(tocomb)
|
||||
return dest
|
||||
|
||||
# Arbitrarily groups beats into lists of 4, 6, 8, or 9, perfect for looping.
|
||||
|
||||
def generate_sections(ary):
|
||||
sections = []
|
||||
beats = [4,6,8,9]
|
||||
index = 0
|
||||
while(index != len(ary)):
|
||||
current_beat = beats[randint(0,len(beats)-1)]
|
||||
new_section = []
|
||||
while((current_beat != 0) and (index != len(ary))):
|
||||
new_section.append(ary[index])
|
||||
current_beat -= 1
|
||||
index += 1
|
||||
sections.append(new_section)
|
||||
return sections
|
||||
|
||||
|
||||
# given a list of sections, selects some of them and duplicates them, perfect for that vaporwave looping effect
|
||||
def dup_sections(sections):
|
||||
new_section = []
|
||||
for section in sections:
|
||||
new_section.append(section)
|
||||
if(randint(0,1) == 0):
|
||||
new_section.append(section)
|
||||
return new_section
|
||||
|
||||
# a passage is a list of sections. This takes some sections and groups them into passages.
|
||||
|
||||
def make_passages(sections):
|
||||
passages = []
|
||||
index = 0
|
||||
while(index != len(sections)):
|
||||
passage_len = randint(1,4)
|
||||
passage = []
|
||||
while(index != len(sections) and passage_len > 0):
|
||||
passage.append(sections[index])
|
||||
index += 1
|
||||
passage_len -= 1
|
||||
passages.append(passage)
|
||||
return passages
|
||||
|
||||
# Given all of our passages, picks some of them and inserts them into a list some number of times.
|
||||
|
||||
def reorder_passages(passages):
|
||||
new_passages = []
|
||||
passage_count = randint(5,12)
|
||||
while(passage_count != 0):
|
||||
passage = passages[randint(0,len(passages)-1)]
|
||||
passage_count -= 1
|
||||
dup = randint(1,4)
|
||||
while(dup != 0):
|
||||
dup -= 1
|
||||
new_passages.append(passage)
|
||||
return new_passages
|
||||
|
||||
# converts a list of passages to a list of sections.
|
||||
|
||||
def flatten(passages):
|
||||
sections = []
|
||||
for passage in passages:
|
||||
for section in passage:
|
||||
sections.append(section)
|
||||
return sections
|
||||
|
||||
# It's all coming together
|
||||
|
||||
def vaporize_song(fname, title):
|
||||
logger.info("Slowing down the music")
|
||||
VaporSong.slow_down(fname, 0.7, "beats/out.wav")
|
||||
#logger.info("Cropping")
|
||||
#VaporSong.random_crop("beats/out.wav",150,"beats/outcrop.wav")
|
||||
logger.info("Doing Beat Analysis")
|
||||
bm = VaporSong.fetchbeats("beats/out.wav")
|
||||
logger.info("Split into beats")
|
||||
splitd = VaporSong.split_beat("beats/out.wav",bm)
|
||||
#group beats to sections
|
||||
logger.info("Divide into sections")
|
||||
sections = VaporSong.generate_sections(splitd)
|
||||
logger.info("Duping Sections")
|
||||
sdup = VaporSong.dup_sections(sections)
|
||||
# group sections into passages
|
||||
paslist = VaporSong.make_passages(sdup)
|
||||
# reorder packages
|
||||
pasloop = VaporSong.reorder_passages(paslist)
|
||||
sectionflat = VaporSong.flatten(pasloop)
|
||||
logger.info("Mastering & Reverbing")
|
||||
VaporSong.combine(sectionflat,"beats/out_norev.wav")
|
||||
VaporSong.reverbize("beats/out_norev.wav","./" + (re.sub(r"\W+|_", " ", title)).replace(" ","_") + ".wav")
|
||||
logger.info("Generated V A P O R W A V E")
|
Loading…
Reference in New Issue