music21.noteworthy.binaryTranslate¶
Attempts at reading pure .nwc files in music21
First will solve uncompressed .nwc then compressed .nwc
Thanks to Juria90 and the nwc2xml project for solving so many of the documentation problems. No part of this code is taken from that project, but this project would have been impossible without his work.
Translates .nwc into .nwctxt and then uses Jordi Guillen’s .nwctxt translator to go from there to music21.
BETA – does not work for many file elements and is untested.
Demo, showing the extent of problems. The measure numbers are not set. Lyrics are missing. Drum is still poorly handled. This is very beta. Much better would be to convert the file into .xml or .nwctxt first.
>>> c = converter.parse('/Users/Hildegard/Desktop/test1.nwc')
>>> c.show('text')
{0.0} <music21.metadata.Metadata object at ...>
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Violin 'Violin'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.TrebleClef>
{0.0} <music21.tempo.MetronomeMark animato Quarter=120>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note G>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note C>
{3.0} <music21.note.Note B>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.note.Note C>
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Violin 'Violin'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.TrebleClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note G>
{1.0} <music21.note.Note A>
{2.0} <music21.note.Note A>
{3.5} <music21.note.Note G>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.note.Note G>
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Viola 'Viola'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.AltoClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note D>
{2.0} <music21.note.Note C#>
{2.6667} <music21.note.Note D>
{3.3333} <music21.note.Note E>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.note.Note E>
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Violoncello 'Violoncello'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note G>
{1.0} <music21.note.Note F>
{2.0} <music21.note.Note E>
{3.0} <music21.note.Note G>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.note.Note C>
>>> c = converter.parse('/Users/Hildegard/Desktop/jingle1.nwc')
>>> c.show('text')
{0.0} <music21.metadata.Metadata object at 0x7fe8c0a5ffa0>
{0.0} <music21.stream.Part 0x7fe8c0920100>
{0.0} <music21.instrument.Piano 'Piano'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.expressions.TextExpression 'Lively'>
{0.0} <music21.expressions.TextExpression 'F'>
{0.0} <music21.clef.TrebleClef>
{0.0} <music21.tempo.MetronomeMark animato Quarter=120>
{0.0} <music21.key.KeySignature of 1 flat>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note A>
{1.0} <music21.note.Note A>
{2.0} <music21.note.Note A>
{3.0} <music21.note.Rest quarter>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.note.Note A>
{1.0} <music21.note.Note A>
{2.0} <music21.note.Note A>
{3.0} <music21.note.Rest quarter>
{8.0} <music21.stream.Measure 1 offset=8.0>
{0.0} <music21.note.Note A>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note F>
{3.5} <music21.note.Note G>
{12.0} <music21.stream.Measure 2 offset=12.0>
{0.0} <music21.note.Note A>
{3.0} <music21.note.Rest quarter>
{16.0} <music21.stream.Measure 3 offset=16.0>
{0.0} <music21.expressions.TextExpression 'Bb'>
{0.0} <music21.note.Note B->
{1.0} <music21.note.Note B->
{2.0} <music21.note.Note B->
{3.5} <music21.note.Note B->
{20.0} <music21.stream.Measure 4 offset=20.0>
{0.0} <music21.expressions.TextExpression 'F'>
{0.0} <music21.note.Note B->
{1.0} <music21.note.Note A>
{2.0} <music21.note.Note A>
{3.0} <music21.note.Note A>
{3.5} <music21.note.Note A>
{24.0} <music21.stream.Measure 5 offset=24.0>
{0.0} <music21.expressions.TextExpression 'G'>
{0.0} <music21.bar.Barline type=regular>
{0.0} <music21.note.Note A>
{1.0} <music21.note.Note G>
{2.0} <music21.note.Note G>
{3.0} <music21.note.Note A>
{28.0} <music21.stream.Measure 6 offset=28.0>
{0.0} <music21.expressions.TextExpression 'C7'>
{0.0} <music21.note.Note G>
{2.0} <music21.note.Note C>
{4.0} <music21.bar.Repeat direction=end>
{28.0} <music21.spanner.RepeatBracket 1
<music21.stream.Measure 5 offset=24.0><music21.stream.Measure 6 offset=28.0>>
{32.0} <music21.stream.Measure 7 offset=32.0>
{0.0} <music21.expressions.TextExpression 'C7'>
{0.0} <music21.bar.Barline type=regular>
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note B->
{3.0} <music21.note.Note G>
{36.0} <music21.stream.Measure 8 offset=36.0>
{0.0} <music21.expressions.TextExpression 'F'>
{0.0} <music21.note.Note F>
{3.0} <music21.note.Rest quarter>
{0.0} <music21.stream.Part 0x7fe8c0921660>
{0.0} <music21.instrument.Piano 'Piano'>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.BassClef>
{0.0} <music21.key.KeySignature of 1 flat>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.chord.Chord F3 A3 C4>
{4.0} <music21.stream.Measure 0 offset=4.0>
{0.0} <music21.chord.Chord F3 A3 C4>
{8.0} <music21.stream.Measure 1 offset=8.0>
{0.0} <music21.chord.Chord F3 A3 C4>
{12.0} <music21.stream.Measure 2 offset=12.0>
{0.0} <music21.chord.Chord F3 A3 C4>
{1.0} <music21.note.Rest quarter>
{2.0} <music21.chord.Chord F3 A3 C4>
{3.0} <music21.note.Rest quarter>
{16.0} <music21.stream.Measure 3 offset=16.0>
{0.0} <music21.chord.Chord F3 B-3 D4>
{20.0} <music21.stream.Measure 4 offset=20.0>
{0.0} <music21.chord.Chord F3 A3 C4>
{1.0} <music21.note.Rest quarter>
{2.0} <music21.note.Rest half>
{24.0} <music21.stream.Measure 5 offset=24.0>
{0.0} <music21.bar.Barline type=regular>
{0.0} <music21.chord.Chord G3 B3>
{2.0} <music21.note.Rest half>
{28.0} <music21.stream.Measure 6 offset=28.0>
{0.0} <music21.chord.Chord E3 B-3 C4>
{4.0} <music21.bar.Repeat direction=end>
{28.0} <music21.spanner.RepeatBracket 1
<music21.stream.Measure 5 offset=24.0><music21.stream.Measure 6 offset=28.0>>
{32.0} <music21.stream.Measure 7 offset=32.0>
{0.0} <music21.bar.Barline type=regular>
{0.0} <music21.chord.Chord E3 B-3 C4>
{1.0} <music21.note.Rest quarter>
{2.0} <music21.note.Rest half>
{36.0} <music21.stream.Measure 8 offset=36.0>
{0.0} <music21.chord.Chord F3 A3 C4>
{3.0} <music21.note.Rest quarter>
FontDict¶
- class music21.noteworthy.binaryTranslate.FontDict¶
NWCConverter¶
- class music21.noteworthy.binaryTranslate.NWCConverter(**keywords)¶
A converter object for binary .nwc files. Do not normally use directly; use converter.parse.
>>> nwcc = noteworthy.binaryTranslate.NWCConverter() >>> nwcc <music21.noteworthy.binaryTranslate.NWCConverter object at 0x...> >>> nwcc.fileContents b'' >>> nwcc.parsePosition 0 >>> nwcc.version # version of nwc file to be parsed 200 >>> nwcc.numberOfStaves 0 >>> nwcc.staves []
NWCConverter
methods
- NWCConverter.advanceToNotNUL(nul: bytes = b'\x00')¶
- NWCConverter.byteToInt(updateParsePosition=True)¶
changes a byte into an unsigned int (i.e., if the byte is > 127 then it’s subtracted from 256)
- NWCConverter.byteToSignedInt(updateParsePosition=True)¶
changes a byte into a signed int (i.e., if the byte is > 127 then it’s subtracted from 256)
- NWCConverter.dumpToNWCText() list[str] ¶
- NWCConverter.fileVersion(updateParsePosition=True)¶
- NWCConverter.isValidNWCFile(updateParsePosition=True) bool ¶
- NWCConverter.parse()¶
the main parse routine called by parseFile() or parseString()
- NWCConverter.parseFile(fp: Path | str)¶
Parse a file (calls .toStream)
>>> fp = '/Users/cuthbert/desktop/cuthbert_test1.nwc' >>> nwcc = noteworthy.binaryTranslate.NWCConverter() >>> nwcc.fileContents b'' >>> streamObj = nwcc.parseFile(fp) >>> len(nwcc.fileContents) # binary 1139 >>> nwcc.fileContents[0:80] b'[NoteWorthy ArtWare]\x00\x00\x00[NoteWorthy Composer]\x00\x01\x02\x02\x00\x00\x00N/A\x000_JldRQMSKq6M5a3FQqK_g\x00\x00\x00' >>> streamObj <music21.stream.Score ...>
- NWCConverter.parseHeader() None ¶
Sets a ton of information from the header, and advances the parse position.
- NWCConverter.parseString(bytesIn: bytes = b'')¶
same as parseFile but takes a string (in Py3, bytes) of binary data instead.
- NWCConverter.readBytes(bytesToRead=1, updateParsePosition=True) bytes ¶
reads the next bytesToRead bytes and then (optionally) updates self.parsePosition
- NWCConverter.readLEShort(updateParsePosition=True)¶
Helper module: read a little-endian short value to an integer
>>> nwcc = noteworthy.binaryTranslate.NWCConverter() >>> nwcc.fileContents = b'' >>> nwcc.parsePosition 0 >>> nwcc.readLEShort() 258 >>> nwcc.parsePosition 2 >>> nwcc.readLEShort() 259 >>> nwcc.parsePosition 4
Or to not update the parsePosition, send False: >>> nwcc.parsePosition = 0 >>> nwcc.readLEShort(False) 258 >>> nwcc.readLEShort(False) 258 >>> nwcc.parsePosition 0
- NWCConverter.readToNUL(updateParsePosition=True) bytes ¶
reads self.fileContents up to, but not including, the next position of x00.
updates the parsePosition unless updateParsePosition is False
- NWCConverter.skipBytes(numBytes=1)¶
- NWCConverter.toStream()¶
NWCObject¶
- class music21.noteworthy.binaryTranslate.NWCObject(staffParent: NWCStaff, parserParent: NWCConverter)¶
NWCObject class is a union that can be used for each type of object contained in a staff.
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.
NWCObject
methods
- NWCObject.barline()¶
Bar line 2 bytes
- NWCObject.clef()¶
clef info, 4 bytes
- NWCObject.dynamic()¶
dynamics 7 bytes
- NWCObject.dynamicVariation()¶
Dynamic variation 3 bytes
- NWCObject.ending()¶
Endings 2 bytes
- NWCObject.flowDir()¶
Flow 4 bytes
- NWCObject.instrument()¶
Instrument 8 bytes
- NWCObject.keySig()¶
Key signature 10 bytes
- NWCObject.mpc()¶
Midi Instructions 34 bytes
- NWCObject.note()¶
Note 8 bytes
- NWCObject.noteChordMember()¶
Chord member 8 bytes + n Note objects
- NWCObject.parse()¶
determine what type of object I am, and set things accordingly
- NWCObject.pedal()¶
Pedal 3 bytes
- NWCObject.performance()¶
Performance 3 bytes
- NWCObject.rest()¶
Rest 8 bytes
- NWCObject.restChordMember()¶
Rest chord 10 bytes
- NWCObject.setDurationForObject()¶
get duration string for note or rest
- NWCObject.tempo()¶
Tempo indications 5 bytes + null terminated string
- NWCObject.tempoVariation()¶
Tempo variation 4 bytes
- NWCObject.textObj()¶
Text 3 bytes + null terminated string
- NWCObject.timeSig()¶
Time signature 6 bytes
NWCStaff¶
- class music21.noteworthy.binaryTranslate.NWCStaff(parent: NWCConverter)¶
A NWCStaff is a list of NWCObjects (see
parseObjects()
) associated to metadata (seeparseHeader()
). It may also contain some lyrics (seeparseLyrics()
). It defines adump()
method that return a list of string containing the nwctxt-formatted content of each object of the staff.
NWCStaff
methods
- NWCStaff.dump() list[str] ¶
- NWCStaff.parse()¶
- NWCStaff.parseHeader()¶
- NWCStaff.parseLyrics()¶
- NWCStaff.parseObjects()¶