@@ -5473,11 +5473,18 @@ def articulationToXmlTechnical(self, articulationMark: articulations.Articulatio
54735473 >>> mxOther = MEX.articulationToXmlTechnical(g)
54745474 >>> MEX.dump(mxOther)
54755475 <other-technical>unda maris</other-technical>
5476+
5477+ Same with technical marks not yet supported.
5478+ TODO: support HammerOn, PullOff, Hole, Arrow.
5479+
5480+ >>> h = articulations.HammerOn()
5481+ >>> mxOther = MEX.articulationToXmlTechnical(h)
5482+ >>> MEX.dump(mxOther)
5483+ <other-technical />
54765484 '''
54775485 # these technical have extra information
54785486 # TODO: hammer-on
54795487 # TODO: pull-off
5480- # TODO: bend
54815488 # TODO: hole
54825489 # TODO: arrow
54835490 musicXMLTechnicalName = None
@@ -5489,7 +5496,7 @@ def articulationToXmlTechnical(self, articulationMark: articulations.Articulatio
54895496 musicXMLTechnicalName = 'other-technical'
54905497
54915498 # TODO: support additional technical marks listed above
5492- if musicXMLTechnicalName in ('bend' , ' hole' , 'arrow' ):
5499+ if musicXMLTechnicalName in ('hole' , 'arrow' ):
54935500 musicXMLTechnicalName = 'other-technical'
54945501
54955502 mxTechnicalMark = Element (musicXMLTechnicalName )
@@ -5523,7 +5530,10 @@ def articulationToXmlTechnical(self, articulationMark: articulations.Articulatio
55235530 if t .TYPE_CHECKING :
55245531 assert isinstance (articulationMark , articulations .FretIndication )
55255532 mxTechnicalMark .text = str (articulationMark .number )
5526-
5533+ if musicXMLTechnicalName == 'bend' :
5534+ if t .TYPE_CHECKING :
5535+ assert isinstance (articulationMark , articulations .FretBend )
5536+ self .setBend (mxTechnicalMark , articulationMark )
55275537 # harmonic needs to check for whether it is artificial or natural, and
55285538 # whether it is base-pitch, sounding-pitch, or touching-pitch
55295539 if musicXMLTechnicalName == 'harmonic' :
@@ -5539,6 +5549,67 @@ def articulationToXmlTechnical(self, articulationMark: articulations.Articulatio
55395549 # mxArticulations.append(mxArticulationMark)
55405550 return mxTechnicalMark
55415551
5552+ @staticmethod
5553+ def setBend (mxh : Element , bend : articulations .FretBend ) -> None :
5554+ '''
5555+ Sets the bend-alter SubElement and the pre-bend,
5556+ release and with-bar SubElements when present.
5557+
5558+ Called from articulationToXmlTechnical
5559+
5560+ >>> from xml.etree.ElementTree import Element
5561+ >>> from fractions import Fraction
5562+
5563+ >>> MEXclass = musicxml.m21ToXml.MeasureExporter
5564+
5565+ >>> a = articulations.FretBend(bendAlter=interval.Interval(2))
5566+ >>> mxh = Element('bend')
5567+ >>> MEXclass.setBend(mxh, a)
5568+ >>> MEXclass.dump(mxh)
5569+ <bend>
5570+ <bend-alter>2</bend-alter>
5571+ </bend>
5572+ >>> mxh = Element('bend')
5573+ >>> a = articulations.FretBend(bendAlter=interval.Interval(2))
5574+ >>> a.preBend = True
5575+ >>> MEXclass.setBend(mxh, a)
5576+ >>> MEXclass.dump(mxh)
5577+ <bend>
5578+ <bend-alter>2</bend-alter>
5579+ <pre-bend />
5580+ </bend>
5581+ >>> mxh = Element('bend')
5582+ >>> a = articulations.FretBend(bendAlter=interval.Interval(-2), release=Fraction(1, 10080))
5583+ >>> MEXclass.setBend(mxh, a)
5584+ >>> MEXclass.dump(mxh)
5585+ <bend>
5586+ <bend-alter>-2</bend-alter>
5587+ <release offset="1" />
5588+ </bend>
5589+ >>> mxh = Element('bend')
5590+ >>> a = articulations.FretBend(bendAlter=interval.Interval(-2), withBar='scoop')
5591+ >>> MEXclass.setBend(mxh, a)
5592+ >>> MEXclass.dump(mxh)
5593+ <bend>
5594+ <bend-alter>-2</bend-alter>
5595+ <with-bar>scoop</with-bar>
5596+ </bend>
5597+ '''
5598+ bendAlterSubElement = SubElement (mxh , 'bend-alter' )
5599+ alter = bend .bendAlter
5600+ if alter is not None :
5601+ bendAlterSubElement .text = str (alter .semitones )
5602+ if bend .preBend :
5603+ SubElement (mxh , 'pre-bend' )
5604+ if bend .release is not None :
5605+ releaseSubElement = SubElement (mxh , 'release' )
5606+ quarterLengthValue = bend .release
5607+ divisionsValue = int (defaults .divisionsPerQuarter * quarterLengthValue )
5608+ releaseSubElement .set ('offset' , str (divisionsValue ))
5609+ if bend .withBar is not None :
5610+ withBarSubElement = SubElement (mxh , 'with-bar' )
5611+ withBarSubElement .text = str (bend .withBar )
5612+
55425613 @staticmethod
55435614 def setHarmonic (mxh : Element , harm : articulations .StringHarmonic ) -> None :
55445615 # noinspection PyShadowingNames
0 commit comments