|
import io |
|
|
|
import numpy as np |
|
import pedalboard as pb |
|
import pydub |
|
import soundfile as sf |
|
import streamlit as st |
|
from audio_recorder_streamlit import audio_recorder |
|
|
|
|
|
def stretch(audio, factor): |
|
buffer = [] |
|
for s in audio: |
|
for _ in range(factor): |
|
buffer.append(s) |
|
return np.array(buffer) |
|
|
|
|
|
st.title("πΉ Sound Refukculator") |
|
|
|
audio = np.array([]) |
|
|
|
source = st.radio("Choose source", ["Microphone", "File upload"]) |
|
if source == "Microphone": |
|
audio_bytes = audio_recorder() |
|
if audio_bytes: |
|
audio, sr = sf.read(io.BytesIO(audio_bytes)) |
|
else: |
|
audio_bytes = st.file_uploader("Upload file") |
|
if audio_bytes: |
|
if audio_bytes.name.endswith("mp3"): |
|
audio = pydub.AudioSegment.from_mp3(audio_bytes) |
|
sr = audio.frame_rate |
|
audio = np.float32(audio.get_array_of_samples()) / 2**15 |
|
else: |
|
audio, sr = sf.read(audio_bytes) |
|
|
|
|
|
if audio.any(): |
|
st.write("Original sound:") |
|
st.audio(audio.T, sample_rate=sr) |
|
cols = st.columns(5) |
|
chunk_dividend = cols[0].slider("π« Chunkizer", 16, 128, step=16) |
|
prob = cols[1].slider("π€‘ Impredictidiblize", 0, 100, 0) |
|
stretch_factor = cols[2].slider("π§ Trollizer", 0, 10, 0) |
|
reps = cols[3].slider("π«£ Repetizer", 0, 1, 0) |
|
rev_size = cols[4].slider("π Hugermaker", 0.0, 0.09, 0.0) |
|
delay_macro = cols[0].slider("πͺ Spaceometer", 0.01, 0.09, 0.0) |
|
rounder = cols[1].slider("π€ Rounder", 0, 100, 0) |
|
pshift = cols[2].slider("π± Tonermaker", 0, 1, 0) |
|
reverse = cols[3].slider("π§Ά Revolver", 0, 1, 0) |
|
sr_factor = cols[4].slider("πββοΈ Chirpidize", 1, 16, 1) |
|
delay = pb.Pedalboard( |
|
[pb.Delay(delay_seconds=delay_macro, feedback=delay_macro * 5)] |
|
) |
|
reverb = pb.Pedalboard([pb.Reverb(room_size=rev_size)]) |
|
chorus = pb.Pedalboard([pb.Chorus(rate_hz=rounder)]) |
|
pshifter7 = pb.Pedalboard([pb.PitchShift(-7)]) |
|
pshifter3 = pb.Pedalboard([pb.PitchShift(-3)]) |
|
pshifter5 = pb.Pedalboard([pb.PitchShift(-5)]) |
|
pshifter12 = pb.Pedalboard([pb.PitchShift(-12)]) |
|
processed = [] |
|
chunk_dividend = sorted(np.random.randint(audio.shape[0], size=chunk_dividend)) |
|
for i, chunk in enumerate(np.array_split(audio, chunk_dividend)): |
|
chunk = ( |
|
stretch(chunk, stretch_factor) |
|
if np.random.randint(100) < prob and stretch_factor |
|
else chunk |
|
) |
|
chunk = ( |
|
reverb(chunk, sample_rate=sr, reset=False) |
|
if np.random.randint(100) < prob and rev_size |
|
else chunk |
|
) |
|
chunk = ( |
|
delay(chunk, sample_rate=sr, reset=False) |
|
if np.random.randint(100) < prob and delay_macro |
|
else chunk |
|
) |
|
chunk = ( |
|
chorus(chunk, sample_rate=sr, reset=False) |
|
if np.random.randint(100) < prob and rounder |
|
else chunk |
|
) |
|
chunk = ( |
|
pshifter7(chunk, sample_rate=sr, reset=True) |
|
if np.random.randint(100) < prob and pshift |
|
else chunk |
|
) |
|
chunk = ( |
|
pshifter3(chunk, sample_rate=sr, reset=True) |
|
if np.random.randint(100) < prob and pshift |
|
else chunk |
|
) |
|
chunk = ( |
|
pshifter5(chunk, sample_rate=sr, reset=True) |
|
if np.random.randint(100) < prob and pshift |
|
else chunk |
|
) |
|
chunk = ( |
|
pshifter12(chunk, sample_rate=sr, reset=True) |
|
if np.random.randint(100) < prob and pshift |
|
else chunk |
|
) |
|
chunk = np.concatenate([chunk, chunk]) if np.random.randint(100) < prob and reps else chunk |
|
chunk = np.flip(chunk) if np.random.randint(100) < prob and reverse else chunk |
|
processed += [s for s in chunk] |
|
|
|
processed = np.array(processed) |
|
reverb = pb.Pedalboard([pb.Reverb(room_size=0.3)]) |
|
|
|
compressor = pb.Pedalboard([pb.Limiter(threshold_db=-1)]) |
|
processed = compressor(processed, sr, reset=False) |
|
|
|
st.write("Refukculized sound:") |
|
st.audio(processed.T, sample_rate=sr * sr_factor) |
|
|