7

私はプログラミングと Python は初めてですが、現在の研究の多くは musicxml ファイルからのデータの抽出に関するものです。私は曲を持っていて、調号の一部を形成しない曲で発生する臨時記号の数を抽出したいと考えています。これを行う方法がわかりません。誰か助けてください。これは、私が見ている musicxml ファイルからの 1 つのメジャーの例です。

<measure number='19'>
        <print new-system='no'/>
        <note>
            <rest/>
            <duration>768</duration>
            <voice>1</voice>
            <type>quarter</type>
            <staff>1</staff>
        </note>
        <backup>
            <duration>768</duration>
        </backup>
        <note>
            <pitch>
                <step>E</step>
                <octave>4</octave>
            </pitch>
            <duration>2304</duration>
            <tie type='start'/>
            <voice>2</voice>
            <type>half</type>
            <dot/>
            <staff>1</staff>
            <notations>
                <tied type='start'/>
                <slur type='stop' number='1'/>
            </notations>
        </note>
        <backup>
            <duration>1536</duration>
        </backup>
        <note>
            <pitch>
                <step>E</step>
                <alter>3</alter>
                <octave>3</octave>
            </pitch>
            <duration>1536</duration>
            <voice>1</voice>
            <type>half</type>
            <staff>1</staff>
        </note>
        <note>
            <chord/>
            <pitch>
                <step>G</step>
                <alter>4</alter>
                <octave>3</octave>
            </pitch>
            <duration>1536</duration>
            <voice>1</voice>
            <type>half</type>
            <staff>1</staff>
        </note>
        <backup>
            <duration>2304</duration>
        </backup>
        <note>
            <pitch>
                <step>E</step>
                <octave>2</octave>
            </pitch>
            <duration>2304</duration>
            <voice>5</voice>
            <type>half</type>
            <dot/>
            <staff>2</staff>
        </note>
    </measure>

この問題は、musicxml ファイルを検索して回数を数えることに変換されます。

<pitch>
   <step>*</step>
   <alter>**</alter>
       ...

<alter>* が (F または C) ではない場所で発生し、* が F または C であり、タグが続かない回数も検出します。

どんな助けやアドバイスも大歓迎です!

4

2 に答える 2

8

Python の詳細についてはお答えできませんが、MusicXML 関連の提案が 2 つあります。

1)あなたの質問は臨時記号で表現されていますが、コードは変更要素に焦点を当てています。alter 要素はピッチの変更に使用されます。臨時要素は、書かれた臨時記号に使用されるものです。どれをお探しですか?音の量と記譜法での表示方法の二重性は、MusicXML では一般的であり、MusicXML ファイルで研究を行うために理解することが重要です。

2) プログラミングと Python を初めて使用する場合は、MusicXML を適切にサポートする、音楽学専用に設計された高レベルのツールキットを使用することをお勧めします。問題のドメインをより高いレベルに移動すると、進歩がはるかに速くなります. これに対する明らかな選択は、同じく Python で記述された music21 ツールキットです。http://web.mit.edu/music21/にはさらに多くの情報があります。

研究頑張ってください!

于 2013-02-01T07:17:26.887 に答える
3

Python には、xml ファイルをすばやくナビゲートできるxml.domモジュールがあります。Web 開発の経験があれば、それは JavaScript のドキュメント オブジェクト モデルに非常に似ています。

from xml.dom.minidom import parse, parseString

def get_step(note):
    stepNode = note.getElementsByTagName("step")[0]
    #get the text from the Text Node within the <step>,
    #and convert it from unicode to ascii
    return str(stepNode.childNodes[0].nodeValue)

def get_alter(note):
    alters = note.getElementsByTagName("alter")
    if len(alters) == 0:
        return None
    return alters[0]

def is_rest(note):
    return len(note.getElementsByTagName("rest")) > 0

def is_accidental(note):
    return get_alter(note) != None

dom = parse("data.xml")

notes = dom.getElementsByTagName("note")
#rests don't have steps or alters, so we don't care about them. Filter them out.
notes = filter(lambda note: not is_rest(note), notes)

#compile a list of notes of all accidentals (notes with <alter> tags)
accidentals = filter(is_accidental, notes)
#remove notes that are F or C
accidentals_that_are_not_f_or_c = filter(lambda note: get_step(note) not in ["F", "C"], accidentals)

#compile a list of notes that don't contain the alter tag
non_accidentals = filter(lambda note: not is_accidental(note), notes)
#remove notes that are not F or C
non_accidentals_that_are_f_or_c = filter(lambda note: get_step(note) in ["F", "C"], non_accidentals)

print "Accidental notes that are not F or C:"
if len(accidentals_that_are_not_f_or_c) == 0:
    print "(None found)"
else:
    for note in accidentals_that_are_not_f_or_c:
        print get_step(note)

print "Non-accidental notes that are F or C:"
if len(non_accidentals_that_are_f_or_c) == 0:
    print "(None found)"
else:
    for note in non_accidentals_that_are_f_or_c:
        print get_step(note), get_step(note) in ["F", "C"]

出力:

Accidental notes that are not F or C:
E
G
Non-accidental notes that are F or C:
(None found)
于 2013-01-30T13:09:03.097 に答える