Skip to content

Commit 07d5f6a

Browse files
committed
be quit!
1 parent f2ae378 commit 07d5f6a

9 files changed

Lines changed: 85 additions & 32 deletions

File tree

.DS_Store

0 Bytes
Binary file not shown.

.github/workflows/BuildMacARM64.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ jobs:
2929
- name: Install dependencies
3030
run: |
3131
python -m pip install --upgrade pip
32-
brew install raylib
32+
brew install portaudio
3333
pip install -r requirements.txt
34-
ln -s /opt/homebrew/lib/libraylib.5.5.0.dylib \
35-
/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/raylibpy/bin/64bit/
3634
3735
- name: Run tests
3836
run: |

Frameworks/.DS_Store

6 KB
Binary file not shown.

Frameworks/libraylib.5.5.0.dylib

-3.37 MB
Binary file not shown.

Frameworks/libraylib.550.dylib

Lines changed: 0 additions & 1 deletion
This file was deleted.

Frameworks/libraylib.a

-4.77 MB
Binary file not shown.

Frameworks/libraylib.dylib

Lines changed: 0 additions & 1 deletion
This file was deleted.

assets/.DS_Store

0 Bytes
Binary file not shown.

poo.py

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,96 @@
1+
#./assets/audio/(radzlan - Miami Hotline Vol.3 (feat. Demonicity)) 673473_-Miami-Hotline--Vol3.mp3
2+
import tkinter as tk
3+
from tkinter import filedialog
14
import pygame
5+
from pydub import AudioSegment
26
import numpy as np
3-
import scipy.signal
7+
from scipy.signal import resample
8+
import threading
9+
import time
410

5-
def resample_sound(sound, pitch_factor):
6-
# Extract raw sound buffer
7-
raw = pygame.sndarray.array(sound)
8-
9-
# Get the current shape
10-
num_samples = raw.shape[0]
11+
# Init Pygame
12+
sample_rate = 44100
13+
pygame.mixer.init(frequency=sample_rate, size=-16, channels=1)
1114

12-
# Calculate new length
13-
new_length = int(num_samples / pitch_factor)
15+
# Globals
16+
audio_data = None
17+
playing = False
18+
start_frame = 0
19+
frame_count = int(sample_rate * 0.1) # smaller chunks for smoother updates
20+
semitone_ratio = 2 ** (1 / 12)
1421

15-
# Resample using scipy
16-
resampled = scipy.signal.resample(raw, new_length)
22+
# Load audio
23+
def load_audio():
24+
global audio_data, start_frame
25+
file_path = filedialog.askopenfilename(filetypes=[("WAV files", "*.wav")])
26+
if not file_path:
27+
return
28+
audio = AudioSegment.from_file(file_path).set_channels(1).set_frame_rate(sample_rate)
29+
raw = np.array(audio.get_array_of_samples()).astype(np.float32)
30+
audio_data = raw
31+
start_frame = 0
32+
status_label.config(text=f"Loaded: {file_path.split('/')[-1]}")
33+
start_playback()
1734

18-
# Convert to int16 for pygame compatibility
19-
resampled = resampled.astype(np.int16)
35+
# Resample chunk with pitch shift
36+
def resample_audio(data, pitch_factor):
37+
new_len = int(len(data) / pitch_factor)
38+
return resample(data, new_len)
2039

21-
# Convert back to a Sound object
22-
return pygame.sndarray.make_sound(resampled)
40+
# Start playback
41+
def start_playback():
42+
global playing
43+
if audio_data is None:
44+
status_label.config(text="No audio loaded.")
45+
return
2346

24-
# --- Usage ---
25-
pygame.init()
26-
pygame.mixer.init(frequency=44100, size=-16, channels=2)
47+
if not playing:
48+
playing = True
49+
threading.Thread(target=play_loop, daemon=True).start()
2750

28-
# Load original sound
29-
original = pygame.mixer.Sound("./assets/audio/(radzlan - Miami Hotline Vol.3 (feat. Demonicity)) 673473_-Miami-Hotline--Vol3.wav")
51+
# Stop playback
52+
def stop_audio():
53+
global playing
54+
playing = False
55+
pygame.mixer.stop()
3056

31-
# Resample (e.g., 1.5x pitch and speed)
32-
new_sound = resample_sound(original, pitch_factor=1.5)
57+
# Main loop
58+
def play_loop():
59+
global start_frame
60+
while playing and start_frame < len(audio_data):
61+
semitone_step = semitone_slider.get()
62+
pitch_factor = 2 ** (semitone_step / 12)
3363

34-
# Play new sound
35-
new_sound.play()
64+
chunk = audio_data[start_frame:start_frame + frame_count]
65+
if len(chunk) == 0:
66+
break
3667

37-
# Keep program running while sound plays
38-
pygame.time.wait(int(new_sound.get_length() * 1000))
39-
pygame.quit()
68+
# Resample for pitch
69+
pitched = resample_audio(chunk, 1 / pitch_factor)
70+
pitched = np.clip(pitched, -32768, 32767).astype(np.int16)
71+
72+
sound = pygame.mixer.Sound(buffer=pitched.tobytes())
73+
sound.play()
74+
75+
time.sleep(len(pitched) / sample_rate)
76+
start_frame += frame_count
77+
78+
playing = False
79+
80+
# GUI
81+
root = tk.Tk()
82+
root.title("Live Pitch Shift Player")
83+
84+
load_btn = tk.Button(root, text="Load Audio", command=load_audio)
85+
load_btn.pack()
86+
87+
stop_btn = tk.Button(root, text="Stop", command=stop_audio)
88+
stop_btn.pack()
89+
90+
semitone_slider = tk.Scale(root, from_=-12, to=12, orient=tk.HORIZONTAL, label="Semitone Shift")
91+
semitone_slider.pack()
92+
93+
status_label = tk.Label(root, text="No audio loaded.")
94+
status_label.pack()
95+
96+
root.mainloop()

0 commit comments

Comments
 (0)