Skip to content

Commit

Permalink
Merge pull request #1 from huang0h/working
Browse files Browse the repository at this point in the history
add vectorscope; back to work
  • Loading branch information
huang0h authored Aug 16, 2022
2 parents 82d5910 + 830ed35 commit f6b4e95
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
10 changes: 7 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# you might need to install these:
# pip install pydub
# pip install pygame
# pip install scipy
from pydub import AudioSegment
import pygame
from scipy import signal

import math
import sys
import numpy as np
import random

from star import Star
from nebula import Nebula
from oscilloscope import Oscilloscope
from vector import Vectorscope

# config vars - edit these to alter the visualizer
FILENAME = "audio/mightaswellbedead.wav"
FILENAME = "testaudio/sinetest.mp3"

WINDOW_SIZE = 400
HOP_SIZE = 100
Expand Down Expand Up @@ -99,7 +99,10 @@ def rand_color(base: int) -> pygame.Color:
RECORDING = False

oscope = Oscilloscope(screen, SCOPE_WIDTH, SCOPE_HEIGHT, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, MAX_AMP)
vscope = Vectorscope(screen, SCOPE_WIDTH, SCOPE_HEIGHT, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, MAX_AMP)

# visualizer still lags behind by small amounts - will investigate further
# current theory is that clock tick lags a bit while music plays uninterrupted
while total_elapsed * smp_per_second + WINDOW_SIZE < NUM_SAMPLES and RUNNING:
for event in pygame.event.get():
if event.type == pygame.QUIT:
Expand Down Expand Up @@ -173,6 +176,7 @@ def rand_color(base: int) -> pygame.Color:
neb.draw()

oscope.draw(window)
vscope.draw(left_win, right_win, 10)

pygame.display.flip()

Expand Down
38 changes: 34 additions & 4 deletions vector.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import pygame
import math
import numpy as np
import scipy
from scipy import signal

# vectorscope based off of Wave Candy's vectorscope
class Vectorscope:
def __init__(self, screen, width, height, x, y, max_amp):
self.screen = screen
Expand All @@ -13,9 +18,33 @@ def draw(self, left_samples, right_samples, resolution):
# x is determined by proportion of magnitude on left/right
# i.e. 100% of signal left = max on left axis
# y is determined by ??? - needs more experimentation
pass

def samples_to_hsla(samples: list) -> pygame.Color:
# split the left, right samples into indivudal windows, based on resolution, and get their averages
left_windows = np.split(np.array(left_samples), np.arange(resolution, len(left_samples), resolution))[:-1]
right_windows = np.split(np.array(right_samples), np.arange(resolution, len(right_samples), resolution))[:-1]

left_windows = list(map(lambda l: np.sum(l) / len(l), left_windows))
right_windows = list(map(lambda l: np.sum(l) / len(l), right_windows))

points = []
for left_avg, right_avg in zip(left_windows, right_windows):
l_x = self.x - (self.width / 2) * (left_avg / self.max_amp)
l_y = self.y - (self.height / 2) * (left_avg / self.max_amp)

r_x = self.x + (self.width / 2) * (right_avg / self.max_amp)
r_y = self.y - (self.height / 2) * (right_avg / self.max_amp)

l_prop = abs(left_avg / (abs(left_avg) + abs(right_avg)))
r_prop = abs(right_avg / (abs(left_avg) + abs(right_avg)))
points.append( ( l_x * l_prop + r_x * r_prop, l_y * l_prop + r_y * r_prop ) )

color = pygame.Color(255, 0, 0) #self.samples_to_hsla(list(map(lambda l, r: l + r / 2, left_samples, right_samples)))

for point in points:
pygame.draw.circle(self.screen, color, point, 5, 1)


def samples_to_hsla(self, samples: list) -> pygame.Color:
color: pygame.Color = pygame.Color(0, 0, 0)
window = signal.windows.blackmanharris(10000)

Expand All @@ -27,5 +56,6 @@ def samples_to_hsla(samples: list) -> pygame.Color:
return color

# formula adapted from https://en.wikipedia.org/wiki/Piano_key_frequencies
hue: int = math.ceil(41.9 * math.log(freq / 440, 2) + 171.11)
# saturation = rms(samples)
hue = math.ceil(41.9 * math.log(freq / 440, 2) + 171.11)
color.hsla = (hue, 100, 100, 100)
return color

0 comments on commit f6b4e95

Please sign in to comment.