XML – DECODE https://decode.red/blog data decode, decoder or decoded ... design of code Mon, 15 Dec 2025 06:15:00 +0000 ja hourly 1 https://wordpress.org/?v=4.7.29 Music XML ../../../20190322967/ Thu, 21 Mar 2019 23:56:57 +0000 ../../../?p=967 音楽のスコアデータをあつかうXML形式ファイルの作成をプログラムでやってみました。
通常は楽譜印刷ソフトの入出力などで利用されるファイルですが、XMLファイルということでWebスクレイピングなどでよく使われるRubyのNokogiriというライブラリを使って、音符データを追加してみました。

https://ja.wikipedia.org/wiki/MusicXML
Wikipediaのコードを参考に下記をスケルトンとしてプログラムの入力に使いました。

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE score-partwise PUBLIC
     "-//Recordare//DTD MusicXML 1.1 Partwise//EN"
     "http://www.musicxml.org/dtds/partwise.dtd">
 <score-partwise>
   <part-list>
     <score-part id="part1">
       <part-name>Part1</part-name>
     </score-part>
   </part-list>
   <part id="part1">
     <measure number="1">
     </measure>
   </part>
 </score-partwise>

入力してXMLファイルの音符データを記述する部分に、音階をランダムで選択した音を追加していきます。

require "nokogiri"
file = File.open("skelton.xml")
xml = Nokogiri::XML(file)

note = Nokogiri::XML::Node::new('note',xml)
pitch = Nokogiri::XML::Node::new('pitch',xml)
step = Nokogiri::XML::Node::new('step',xml)
octave = Nokogiri::XML::Node::new('octave',xml)
duration = Nokogiri::XML::Node::new('duration',xml)
type = Nokogiri::XML::Node::new('type', xml)

pitch.add_child(step)
pitch.add_child(octave)
note.add_child(pitch)
note.add_child(duration)
note.add_child(type)

scale = "CDEFGAB"
measure = xml.at('/score-partwise/part/measure')
for n in 1..7 do
   step.content = scale.chars[rand(7)]
   octave.content = 4
   duration.content = 1
   type.content = "eighth"
   measure.add_child(note.to_xml)
end

File.open("score.xml", "w") do |file|
	file.puts Nokogiri::XML(xml.to_xml, nil, 'utf-8').to_xml
end

実際に楽譜印刷ソフト(ここでは定番のFinaleを使用)が出力するファイルはもっと情報が多いですが、最低限Finaleで表示する内容にして音符の生成することをに目的を絞っています。

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise>
   <part-list>
     <score-part id="part1">
       <part-name>Part1</part-name>
     </score-part>
   </part-list>
   <part id="part1">
     <measure number="1">
     <note>
  <pitch>
    <step>C</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>E</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>C</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>G</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>A</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>G</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
<note>
  <pitch>
    <step>B</step>
    <octave>4</octave>
  </pitch>
  <duration>1</duration>
  <type>eighth</type>
</note>
</measure>
   </part>
 </score-partwise>

measureというのは小節で、ここでは1小節のみ扱っています。拍子や記号、4分音符より細かい音符では旗の部分をまとめるbeamといったタグもありますが、ここでは省略しています。
(https://usermanuals.musicxml.com/MusicXML/Content/EL-MusicXML-beam.htm)

Music XMLのデータを見てみて、楽譜の表現のための情報量がいかに多いかを気付かされました。

]]>