不懂乐理,也能扒谱,基于openvpi将mp3转换为midi乐谱(Python3.10)

所谓"扒谱"是指通过听歌或观看演奏视频等方式,逐步分析和还原音乐作品的曲谱或乐谱的过程。它是音乐学习和演奏的一种常见方法,通常由音乐爱好者、乐手或学生使用。

在扒谱的过程中,人们会仔细聆听音乐作品,辨别和记录出各个音符、和弦、节奏等元素,并通过试错和反复推敲来逐渐还原出准确的曲谱或乐谱。这对于那些没有正式乐谱或想学习特定曲目的人来说,是一种有效的方式。

扒谱的目的是为了更好地理解和演奏音乐作品,从中学习技巧、乐曲结构和艺术表达等方面。但不懂乐理的人很难听出音符和音准,本次我们通过openvpi的开源项目some来直接针对mp3文件进行扒谱,将mp3转换为midi文件。

项目配置

首先我们来克隆项目:

复制代码
git clone https://github.com/openvpi/SOME.git

进入项目的目录some:

复制代码
cd some

接着下载项目的预训练模型:

复制代码
https://pan.baidu.com/s/1lVQcKP7ijTELslJNgoDqkQ?pwd=odsm

2stems模型放到项目的pretrained_models目录下。

ckpt模型放入项目的ckpt目录下。

如果没有ckpt和pretrained_models目录,请手动建立。

如下所示:

复制代码

├───ckpt

│ config.yaml

│ model_ckpt_steps_104000_simplified.ckpt

├───pretrained_models

│ └───2stems

│ ._checkpoint

│ checkpoint

│ model.data-00000-of-00001

│ model.index

│ model.meta

复制代码

如此,项目就配置好了。

背景音乐和人声分离

扒谱主要针对人声部分,所以需要spleeter的参与,关于spleeter,请参见:人工智能AI库Spleeter免费人声和背景音乐分离实践(Python3.10),囿于篇幅,这里不再赘述。

执行命令:

复制代码
spleeter separate -p spleeter:2stems -o ./output ./test.mp3

这里使用2stems模型已经在上文中进行下载,并且放置在项目的pretrained_models目录。

如果没有output目录,请手动建立,test.mp3为需要扒谱的音乐文件。

随后会将背景音乐accompaniment.wav和人声vocals.wav分别输出在项目的output目录:

复制代码
├───output  
│   └───test  
│           accompaniment.wav  
│           vocals.wav

人声去噪

一般情况下,分离后的人声可能还存在混音等噪音,会影响转换的效果。

这里使用noisereduce来进行降噪:

复制代码
pip install noisereduce

编写降噪代码:

复制代码
from scipy.io import wavfile  
import noisereduce as nr  
# load data  
rate, data = wavfile.read("./output/test/vocals.wav")  
# perform noise reduction  
reduced_noise = nr.reduce_noise(y=data, sr=rate)  
wavfile.write("./output/test/vocals.wav", rate, reduced_noise)

运行后会对vocals.wav人声文件进行降噪重写操作。

扒谱(wav转换midi)

接着运行命令进行转换:

复制代码
python infer.py --model ./ckpt/model_ckpt_steps_104000_simplified.ckpt --wav ./output/test/vocals.wav

程序返回:

