8 Stimmen

Extrahieren von Informationen aus MusicXML

Ich bin neu in der Programmierung und Python, aber ein Großteil meiner aktuellen Forschung befasst sich mit der Extraktion von Daten aus Musicxml-Dateien. Ich habe ein Musikstück und möchte die Anzahl der Vorzeichen extrahieren, die in einem Stück vorkommen und nicht Teil der Tonart sind. Ich habe keine Ahnung, wie das geht, könnte mir bitte jemand helfen? Hier ist ein Beispiel für ein Takt aus der Musicxml-Datei, die ich mir anschaue:

            768
            1
            quarter
            1

            768

                E
                4

            2304

            2
            half

            1

            1536

                E
                3
                3

            1536
            1
            half
            1

                G
                4
                3

            1536
            1
            half
            1

            2304

                E
                2

            2304
            5
            half

            2

Das Problem besteht darin, durch die Musicxml-Datei zu suchen und die Anzahl der Male zu zählen, dass

   *
   **
       ...

vorkommt, wobei * nicht (F oder C) ist, und auch herauszufinden, wie oft * F oder C ist und nicht vom Tag gefolgt wird.

Jede Hilfe oder Ratschlag wäre sehr geschätzt!

8voto

Michael Punkte 725

Ich kann nicht bei Python-Details helfen, aber ich habe zwei MusicXML-bezogene Vorschläge:

1) Ihre Frage ist in Bezug auf Vorzeichen formuliert, aber Ihr Code konzentriert sich auf das ändern-Element. Das ändern-Element wird zur Tonhöhenänderung verwendet; das Vorzeichen-Element wird für geschriebene Vorzeichen verwendet. Welches davon suchen Sie? Die Dualität zwischen Klang und Notation ist in MusicXML häufig und wichtig zu verstehen, um Forschung mit MusicXML-Dateien durchzuführen.

2) Wenn Sie neu in der Programmierung und Python sind, würde ich empfehlen, ein höherwertiges Toolkit zu verwenden, das speziell für Musikwissenschaft mit guter MusicXML-Unterstützung konzipiert ist. Sie werden das Problemfeld auf eine höhere Ebene verschieben, was Ihnen ermöglichen sollte, viel schneller voranzukommen. Die offensichtliche Wahl dafür ist das music21-Toolkit, das auch in Python geschrieben ist. Weitere Informationen finden Sie unter http://web.mit.edu/music21/.

Viel Glück bei Ihrer Forschung!

3voto

Kevin Punkte 72013

Python hat ein xml.dom Modul, das es Ihnen erlaubt, schnell durch XML-Dateien zu navigieren. Wenn Sie Erfahrung mit der Webentwicklung haben, ist es sehr ähnlich zum Document Object Model von Javascript.

from xml.dom.minidom import parse, parseString

def get_step(note):
    stepNode = note.getElementsByTagName("step")[0]
    #den Text aus dem Textknoten innerhalb des  holen
    #und von Unicode in ASCII konvertieren
    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")
#Ruhezeichen haben keine steps oder alters, also ignorieren wir sie
notes = filter(lambda note: not is_rest(note), notes)

#eine Liste von Noten aller Vorzeichen (Noten mit  Tags) erstellen
accidentals = filter(is_accidental, notes)
#Noten entfernen, die F oder C sind
accidentals_that_are_not_f_or_c = filter(lambda note: get_step(note) not in ["F", "C"], accidentals)

#eine Liste von Noten erstellen, die das  Tag nicht enthalten
non_accidentals = filter(lambda note: not is_accidental(note), notes)
#Noten entfernen, die nicht F oder C sind
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"]

Ausgabe:

Akkidentalnoten, die nicht F oder C sind:
E
G
Nicht-Akkidentalnoten, die F oder C sind:
(None found)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X