Compare commits

...
8 Commits
Author SHA1 Message Date
Saman-Salehizadeh e4f6f0c3a7 A little bug fixing. 2026-07-24 00:18:47 +03:30
Saman-Salehizadeh a015b7a30c Adding supplementary files saving system 2026-07-23 23:57:23 +03:30
Saman-Salehizadeh e658a63b44 PDF Copy Bigfix 2 2026-06-23 19:24:45 +03:30
Saman-Salehizadeh 17dca06952 Copy Bugfix 2026-06-23 19:09:26 +03:30
Saman-Salehizadeh 43027711d8 Update installation command in README 2026-06-12 22:04:50 +03:30
Saman-Salehizadeh 7c42df325d Update setup.py 2026-05-30 00:53:12 +03:30
Saman-Salehizadeh d5a34981c7 Update README.md 2026-05-29 03:01:43 +03:30
Saman-Salehizadeh 47b6bcec4a Update README.md 2026-05-29 03:01:04 +03:30
3 changed files with 61 additions and 23 deletions
+10 -1
View File
@@ -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
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.
+50 -21
View File
@@ -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 copy2
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,46 +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)
copy2(join(tmp,file_name+'.pdf'),output_path)
print(f"Notes PDF saved to {output_path}.")
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 {abspath(output_path)}.")
+1 -1
View File
@@ -1,7 +1,7 @@
from setuptools import setup,find_packages
setup(
name="Music_Mate",
version="0.1.0",
version="0.1.0a1",
packages=find_packages(),
install_requires=[
"imageio-ffmpeg==0.6.0",