复制代码
python infer.py --model ./ckpt/model_ckpt_steps_104000_simplified.ckpt --wav ./output/test/vocals.wav  
accumulate_grad_batches: 1, audio_sample_rate: 44100, binarization_args: {'num_workers': 0, 'shuffle': True}, binarizer_cls: preprocessing.MIDIExtractionBinarizer, binary_data_dir: data/some_ds_fixmel_spk3_aug8/binary,  
clip_grad_norm: 1, dataloader_prefetch_factor: 2, ddp_backend: nccl, ds_workers: 4, finetune_ckpt_path: None,  
finetune_enabled: False, finetune_ignored_params: [], finetune_strict_shapes: True, fmax: 8000, fmin: 40,  
freezing_enabled: False, frozen_params: [], hop_size: 512, log_interval: 100, lr_scheduler_args: {'min_lr': 1e-05, 'scheduler_cls': 'lr_scheduler.scheduler.WarmupLR', 'warmup_steps': 5000},  
max_batch_frames: 80000, max_batch_size: 8, max_updates: 10000000, max_val_batch_frames: 10000, max_val_batch_size: 1,  
midi_extractor_args: {'attention_drop': 0.1, 'attention_heads': 8, 'attention_heads_dim': 64, 'conv_drop': 0.1, 'dim': 512, 'ffn_latent_drop': 0.1, 'ffn_out_drop': 0.1, 'kernel_size': 31, 'lay': 8, 'use_lay_skip': True}, midi_max: 127, midi_min: 0, midi_num_bins: 128, midi_prob_deviation: 1.0,  
midi_shift_proportion: 0.0, midi_shift_range: [-6, 6], model_cls: modules.model.Gmidi_conform.midi_conforms, num_ckpt_keep: 5, num_sanity_val_steps: 1,  
num_valid_plots: 300, optimizer_args: {'beta1': 0.9, 'beta2': 0.98, 'lr': 0.0001, 'optimizer_cls': 'torch.optim.AdamW', 'weight_decay': 0}, pe: rmvpe, pe_ckpt: pretrained/rmvpe/model.pt, permanent_ckpt_interval: 40000,  
permanent_ckpt_start: 200000, pl_trainer_accelerator: auto, pl_trainer_devices: auto, pl_trainer_num_nodes: 1, pl_trainer_precision: 32-true,  
pl_trainer_strategy: auto, raw_data_dir: [], rest_threshold: 0.1, sampler_frame_count_grid: 6, seed: 114514,  
sort_by_len: True, task_cls: training.MIDIExtractionTask, test_prefixes: None, train_set_name: train, units_dim: 80,  
units_encoder: mel, units_encoder_ckpt: pretrained/contentvec/checkpoint_best_legacy_500.pt, use_buond_loss: True, use_midi_loss: True, val_check_interval: 4000,  
valid_set_name: valid, win_size: 2048  
| load 'model' from 'ckpt\model_ckpt_steps_104000_simplified.ckpt'.  
100%|████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.66it/s]  
MIDI file saved at: 'output\test\vocals.mid'

转换好的钢琴旋律midi文件存放在output目录下,直接双击播放即可,也可以通过代码进行播放:

复制代码
''' pg_midi_sound101.py  
play midi music files (also mp3 files) using pygame  
tested with Python273/331 and pygame192 by vegaseat  
'''  
import pygame as pg  
def play_music(music_file):  
  '''  
  stream music with mixer.music module in blocking manner  
  this will stream the sound from disk while playing  
  '''  
  clock = pg.time.Clock()  
  try:  
    pg.mixer.music.load(music_file)  
    print("Music file {} loaded!".format(music_file))  
  except pygame.error:  
    print("File {} not found! {}".format(music_file, pg.get_error()))  
    return  
  pg.mixer.music.play()  
  # check if playback has finished  
  while pg.mixer.music.get_busy():  
    clock.tick(30)  
# pick a midi or MP3 music file you have in the working folder  
# or give full pathname  
music_file = r"D:\work\YiJianBaPu\output\test\vocals.mid"  
#music_file = "Drumtrack.mp3"  
freq = 44100  # audio CD quality  
bitsize = -16  # unsigned 16 bit  
channels = 2  # 1 is mono, 2 is stereo  
buffer = 2048  # number of samples (experiment to get right sound)  
pg.mixer.init(freq, bitsize, channels, buffer)  
# optional volume 0 to 1.0  
pg.mixer.music.set_volume(0.8)  
try:  
  play_music(music_file)  
except KeyboardInterrupt:  
  # if user hits Ctrl/C then exit  
  # (works only in console mode)  
  pg.mixer.music.fadeout(1000)  
  pg.mixer.music.stop()  
  raise SystemExit

结语

笔者在原项目的基础上进行了fork,添加了人声分离和降噪的功能,并且整合了预训练模型,与众乡亲同飨:

复制代码
https://github.com/v3ucn/YiJianBaPu
相关推荐
IT_陈寒4 小时前
React 18实战:7个被低估的Hooks技巧让你的开发效率提升50%
前端·人工智能·后端
数据智能老司机5 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
逛逛GitHub5 小时前
飞书多维表“独立”了!功能强大的超出想象。
人工智能·github·产品
机器之心5 小时前
刚刚,DeepSeek-R1论文登上Nature封面,通讯作者梁文锋
人工智能·openai
数据智能老司机6 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机6 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机6 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i6 小时前
drf初步梳理
python·django
每日AI新事件6 小时前
python的异步函数
python
这里有鱼汤7 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python