random-stuff/spectro/run.py

303 lines
6.3 KiB
Python

colorscheme = [
[ 77, 77, 77],
[ 77, 77, 77],
[ 77, 77, 77],
[ 77, 77, 77],
[ 77, 77, 77],
[ 77, 78, 77],
[ 77, 78, 78],
[ 77, 78, 78],
[ 77, 79, 79],
[ 78, 80, 79],
[ 78, 80, 80],
[ 78, 81, 81],
[ 78, 82, 82],
[ 78, 83, 83],
[ 78, 84, 84],
[ 78, 85, 85],
[ 78, 86, 86],
[ 78, 87, 87],
[ 78, 88, 88],
[ 78, 89, 89],
[ 78, 90, 91],
[ 78, 91, 92],
[ 78, 91, 93],
[ 78, 92, 94],
[ 78, 93, 96],
[ 77, 94, 97],
[ 77, 95, 98],
[ 77, 96, 100],
[ 77, 97, 101],
[ 76, 98, 103],
[ 76, 99, 104],
[ 76, 100, 105],
[ 75, 100, 107],
[ 75, 101, 109],
[ 75, 102, 110],
[ 74, 103, 112],
[ 74, 104, 113],
[ 74, 105, 115],
[ 73, 105, 117],
[ 73, 106, 118],
[ 72, 107, 120],
[ 72, 108, 122],
[ 72, 108, 124],
[ 72, 109, 126],
[ 72, 110, 127],
[ 72, 110, 129],
[ 72, 111, 131],
[ 72, 112, 133],
[ 72, 112, 135],
[ 72, 113, 137],
[ 73, 113, 139],
[ 74, 114, 141],
[ 75, 115, 143],
[ 76, 115, 146],
[ 77, 116, 148],
[ 79, 116, 150],
[ 80, 116, 152],
[ 82, 117, 154],
[ 85, 117, 156],
[ 87, 117, 158],
[ 90, 118, 161],
[ 92, 118, 163],
[ 94, 118, 165],
[ 96, 118, 167],
[ 98, 119, 169],
[101, 119, 171],
[103, 119, 173],
[105, 119, 176],
[107, 119, 178],
[109, 119, 180],
[111, 119, 182],
[113, 119, 184],
[116, 119, 186],
[118, 119, 188],
[120, 118, 190],
[122, 118, 192],
[124, 118, 193],
[126, 118, 195],
[128, 118, 197],
[131, 117, 199],
[133, 117, 200],
[135, 117, 202],
[137, 116, 203],
[139, 116, 205],
[141, 115, 206],
[143, 115, 208],
[146, 115, 209],
[148, 114, 210],
[150, 114, 211],
[152, 113, 212],
[154, 113, 213],
[156, 112, 214],
[158, 112, 215],
[160, 111, 216],
[162, 111, 217],
[164, 110, 217],
[166, 110, 218],
[168, 110, 219],
[170, 109, 219],
[172, 109, 219],
[174, 108, 220],
[176, 108, 220],
[178, 107, 220],
[180, 107, 220],
[182, 107, 220],
[184, 106, 220],
[186, 106, 220],
[187, 106, 220],
[189, 106, 220],
[191, 106, 219],
[193, 105, 219],
[195, 105, 219],
[197, 105, 218],
[198, 105, 218],
[200, 105, 217],
[202, 105, 216],
[204, 105, 216],
[205, 106, 215],
[207, 106, 214],
[209, 106, 213],
[210, 106, 212],
[212, 107, 211],
[214, 107, 210],
[215, 108, 209],
[217, 108, 208],
[219, 108, 207],
[220, 109, 206],
[222, 110, 205],
[223, 110, 203],
[225, 111, 202],
[226, 111, 201],
[228, 112, 200],
[229, 113, 198],
[231, 114, 197],
[232, 114, 195],
[234, 115, 194],
[235, 116, 193],
[236, 117, 191],
[238, 118, 190],
[239, 119, 188],
[240, 120, 187],
[242, 120, 185],
[243, 121, 183],
[244, 122, 182],
[246, 123, 180],
[247, 124, 179],
[248, 126, 177],
[249, 127, 176],
[250, 128, 174],
[252, 129, 173],
[253, 130, 171],
[254, 131, 169],
[255, 132, 168],
[255, 133, 166],
[255, 134, 165],
[255, 136, 163],
[255, 137, 162],
[255, 138, 160],
[255, 139, 158],
[255, 140, 157],
[255, 142, 155],
[255, 143, 154],
[255, 144, 152],
[255, 145, 150],
[255, 146, 149],
[255, 148, 147],
[255, 149, 146],
[255, 150, 144],
[255, 152, 143],
[255, 153, 141],
[255, 154, 139],
[255, 156, 138],
[255, 157, 136],
[255, 158, 135],
[255, 160, 133],
[255, 161, 131],
[255, 163, 130],
[255, 164, 128],
[255, 166, 127],
[255, 167, 125],
[255, 169, 124],
[255, 170, 122],
[255, 172, 120],
[255, 173, 119],
[255, 175, 117],
[255, 177, 116],
[255, 178, 115],
[255, 180, 113],
[255, 182, 112],
[255, 183, 111],
[255, 185, 109],
[255, 187, 108],
[255, 189, 107],
[255, 190, 107],
[255, 192, 106],
[255, 194, 105],
[255, 196, 105],
[255, 198, 105],
[255, 200, 105],
[255, 201, 105],
[255, 203, 105],
[255, 205, 106],
[255, 207, 107],
[255, 209, 108],
[255, 211, 109],
[255, 213, 111],
[255, 215, 113],
[255, 217, 115],
[255, 218, 117],
[255, 220, 119],
[255, 222, 121],
[255, 224, 124],
[255, 226, 127],
[255, 228, 129],
[255, 230, 132],
[255, 232, 135],
[255, 233, 138],
[255, 235, 142],
[255, 237, 145],
[255, 239, 148],
[255, 240, 152],
[255, 242, 155],
[255, 244, 159],
[255, 245, 163],
[255, 247, 166],
[255, 248, 170],
[255, 250, 174],
[255, 251, 178],
[255, 253, 182],
[255, 254, 186],
[255, 255, 190],
[255, 255, 194],
[255, 255, 198],
[255, 255, 202],
[255, 255, 207],
[255, 255, 211],
[255, 255, 215],
[255, 255, 219],
[255, 255, 223],
[255, 255, 227],
[255, 255, 230],
[255, 255, 234],
[255, 255, 238],
[255, 255, 242],
[255, 255, 245],
[255, 255, 249],
[255, 255, 252],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
];
from PIL import Image
import numpy as np
import wave, math
import os, pickle
cols = np.array(colorscheme)
def nearest_color(x):
return np.argmin(np.linalg.norm(x - cols, axis=1))
im = np.array(Image.open("1200.png"))[:-1, ..., :3]
if not os.path.exists("save.pkl"):
spectro = np.apply_along_axis(nearest_color, -1, im)
pickle.dump(spectro, open("save.pkl", "wb"))
else:
spectro = pickle.load(open("save.pkl", "rb"))
print(spectro)
samples = 48000
actual_samples = samples * 4 # 4 seconds of audio time
print(im.shape)
spectro = spectro.transpose() # axis 0 is horizontal in image and axis 1 is vertical, probably
spectro = spectro.astype(np.float)
spectro -= spectro.min()
out = np.zeros(actual_samples)
ω = np.linspace(0, 10_000, num=im.shape[0]) * 2 * math.pi
for i in range(actual_samples):
index = i / actual_samples * (im.shape[1] - 1)
p, n = math.floor(index), math.ceil(index)
d = index - p
spec = spectro[p] * (1-d) + spectro[n] * d
θ = ω * (i / samples)
a = np.sin(θ * spec)
out[i] = sum(a)
if i % 1000 == 0: print(i)
print(out)
out /= max(out)
out *= 16384
print(out)
data = out.astype("<i2")
with wave.open("out.wav", "wb") as w:
w.setsampwidth(2)
w.setnchannels(1)
w.setframerate(samples)
w.writeframes(data.tobytes())