diff --git a/music21/noteworthy/binaryTranslate.py b/music21/noteworthy/binaryTranslate.py index ffb5b68f32..045dcd9435 100644 --- a/music21/noteworthy/binaryTranslate.py +++ b/music21/noteworthy/binaryTranslate.py @@ -433,8 +433,11 @@ def parseHeader(self): self.skipBytes(1) def dumpToNWCText(self) -> t.List[str]: - infos = '|SongInfo|Title:' + self.title.decode('latin_1') - infos += '|Author:' + self.author.decode('latin_1') + infos = '' + if self.title: + infos += '|SongInfo|Title:' + self.title.decode('latin_1') + if self.author: + infos += '|Author:' + self.author.decode('latin_1') dumpObjects = [infos] for s in self.staves: staffDumpObjects = s.dump() @@ -489,7 +492,8 @@ def parse(self): def dump(self) -> t.List[str]: dumpObjects = [] - instruName = self.instrumentName if self.instrumentName else 'NoName' + # default to first midi instrument + instruName = self.instrumentName if self.instrumentName else 'Acoustic Grand Piano' label = self.label.decode('utf-8') if self.label else instruName staffString = '|AddStaff|Name:' + label @@ -498,7 +502,7 @@ def dump(self) -> t.List[str]: staffInstruString = '|StaffInstrument|Name:' + instruName if instruName in constants.MidiInstruments: staffInstruString += '|Patch:' - staffInstruString += str(constants.MidiInstruments.index(self.instrumentName)) + staffInstruString += str(constants.MidiInstruments.index(instruName)) staffInstruString += '|Trans:' + str(self.transposition) @@ -639,7 +643,7 @@ class NWCObject: ''' NWCObject class is an union that can be used for each type of object contained in a staff. - An object binary blob start with its type. + An object binary blob starts with its type. The parse() method calls the appropriate method depending on the object type. Each parsing method should set up the 'dumpMethod' method that return the nwctxt version of the object. @@ -814,18 +818,17 @@ def instrument(self): ''' p = self.parserParent self.type = 'Instrument' - p.skipBytes(8) # self.name = p.readToNUL() # p.skipBytes(1) - # p.skipBytes(8) # velocity + p.skipBytes(8) # velocity - def timeSignature(self): + def timeSig(self): ''' Time signature 6 bytes ''' p = self.parserParent - self.type = 'TimeSignature' + self.type = 'TimeSig' self.numerator = p.readLEShort() self.bits = p.readLEShort() self.denominator = 1 << self.bits @@ -969,7 +972,7 @@ def note(self): # in NWC, alteration is not specified for other octave if self.alterationStr == '': - self.alterationStr = self.parserParent.currentAlterations.get(self.pos % 7) + self.alterationStr = self.parserParent.currentAlterations.get(self.pos % 7, '') if self.alterationStr is None: self.alterationStr = '' self.parserParent.currentAlterations[self.pos % 7] = self.alterationStr @@ -1218,7 +1221,7 @@ def dump(inner_self): barline, # 2 ending, # 3 instrument, # 4 - timeSignature, # 5 + timeSig, # 5 tempo, # 6 dynamic, # 7 note, # 8 diff --git a/music21/noteworthy/translate.py b/music21/noteworthy/translate.py index 0b9aad9e52..c1e08d297d 100644 --- a/music21/noteworthy/translate.py +++ b/music21/noteworthy/translate.py @@ -60,7 +60,6 @@ from __future__ import annotations import unittest -import warnings from music21 import bar from music21 import chord @@ -70,7 +69,6 @@ from music21 import dynamics from music21 import environment from music21 import expressions -from music21.exceptions21 import InstrumentException from music21.exceptions21 import Music21Exception from music21 import instrument from music21 import interval @@ -492,10 +490,10 @@ def translateNote(self, attributes): if self.currentClef == 'PERCUSSION': n = note.Unpitched() - n.fromDisplayPitch(p) + n.displayStep = p.step + n.displayOctave = p.octave else: - n = note.Note() # note! - n.pitch = p + n = note.Note(p) # note! # durationInfo self.setDurationForObject(n, durationInfo) @@ -507,20 +505,20 @@ def translateNote(self, attributes): if self.lyrics and self.lyricPosition < len(self.lyrics): n.addLyric(self.lyrics[self.lyricPosition]) - self.getCurrentVoice().append(n) + self.getShortestStream().append(n) - # current voice has shorter duration. If no voices, return current measure - def getCurrentVoice(self): - voice = None - shorter = 999 - for item in self.currentMeasure: - if isinstance(item, stream.Voice): - d = item.quarterLength - if d < shorter: - voice = item - shorter = d + # Returns the shortest stream. It can be the shortest Voice + # or current measure if no voice. + def getShortestStream(self): + if self.currentMeasure.isFlat: + # O(1) in most cases. + return self.currentMeasure - return voice if voice is not None else self.currentMeasure + # O(n) only if voices already exist. + return min( + self.currentMeasure.getElementsByClass(stream.Voice), + key=lambda v: v.quarterLength + ) def translateChord(self, attributes): r''' @@ -542,27 +540,22 @@ def translateChord(self, attributes): ''' durationInfos = attributes['Dur'] pitchInfos = attributes['Pos'] - currentDuration = self.getCurrentVoice().duration + currentDuration = self.getShortestStream().duration isRestChord = 'Dur2' in attributes i = 0 def getVoiceAtDuration(inner_self, voiceId, dur): # first check if voice already exists in measure voice = None - hasVoice = False - for item in inner_self.currentMeasure: - if isinstance(item, stream.Voice): - hasVoice = True - if item.id == voiceId: - voice = item - break + voices = inner_self.currentMeasure.getElementsByClass(stream.Voice) + voice = voices.getElementById(voiceId) # otherwise create it if voice is None: voice = stream.Voice() voice.id = voiceId # if creating the first voice, add current measure contents to it - if not hasVoice: + if len(voices) == 0: notes = [] for item in inner_self.currentMeasure: if isinstance(item, note.GeneralNote): @@ -601,7 +594,7 @@ def getVoiceAtDuration(inner_self, voiceId, dur): c.addLyric(self.lyrics[self.lyricPosition]) if len(durationInfos) == 1 and isRestChord is not None: - self.getCurrentVoice().append(c) + self.getShortestStream().append(c) else: v = getVoiceAtDuration(self, i, currentDuration) v.append(c) @@ -640,7 +633,7 @@ def translateRest(self, attributes): r = note.Rest() self.setDurationForObject(r, durationInfo) - self.getCurrentVoice().append(r) + self.getShortestStream().append(r) def createClef(self, attributes): r'''