Spaces:
Running
Running
from . import main as bm | |
from .main import _outputfilename | |
import json | |
def _safer_eval(string:str) -> float: | |
if isinstance(string, str): | |
#print(''.join([i for i in string if i.isdecimal() or i in '.+-*/'])) | |
string = eval(''.join([i for i in string if i.isdecimal() or i in '.+-*/'])) | |
return string | |
with open("presets.json", "r") as f: | |
presets=f.read() | |
presets=json.loads(presets) | |
def _song_copy(audio:bm.song): | |
return bm.song(path=audio.path, audio=audio.audio, samplerate=audio.samplerate, bmap=audio.beatmap, caching=audio.caching, filename=audio.filename, copied=True) | |
def _normalize(song: bm.song, beat, pattern=None, scale=None, shift=None): | |
beat=beat.lower() | |
if pattern is not None: | |
if scale is None: scale=1 | |
if shift is None: shift=0 | |
song.quick_beatswap(output=None, pattern=pattern, scale=scale,shift=shift) | |
elif beat=='normal' or beat is None: pass | |
elif beat=='shifted': song.quick_beatswap(output=None, pattern='1,2,3,4,5,7,6,8', scale=0.5) | |
elif beat=='shifted2': song.quick_beatswap(output=None, pattern='1,2,3,4,5,6,8,7', scale=0.5) | |
else: print(f"'{beat}' is not a valid beat") | |
return song | |
def lib_test(filename,output='', samplerate=44100, lib='madmom.BeatDetectionProcessor', scale=1, shift=0,beat='normal', log=False): | |
'''basically a way to quickly test scale and offset''' | |
if type(filename)==str : | |
song=bm.song(filename) | |
samplerate=song.samplerate | |
else: | |
song=filename | |
if beat!='normal' and beat is not None: song=_normalize(song=song, beat=beat, scale=scale, shift=shift) | |
song.quick_beatswap(output=None, pattern='test', scale=scale, shift=shift, log=log) | |
if beat!='normal' and beat is not None: song=_normalize(song=song, beat=beat, scale=scale, shift=shift) | |
song.write_audio(output=bm.outputfilename('', song.filename, f' ({lib} x{scale} {shift})')) | |
def lib_test_full(filename,samplerate, log): | |
'''A way to test all beat detection modules to see which one performs better.''' | |
print(filename) | |
lib_test(filename, samplerate,'madmom.BeatDetectionProcessor', log=log) | |
lib_test(filename, samplerate,'madmom.BeatDetectionProcessor.consistent', log=log) | |
#lib_test(filename, samplerate,'madmom.BeatTrackingProcessor') # better for live performances with variable BPM | |
#lib_test(filename, samplerate,'madmom.BeatTrackingProcessor.constant') # results identical to madmom.BeatDetectionProcessor | |
lib_test(filename, samplerate,'madmom.BeatTrackingProcessor.consistent', log=log) | |
lib_test(filename, samplerate,'madmom.CRFBeatDetectionProcessor', log=log) | |
lib_test(filename, samplerate,'madmom.CRFBeatDetectionProcessor.constant',log=log) | |
#lib_test(filename, samplerate,'madmom.DBNBeatTrackingProcessor') # better for live performances with variable BPM | |
lib_test(filename, samplerate,'madmom.DBNBeatTrackingProcessor.1000',log=log) | |
lib_test(filename, samplerate,'madmom.DBNDownBeatTrackingProcessor',log=log) | |
import gc | |
gc.collect() | |
def _process_list(something)-> list: | |
if isinstance(something, int) or isinstance(something, float): something=(something,) | |
elif isinstance(something,list): False if isinstance(something[0],int) or isinstance(something[0],float) else list(_safer_eval(i) for i in something) | |
else: something=list(_safer_eval(i) for i in something.split(',')) | |
return something | |
def _process(song:bm.song, preset: str, scale:float, shift:float, random=False, every=False, log=True)->bm.song: | |
#print(preset) | |
if 'pattern' in preset: | |
shift=shift+(preset['shift'] if 'shift' in preset else 0) | |
# Scale can be a list and we either take one value or all of them | |
if 'scale' in preset: pscale=_process_list(preset['scale']) | |
else: pscale=(1,) | |
#input(pscale) | |
if random is True: | |
import random | |
pscale=random.choice(pscale) | |
elif every is True: | |
songs=[] | |
for i in pscale: | |
song2=_song_copy(song) | |
song2.quick_beatswap(output=None, pattern=preset['pattern'], scale=scale*i, shift=shift, log = log) | |
songs.append((song2, i)) | |
return songs | |
else: pscale=preset['scale_d'] if 'scale_d' in preset else pscale[0] | |
if every is False: song.quick_beatswap(output=None, pattern=preset['pattern'], scale=scale*pscale, shift=shift, log = log) | |
elif preset['type'] =='sidechain': | |
length=preset['sc length'] if 'sc length' in preset else 0.5 | |
curve=preset['sc curve'] if 'sc curve' in preset else 2 | |
vol0=preset['sc vol0'] if 'sc vol0' in preset else 0 | |
vol1=preset['sc vol1'] if 'sc vol1' in preset else 1 | |
from . import generate | |
sidechain=bm.open_audio(preset['sc impulse'])[0] if 'sc impulse' in preset else generate.sidechain(samplerate=song.samplerate, length=length, curve=curve, vol0=vol0, vol1=vol1, smoothing=40) | |
scale=scale*(preset['scale'] if 'scale' in preset else 1) | |
shift=shift+(preset['shift'] if 'shift' in preset else 0) | |
song.quick_sidechain(output=None, audio2=sidechain, scale=scale, shift=shift) | |
elif preset['type'] =='beatsample': | |
sample=preset['filename'] | |
scale=scale*(preset['scale'] if 'scale' in preset else 1) | |
shift=shift+(preset['shift'] if 'shift' in preset else 0) | |
song.quick_beatsample(output=None, filename2=sample, scale=scale, shift=shift) | |
return song | |
def use_preset(output:str,song: str, preset: str, presets=presets, scale=1, shift=0, beat:str='normal', test=False, _normalize=True, random=False, every=False, log = True): | |
if not isinstance(song, bm.song): | |
song=bm.song(song) | |
else: song = _song_copy(song) | |
#print(song.samplerate) | |
if preset is None: | |
weights=[] | |
for i in presets.items(): | |
weights.append(i[1]['weight']) | |
import random | |
preset = random.choices(population=list(presets), weights=weights, k=1)[0] | |
name=preset | |
if isinstance(preset, str): preset=presets[preset] | |
if test is True: | |
testsong=_song_copy(song) | |
lib_test(testsong, output, samplerate=testsong.samplerate, log = log) | |
del testsong | |
#print(name, preset) | |
if _normalize is True and beat!='normal' and beat is not None: | |
if '_normalize' in preset: | |
if preset['_normalize'] is True: | |
song=_normalize(song, beat) | |
if '1' in preset: | |
for i in preset: | |
if type(preset[i])==dict:song=_process(song, preset[i], scale=scale, shift=shift, log=log) | |
else: song=_process(song, preset,scale=scale,shift=shift,random=random, every=every, log=log) | |
if isinstance(song, list): | |
for i in song: | |
i[0].write(output=_outputfilename(output, i[0].filename, suffix=f' ({name}{(" x"+str(round(i[1], 3)))*(len(song)>1)})')) | |
else: | |
out_folder = _outputfilename(output, song.filename, suffix=' ('+name+')') | |
song.write(output=out_folder) | |
return out_folder | |
def all(output:str,filename: str, presets:dict=presets, scale=1, shift=0, beat='normal', test=True, boring=False, effects=False, variations=False, log = False): | |
if boring is False: | |
for i in ['2x faster','3x faster','4x faster','8x faster','1.33x faster','1.5x faster','1.5x slower','reverse','random', 'syncopated effect']: | |
if i in presets: | |
#print(i) | |
presets.pop(i) | |
if not isinstance(filename, bm.song): song=bm.song(filename) | |
else: song=filename | |
song__normalized=_normalize(_song_copy(song), beat) | |
if test is True: | |
testsong=_song_copy(song) | |
lib_test(testsong, output, samplerate=testsong.samplerate, log = log) | |
del testsong | |
for key, i in presets.items(): | |
#print(key, i) | |
if 'scale' in i: | |
#print(i['scale']) | |
if isinstance(i['scale'], int) or isinstance(i['scale'], float): | |
if i['scale']<0.01: | |
continue | |
if effects is False: | |
if 'effect - ' in key: continue | |
if '_normalize' in i: | |
if i['_normalize'] is True: | |
song2=_song_copy(song__normalized) | |
else: song2=_song_copy(song) | |
else: song2=_song_copy(song) | |
use_preset(output, song2, preset=key, presets=presets, scale=scale, shift=shift, beat=beat, test=False, _normalize=False, every=variations, log = log) | |
# ___ my stuff ___ | |
# ___ get song ___ | |
#filename='F:/Stuff/Music/Tracks/Poseidon & Leon Ross - Parallax.mp3' | |
#filename = 'F:/Stuff/Music/Tracks/'+random.choice(os.listdir("F:\Stuff\Music\Tracks")) | |
# print(filename) | |
# ___ analyze+fix ___ | |
#scale, shift = 1,0 | |
#lib_test(filename, scale=scale, shift=shift) | |
#bm.fix_beatmap(filename, scale=scale, shift=shift) | |
# ___ presets ___ | |
#use_preset ('', filename, 'dotted kicks', scale=1, shift=0, beat='normal', test=False) | |
#use_preset ('', filename, None, scale=scale, shift=shift, test=False) | |
#all('', filename, scale=1, shift=0, beat='normal', test=False) | |
# ___ beat swap __ | |
#song=bm.song(filename) | |
#song.quick_beatswap(output='', pattern='test', scale=1, shift=0) | |
# ___ osu ___ | |
#song=bm.song() | |
#song.generate_hitmap() | |
#song.osu() | |
#song.hitsample() | |
# ___ saber2osu ___ | |
#import Saber2Osu as s2o | |
#osu=s2o.osu_map(threshold=0.3, declumping=100) | |
# ___ song to image ___ | |
#song.write_image() | |
# ___ randoms ___ | |
# while True: | |
# filename = 'F:/Stuff/Music/Tracks/'+random.choice(os.listdir("F:\Stuff\Music\Tracks")) | |
# use_preset ('', filename, None, scale=scale, shift=shift, test=False) | |
# ___ effects ___ | |
#song = bm.song(filename) | |
#song.audio=bm.pitchB(song.audio, 2, 100) | |
#song.write_audio(bm.outputfilename('',filename, ' (pitch)')) |