.. _usersGuide_54_extendingConverter: .. WARNING: DO NOT EDIT THIS FILE: AUTOMATICALLY GENERATED. PLEASE EDIT THE .py FILE DIRECTLY. User’s Guide, Chapter 54: Extending Converter with New Formats ============================================================== For this example, rather than importing \* from music21, we’ll just import the modules we need. If you’re developing a new SubConverter class just for yourself you can import everything, but if you’re thinking that you’d like to contribute your module back to music21 someday, it is important not to import \* since that will create circular imports. .. code:: ipython3 from music21 import converter, note, stream, meter We’ll create a dummy file format, ‘.sb’ or the ‘singlebeat’ format which consists solely of a string of letters A-G in groups of any length separated by spaces. A-G represents the pitch name (no accidentals), while all notes written conjunctly in a group are interpreted as evenly fitting within a quarter note. .. code:: ipython3 class SingleBeat(converter.subConverters.SubConverter): registerFormats = ('singlebeat',) # note the comma after the string registerInputExtensions = ('sb',) # these are single element tuples. # we will just define parseData for now and let the SubConverter base class # deal with loading data from files of type .sb and URLs ending in .sb for us. def parseData(self, strData, number=None): # movement number is ignored... ''' 'AB C' -> A-8th, B-8th, C-qtr ''' strDataList = strData.split() s = stream.Part() m = meter.TimeSignature('4/4') s.insert(0, m) for beat in strDataList: ql = 1.0/len(beat) for n in beat: nObj = note.Note(n) nObj.duration.quarterLength = ql s.append(nObj) self.stream = s.makeMeasures() Next we tell the converter module that our subConverter exists and can handle ‘singlebeat’/‘singleBeat’/‘.sb’ files. .. code:: ipython3 converter.registerSubConverter(SingleBeat) Now the format is ready to be used through converter.parse() on string data: .. code:: ipython3 s = converter.parse('CDC DE F GAGB GE C DEFED C', format='singleBeat') s.show('text') .. parsed-literal:: :class: ipython-result {0.0} {0.0} {0.0} {0.0} {0.3333} {0.6667} {1.0} {1.5} {2.0} {3.0} {3.25} {3.5} {3.75} {4.0} {0.0} {0.5} {1.0} {2.0} {2.2} {2.4} {2.6} {2.8} {3.0} {4.0} Or, singleBeat is now a custom header for parse: .. code:: ipython3 s = converter.parse('singleBeat: CDC DE F GAGB GE C DEFED C') s[-1][0] .. parsed-literal:: :class: ipython-result Or we can write out a file and read it in: .. code:: ipython3 from music21 import environment e = environment.Environment() fp = e.getTempFile('.sb') with open(fp, 'w') as f: f.write('CDC DE F GAGB GE C DEFED C') print(fp) .. parsed-literal:: :class: ipython-result /var/folders/qg/klchy5t14bb2ty9pswk6c2bw0000gn/T/music21/tmpowosgwxt.sb .. code:: ipython3 s2 = converter.parse(fp) s2.show('text') .. parsed-literal:: :class: ipython-result {0.0} {0.0} {0.0} {0.0} {0.0} {0.3333} {0.6667} {1.0} {1.5} {2.0} {3.0} {3.25} {3.5} {3.75} {4.0} {0.0} {0.5} {1.0} {2.0} {2.2} {2.4} {2.6} {2.8} {3.0} {4.0} If you want to be extra-safe, pass the format in with the parse .. code:: ipython3 s3 = converter.parse(fp, format='singleBeat') s3 .. parsed-literal:: :class: ipython-result SingleBeat will now appear in all places where fileformats are listed: .. code:: ipython3 from music21 import common common.findFormat('singleBeat') .. parsed-literal:: :class: ipython-result ('singlebeat', '.sb') We can cleanup what we’ve done (always be a good citizen) by calling ``converter.resetSubConverters``. .. code:: ipython3 converter.resetSubConverters() A demonstration of the singleBeat type (simplified a bit), but including a ``.write()`` call, can be found in the ``converter`` directory under the filename ``qmConverter.py``. Now that you have a system that can take in just about any format you can write a converter for, it’s time to get back to understanding the music that you have available to you. Meter is a concept that is far deeper than simple concepts like 4/4 or 6/8 would let on. To learn more about how to do metrical analysis, turn to :ref:`Chapter 55: Advanced Meter Topics `