Compare commits
8
Commits
2dc85ea918
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f6f0c3a7 | ||
|
|
a015b7a30c | ||
|
|
e658a63b44 | ||
|
|
17dca06952 | ||
|
|
43027711d8 | ||
|
|
7c42df325d | ||
|
|
d5a34981c7 | ||
|
|
47b6bcec4a |
@@ -1,3 +1,12 @@
|
|||||||
|
# Music-Mate
|
||||||
|
Music-Mate is a python library that gets your voice or video and gives you its notes in a PDF.
|
||||||
|
To install it, run this prompt on terminal:
|
||||||
```bash
|
```bash
|
||||||
pip install git+git@github.com:Saman-Salehizadeh/Music_Mate.git
|
pip install git+https://github.com/Saman-Salehizadeh/Music_Mate.git
|
||||||
```
|
```
|
||||||
|
You can use this library as you see:
|
||||||
|
```python
|
||||||
|
import music_mate
|
||||||
|
music_mate.media_to_notes(input_path,output_path)
|
||||||
|
```
|
||||||
|
The accurancy is not very good in this version and it's suitable with basic instruments, but in the future versions it will have functions for piano, guitar, etc.
|
||||||
|
|||||||
@@ -6,21 +6,23 @@ from noisereduce import reduce_noise
|
|||||||
from soundfile import write
|
from soundfile import write
|
||||||
from basic_pitch.inference import predict_and_save, ICASSP_2022_MODEL_PATH
|
from basic_pitch.inference import predict_and_save, ICASSP_2022_MODEL_PATH
|
||||||
from music21.midi import MidiFile, translate, environment
|
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 os import makedirs
|
||||||
from lilypond import executable
|
from lilypond import executable
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from shutil import copy2
|
from shutil import copy
|
||||||
from platform import system
|
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
|
#Main Function
|
||||||
def media_to_notes(input_path,output_path,lilypond_path=lilypond_path):
|
def media_to_notes(input_path,output_path):
|
||||||
makedirs(dirname(output_path),exist_ok=True)
|
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_extension=splitext(input_path)[1]
|
||||||
file_name=splitext(basename(input_path))[0]
|
file_name=splitext(basename(input_path))[0]
|
||||||
|
|
||||||
@@ -28,46 +30,73 @@ def media_to_notes(input_path,output_path,lilypond_path=lilypond_path):
|
|||||||
with TemporaryDirectory() as tmp:
|
with TemporaryDirectory() as tmp:
|
||||||
#Correcting File Format
|
#Correcting File Format
|
||||||
if file_extension.lower()!='.wav':
|
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')
|
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:
|
else:
|
||||||
wav_path=input_path
|
wav_path=input_path
|
||||||
|
|
||||||
#Noise Reduction
|
#Noise Reduction
|
||||||
y,sr=load(wav_path,sr=None,mono=True)
|
y,sr=load(wav_path,sr=None,mono=True)
|
||||||
noise_reduced_music=reduce_noise(y=y,sr=sr,stationary=True,prop_decrease=0.6)
|
denoised_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_path=join(tmp,file_name+'_denoised.wav')
|
||||||
|
write(denoised_music_path,denoised_music,sr)
|
||||||
|
supplementary_files.append(denoised_music_path)
|
||||||
#Making The MIDI
|
#Making The MIDI
|
||||||
predict_and_save(
|
predict_and_save(
|
||||||
audio_path_list=[join(tmp,file_name+'_denoised.wav')],
|
audio_path_list=[denoised_music_path],
|
||||||
output_directory=tmp,
|
output_directory=tmp,
|
||||||
save_midi=True,
|
save_midi=True,
|
||||||
sonify_midi=False,
|
sonify_midi=False,
|
||||||
save_model_outputs=False,
|
save_model_outputs=False,
|
||||||
save_notes=True,
|
save_notes=True,
|
||||||
model_or_model_path=ICASSP_2022_MODEL_PATH)
|
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
|
#Making The Ly
|
||||||
mf=MidiFile()
|
mf=MidiFile()
|
||||||
mf.open(join(tmp,file_name+'_denoised_basic_pitch.mid'))
|
mf.open(mid_path)
|
||||||
mf.read()
|
mf.read()
|
||||||
mf.close()
|
mf.close()
|
||||||
s=translate.midiFileToStream(mf)
|
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
|
#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()
|
ly=f.read()
|
||||||
if r'\include "lilypond-book-preamble.ly"' in ly:
|
if r'\include "lilypond-book-preamble.ly"' in ly:
|
||||||
ly=ly.replace(r'\include "lilypond-book-preamble.ly"',rf'\include "{file_name}_wrapper.ly"')
|
ly=ly.replace(r'\include "lilypond-book-preamble.ly"',rf'\include "{file_name}_wrapper.ly"')
|
||||||
else:
|
else:
|
||||||
ly=rf'\include "{file_name}_wrapper.ly"'+'\n'+ly
|
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 }')
|
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)
|
f.write(ly)
|
||||||
|
supplementary_files.append(wrapper_path)
|
||||||
|
|
||||||
#Making The PDF
|
#Making The PDF
|
||||||
run([lilypond_path,"-I",tmp,"-o",join(tmp,file_name),join(tmp,file_name+'.ly')],check=True)
|
run([lilypond_path,"-I",tmp,"-o",join(tmp,file_name),join(tmp,file_name+'.ly')],check=True)
|
||||||
copy2(join(tmp,file_name+'.pdf'),output_path)
|
pdf_path=join(tmp,file_name+'.pdf')
|
||||||
print(f"Notes PDF saved to {output_path}.")
|
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 {abspath(output_path)}.")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from setuptools import setup,find_packages
|
from setuptools import setup,find_packages
|
||||||
setup(
|
setup(
|
||||||
name="Music_Mate",
|
name="Music_Mate",
|
||||||
version="0.1.0",
|
version="0.1.0a1",
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"imageio-ffmpeg==0.6.0",
|
"imageio-ffmpeg==0.6.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user