|
from multiprocessing import Process,Value,Queue |
|
from pydub import AudioSegment |
|
import logging |
|
|
|
""" |
|
A scrit that allow real time musique speed modification with calcul on another Proccess to avoid overloading the main boucle |
|
""" |
|
|
|
# method from https://stackoverflow.com/questions/51434897/how-to-change-audio-playback-speed-using-pydub |
|
def speed_change(sound:AudioSegment, speed=1.0): |
|
# Manually override the frame_rate. This tells the computer how many |
|
# samples to play per second |
|
sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={ |
|
"frame_rate": int(sound.frame_rate * speed) |
|
}) |
|
|
|
# convert the sound with altered frame rate to a standard frame rate |
|
# so that regular playback programs will work right. They often only |
|
# know how to play audio at standard frame rate (like 44.1k) |
|
return sound_with_altered_frame_rate.set_frame_rate(sound.frame_rate) |
|
|
|
musique_original = AudioSegment.from_file("Halloween LOOP.wav") |
|
|
|
sound_factor = Value('d',1) |
|
sound_offset = 500 |
|
|
|
Sounds_buffer = Queue(maxsize=2) # maxsize will be interfering with the update (less = more reactive but less resilient to lag) |
|
|
|
def generator(sound_buffer:Queue,factor:Value,offset:int=500): |
|
# var declaration |
|
musique_alternate = musique_original # current study of the musique |
|
player_offset = offset # offset of each sample |
|
max_occilation = 0.01 # max modification of speed between two sample (lesser => more faded) |
|
local_factor = factor.value # local factor of speed |
|
|
|
while True: |
|
if not Sounds_buffer.full(): # if the Queue is not full |
|
# if local factor need update |
|
if local_factor<factor.value: |
|
local_factor += max_occilation |
|
elif local_factor>factor.value: |
|
local_factor -= max_occilation |
|
|
|
if len(musique_alternate) > player_offset*local_factor: # check if we can take a normal sample in the study |
|
sample, musique_alternate = musique_alternate[:player_offset*local_factor], musique_alternate[player_offset*local_factor:] |
|
else: # else we just play what rest and loop the study back |
|
sample,musique_alternate = musique_alternate,musique_original |
|
|
|
_sample = speed_change(sample,local_factor) |
|
buffer = bytearray(_sample.raw_data) |
|
sound_buffer.put(buffer) # buffer send to the partaged Queue |
|
|
|
p = Process(target=generator,args=(Sounds_buffer,sound_factor,sound_offset),daemon=True) |
is it possible to check the framerate to see if you have previously changed the speed or not