moved modules to src folder

This commit is contained in:
Navan Chauhan 2020-03-10 20:48:20 +05:30
parent e7cc59846f
commit ed4dae67af
4 changed files with 352 additions and 0 deletions

BIN
src/VCR_OSD_MONO_1.001.ttf Normal file

Binary file not shown.

170
src/VHSImage.py Normal file
View File

@ -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")

182
src/VaporSong.py Normal file
View File

@ -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")

0
src/__init__.py Normal file
View File