From 780a425fafbc0f67a6682ad93c58f18d56580971 Mon Sep 17 00:00:00 2001 From: Louis Bigo Date: Thu, 18 Nov 2021 13:11:51 +0100 Subject: [PATCH] solves #778 --- music21/musicxml/m21ToXml.py | 10 ++++++++++ music21/musicxml/xmlToM21.py | 13 +++++++++++++ music21/tablature.py | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/music21/musicxml/m21ToXml.py b/music21/musicxml/m21ToXml.py index 48bcc35b5a..e9d87851d5 100644 --- a/music21/musicxml/m21ToXml.py +++ b/music21/musicxml/m21ToXml.py @@ -6062,6 +6062,16 @@ def staffLayoutToXmlStaffDetails(self, staffLayout): mxStaffLines.text = str(staffLayout.staffLines) # TODO: staff-tuning + if hasattr(staffLayout, 'fretboard'): + tuning_pitches = staffLayout.fretboard.tuning + for i in range(len(tuning_pitches)): + mxStaffTuning = SubElement(mxStaffDetails, 'staff-tuning') + mxStaffTuning.set('line', str(i + 1)) + mxTuningStep = SubElement(mxStaffTuning, 'tuning-step') + mxTuningStep.text = tuning_pitches[i].name + mxTuningOctave = SubElement(mxStaffTuning, 'tuning-octave') + mxTuningOctave.text = str(tuning_pitches[i].octave) + # TODO: capo # TODO: staff-size return mxStaffDetails diff --git a/music21/musicxml/xmlToM21.py b/music21/musicxml/xmlToM21.py index e0b02c7135..ba262e9354 100644 --- a/music21/musicxml/xmlToM21.py +++ b/music21/musicxml/xmlToM21.py @@ -5691,7 +5691,20 @@ def xmlStaffLayoutFromStaffDetails( stl.staffType = stream.enums.StaffType(xmlText) except ValueError: environLocal.warn(f'Got an incorrect staff-type in details: {mxStaffType}') + # TODO: staff-tuning* + mxStaffTuning = mxDetails.findall('staff-tuning') + if mxStaffTuning is not None: + tuning_pitches = [] + for i in range(len(mxStaffTuning)): + staff_tuning = mxStaffTuning[i] + line = int(staff_tuning.get('line')) + tuning_step = staff_tuning.find('tuning-step').text + tuning_octave = int(staff_tuning.find('tuning-octave').text) + tuning_pitches.append(pitch.Pitch(tuning_step + str(tuning_octave))) + fretboard = tablature.FretBoard.getFretBoardFromTuning(tuning_pitches) + setattr(stl, 'fretboard', fretboard) + # TODO: capo # TODO: show-frets # TODO: print-spacing diff --git a/music21/tablature.py b/music21/tablature.py index e96b64eb0c..5d0aa58743 100644 --- a/music21/tablature.py +++ b/music21/tablature.py @@ -244,6 +244,13 @@ def getPitches(self): return pitchList + @staticmethod + def getFretBoardFromTuning(pitches): + standard_fret_boards = [GuitarFretBoard, UkeleleFretBoard, BassGuitarFretBoard, MandolinFretBoard] + for standard_fret_board in standard_fret_boards: + if pitches == standard_fret_board().tuning: + return standard_fret_board() + return CustomFretBoard(pitches) class FirstFret: ''' @@ -344,6 +351,17 @@ def __init__(self, fretNotes=None, displayFrets=4): super().__init__(numStrings, fretNotes, displayFrets) self.tuning = [pitch.Pitch('G3'), pitch.Pitch('D4'), pitch.Pitch('A4'), pitch.Pitch('E5')] + +class CustomFretBoard(FretBoard): + ''' + A custom fretboard tuned with any list of pitches + ''' + + def __init__(self, pitches, fretNotes=None, displayFrets=4): + numStrings = len(pitches) + super().__init__(numStrings, fretNotes, displayFrets) + + self.tuning = pitches.copy() # ------------------------------------------------------------------------------