diff --git a/music_mate/basic_converter.py b/music_mate/basic_converter.py index 32afe5f..48c6a7a 100644 --- a/music_mate/basic_converter.py +++ b/music_mate/basic_converter.py @@ -6,21 +6,23 @@ from noisereduce import reduce_noise from soundfile import write from basic_pitch.inference import predict_and_save, ICASSP_2022_MODEL_PATH from music21.midi import MidiFile, translate, environment -from os.path import splitext, basename, join, dirname +from os.path import splitext, basename, join, dirname, abspath, isdir from os import makedirs from lilypond import executable from tempfile import TemporaryDirectory -from shutil import copystat, copy +from shutil import copy from platform import system -lilypond_path=str(executable()) -if system()=="Windows" and not lilypond_path.lower().endswith('.exe'): - lilypond_path+='.exe' -us=environment.UserSettings() -us['lilypondPath']=lilypond_path #Main Function -def media_to_notes(input_path,output_path,lilypond_path=lilypond_path): - makedirs(dirname(output_path),exist_ok=True) +def media_to_notes(input_path,output_path): + supplementary_files=[] + lilypond_path=str(executable()) + if system()=="Windows" and not lilypond_path.lower().endswith('.exe'): + lilypond_path+='.exe' + us=environment.UserSettings() + us['lilypondPath']=lilypond_path + output_dir = dirname(abspath(output_path)) + makedirs(output_dir, exist_ok=True) file_extension=splitext(input_path)[1] file_name=splitext(basename(input_path))[0] @@ -28,51 +30,73 @@ def media_to_notes(input_path,output_path,lilypond_path=lilypond_path): with TemporaryDirectory() as tmp: #Correcting File Format if file_extension.lower()!='.wav': - run([get_ffmpeg_exe(),'-y','-i',input_path,join(tmp,file_name+'.wav')],check=True) wav_path=join(tmp,file_name+'.wav') + run([get_ffmpeg_exe(),'-y','-i',input_path,wav_path],check=True) + supplementary_files.append(wav_path) else: wav_path=input_path + #Noise Reduction y,sr=load(wav_path,sr=None,mono=True) - noise_reduced_music=reduce_noise(y=y,sr=sr,stationary=True,prop_decrease=0.6) - write(join(tmp,file_name+'_denoised.wav'),noise_reduced_music,sr) - + denoised_music=reduce_noise(y=y,sr=sr,stationary=True,prop_decrease=0.6) + denoised_music_path=join(tmp,file_name+'_denoised.wav') + write(denoised_music_path,denoised_music,sr) + supplementary_files.append(denoised_music_path) #Making The MIDI predict_and_save( - audio_path_list=[join(tmp,file_name+'_denoised.wav')], + audio_path_list=[denoised_music_path], output_directory=tmp, save_midi=True, sonify_midi=False, save_model_outputs=False, save_notes=True, model_or_model_path=ICASSP_2022_MODEL_PATH) + mid_path=join(tmp,file_name+'_denoised_basic_pitch.mid') + supplementary_files.append(mid_path) + supplementary_files.append(join(tmp,file_name+'_denoised_basic_pitch.csv')) #Making The Ly mf=MidiFile() - mf.open(join(tmp,file_name+'_denoised_basic_pitch.mid')) + mf.open(mid_path) mf.read() mf.close() s=translate.midiFileToStream(mf) - s.write('lily', fp=join(tmp,file_name+'.ly')) + ly_path=join(tmp,file_name+'.ly') + s.write('lily', fp=ly_path) + supplementary_files.append(ly_path) #Correcting The Layout - with open(join(tmp,file_name+'.ly'),'r',encoding='utf-8') as f: + with open(ly_path,'r',encoding='utf-8') as f: ly=f.read() if r'\include "lilypond-book-preamble.ly"' in ly: ly=ly.replace(r'\include "lilypond-book-preamble.ly"',rf'\include "{file_name}_wrapper.ly"') else: ly=rf'\include "{file_name}_wrapper.ly"'+'\n'+ly - with open(join(tmp,file_name+'_wrapper.ly'),'w',encoding='utf-8') as f: + wrapper_path=join(tmp,file_name+'_wrapper.ly') + with open(wrapper_path,'w',encoding='utf-8') as f: f.write(r'\header { tagline = ##f }') - with open(join(tmp,file_name+'.ly'),'w',encoding='utf-8') as f: + with open(ly_path,'w',encoding='utf-8') as f: f.write(ly) + supplementary_files.append(wrapper_path) #Making The PDF run([lilypond_path,"-I",tmp,"-o",join(tmp,file_name),join(tmp,file_name+'.ly')],check=True) - copy(join(tmp,file_name+'.pdf'),output_path) - try: - copystat(join(tmp,file_name+'.pdf'),output_path) - except: - pass - + pdf_path=join(tmp,file_name+'.pdf') + copy(pdf_path,output_path) + + #Saving The Supplementary Files + supplementary_user=input('Do you want the supplementary files (Y/n)? ').strip().lower() + while supplementary_user!='y' and supplementary_user!='n': + supplementary_user=input('Please answer with "Y" or "n":').strip().lower() + if supplementary_user=='y': + counter=0 + supplementary_dir=join(output_dir,'Supplementary Files') + while isdir(supplementary_dir): + counter+=1 + supplementary_dir=join(output_dir,f'Supplementary Files ({counter})') + makedirs(supplementary_dir) + for supplementary_file in supplementary_files: + destination=join(supplementary_dir,basename(supplementary_file)) + copy(supplementary_file,destination) + print(f"Supplementary files saved to {supplementary_dir}.") print(f"Notes PDF saved to {output_path}.")