如何从Midi文件中提取各个和弦,休止符和音符? [英] How to Extract Individual Chords, Rests, and Notes from a midi file?

查看:494
本文介绍了如何从Midi文件中提取各个和弦,休止符和音符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个程序,该程序应该能够从某个Midi文件中提取音符,休止符和和弦,并将音符和和弦的相应音高(以midi音调编号-从0-127到)写入到一个csv文件供以后使用.

I am making a program that should be able to extract the notes, rests, and chords from a certain midi file and write the respective pitch (in midi tone numbers - they go from 0-127) of the notes and chords to a csv file for later use.

对于这个项目,我正在使用Python库"Music21".

For this project, I am using the Python Library "Music21".

 from music21 import *
 import pandas as pd


 #SETUP

 path = r"Pirates_TheCarib_midi\1225766-Pirates_of_The_Caribbean_Medley.mid"

 #create a function for taking parsing and extracting the notes
 def extract_notes(path):
     stm = converter.parse(path)

     treble = stm[0] #access the first part (if there is only one part)
     bass = stm[1]

     #note extraction
     notes_treble = []
     notes_bass = []
     for thisNote in treble.getElementsByClass("Note"):
         indiv_note = [thisNote.name, thisNote.pitch.midi, thisNote.offset]
         notes_treble.append(indiv_note)  # print's the note and the note's 
         offset

     for thisNote in bass.getElementsByClass("Note"):
         indiv_note = [thisNote.name, thisNote.pitch.midi, thisNote.offset]
         notes_bass.append(indiv_note) #add the notes to the bass

     return notes_treble, notes_bass

 #write to csv
 def to_csv(notes_array):
     df = pd.DataFrame(notes_array, index=None, columns=None)
     df.to_csv("attempt1_v1.csv")

 #using the functions
 notes_array = extract_notes(path)
 #to_csv(notes_array)

 #DEBUGGING
 stm = converter.parse(path)
 print(stm.parts)

这是我正在用作测试分数的链接. https://musescore.com/user/1699036/scores/1225766

Here is the link to the score I am using as a test. https://musescore.com/user/1699036/scores/1225766

当我运行extract_notes函数时,它返回两个空数组和一行:

When I run the extract_notes function, it returns two empty arrays and the line:

print(stm.parts)

返回

<music21.stream.iterator.StreamIterator for Score:0x1b25dead550 @:0>

我对为什么这样做感到困惑.乐曲应分为高音和低音两部分.如何将每个音符,和弦和休止符放入一个数组,以便可以将其放入csv文件中?

I am confused as to why it does this. The piece should have two parts, treble and bass. How can I get each note, chord and rest into an array so I can put it in a csv file?

推荐答案

以下是我的操作摘要.我需要获取特定乐器的所有音符,和弦和休止符.因此,首先我遍历部分内容,找到了特定的乐器,然后检查它是哪种类型的笔记并附加它.

Here is small snippet how I did it. I needed to get all notes, chords and rests for specific instrument. So at first I iterated through part and found specific instrument and afterwards check what kind of type note it is and append it.

您可以像

notes = get_notes_chords_rests(keyboard_instruments, "Pirates_of_The_Caribbean.mid")

其中keyboard_instruments是乐器列表.

where keyboard_instruments is list of instruments.

keyboard_nstrument = ["KeyboardInstrument", "Piano", "Harpsichord", "Clavichord", "Celesta", ]

def get_notes_chords_rests(instrument_type, path):
    try:
        midi = converter.parse(path)
        parts = instrument.partitionByInstrument(midi)
        note_list = []
        for music_instrument in range(len(parts)):
            if parts.parts[music_instrument].id in instrument_type:
                for element_by_offset in stream.iterator.OffsetIterator(parts[music_instrument]):
                    for entry in element_by_offset:
                        if isinstance(entry, note.Note):
                            note_list.append(str(entry.pitch))
                        elif isinstance(entry, chord.Chord):
                            note_list.append('.'.join(str(n) for n in entry.normalOrder))
                        elif isinstance(entry, note.Rest):
                            note_list.append('Rest')
        return note_list
    except Exception as e:
        print("failed on ", path)
        pass

P.S.使用try块很重要,因为Web上的许多Midi文件已损坏.

P.S. It is important to use try block because a lot of midi files on the web are corrupted.

这篇关于如何从Midi文件中提取各个和弦,休止符和音符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