Copy in Hans' 1.0 version of nwc2ly.py.
authorHans de Rijck <hans@octet.nl>
Wed, 1 Dec 2010 12:15:07 +0000 (07:15 -0500)
committerW. Trevor King <wking@drexel.edu>
Wed, 1 Dec 2010 12:15:07 +0000 (07:15 -0500)
From
  http://lily4jedit.svn.sourceforge.net/viewvc/lily4jedit/trunk/LilyPondTool/otherpatches/nwc2ly/nwc2ly.py?view=markup&pathrev=457

nwc2ly.py

index 028cc45e39483373da08ff30b020a7ba8a2efca6..3dc8db97fd0a97a36c01f48c5379832d7e648b19 100644 (file)
--- a/nwc2ly.py
+++ b/nwc2ly.py
-import binascii, sys, zlib, traceback \r
-\r
-shortcopyleft = """\r
-nwc2ly - Converts NWC(v 1.75) to LY fileformat\r
-Copyright (C) 2005  Joshua Koo (joshuakoo @ myrealbox.com)\r
-\r
-This program is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU General Public License\r
-as published by the Free Software Foundation; either version 2\r
-of the License, or (at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
-"""\r
-\r
-##\r
-# most infomation obtained about the nwc format \r
-# is by using noteworthycomposer and the somewhat like the french cafe method\r
-# (http://samba.org/ftp/tridge/misc/french_cafe.txt)\r
-#\r
-#\r
-## \r
-# Revisions\r
-# 0.1  07 april 2005 initial hex parsing;\r
-# 0.2  13 april 2005 added multiple staff, keysig, dots, durations\r
-# 0.3  14 april 2005 clef, key sig detection, absolute notes pitching\r
-# 0.4   15 April 2005 Relative Pitchs, Durations, Accidentals, Stem Up/Down, Beam, Tie\r
-# 0.5   16 April 2005 Bug fixes, Generate ly score , Write to file, Time Sig, Triplets, Experimental chords\r
-# 0.6  17 April 2005 Compressed NWC file Supported!\r
-# 0.7  19 April 2005 Version detection, Header \r
-#      20 April 2005 BUGS FiXes, small Syntax changes\r
-#      21 April 2005 Still fixing aimlessly \r
-#      23 April 2005 Chords Improvement\r
-#      24 April 2005 staccato, accent, tenuto. dynamics, midi detection (but unsupported)\r
-# 0.8  24 April 2005 Experimental Lyrics Support\r
-# 0.9  29 April 2005 Workround for \acciaccatura, simple Check full bar rest adjustment\r
-#      \r
-## \r
-# TODO\r
-# Proper syntax and structure for staffs, lyrics, layering\r
-# version 1.7 Support\r
-# nwc2ly in lilytool\r
-# \r
-# Piano Staff\r
-# Chords\r
-# Pedals\r
-# Midi Instruments\r
-# Visability\r
-# Lyrics\r
-# Context Staff\r
-# Staff layering / Merging\r
-##\r
-#\r
-# BUGS text markups, chords, fermata\r
-######\r
-# \r
-# cd /cygdrive/c/development/nwc2ly\r
-# $ python nwc2ly.py lvb7th1\ uncompressed.nwc test.ly > convert.log\r
-#######\r
-\r
-nwc2lyversion = '0.9.0'\r
-############\r
-# Options  #\r
-############\r
-debug = 0 \r
-       # You can use 0 for False and 1 for True\r
-relativePitch = 1\r
-relativeDuration = 1\r
-barLinesComments = 10 # Comments for every x lines     # section/line comment\r
-\r
-insertBeaming = 1\r
-insertSteming = 1\r
-#insertText = 0\r
-\r
-nwcversion = 1.75\r
-##############\r
-\r
-args =  len(sys.argv)\r
-if args<2:\r
-       print "Syntax: python nwc2ly.py nwcfile [lyfile]"\r
-       sys.exit()\r
-nwcfile = sys.argv[1] # 'simple1.nwc' #'simple2.nwc' 'simple3.nwc' 'bbc5-1-org.nwc' bbc5-1-nop.\r
-\r
-if args<3:\r
-       lyfile = ''  # 'test.ly'\r
-else:\r
-       lyfile = sys.argv[2]\r
-\r
-\r
-\r
-def getFileFormat(nwcData):\r
-       #'[NoteWorthy ArtWare]'\r
-       #'[NoteWorthy Composer]'\r
-       nwcData.seek(0)\r
-       company = readLn(nwcData)\r
-       nwcData.seek(2,1) # pad\r
-       product = readLn(nwcData)\r
-       version = readLn(nwcData)\r
-       version = ord(version[0]) * 0.01 + ord(version[1])\r
-       nwcversion = version\r
-       print 'NWC file version', nwcversion, 'detected!'\r
-       pad(nwcData,2) # times saved\r
-       name1 = readLn(nwcData)\r
-       name2 = readLn(nwcData)\r
-       \r
-       pad(nwcData,8)\r
-       huh = nwcData.read(1)\r
-       pad(nwcData,1)\r
-       \r
-def getFileInfo(nwcData):\r
-       title = readLn(nwcData)\r
-       author = readLn(nwcData)\r
-       copyright1 = readLn(nwcData)\r
-       copyright2 = readLn(nwcData)\r
-       comments = readLn(nwcData)\r
-       \r
-       header = "\\header {"\r
-       header += "\n\ttitle = \"%s\"" % title\r
-       header += "\n\tenteredby = \"%s\"" % author\r
-       header += "\n\tcopyright = \"%s\"" % copyright1\r
-       header += "\n\tfooter = \"%s\"" % copyright2\r
-       header += "\n\t%%{ %s %%}" % comments\r
-       header += "\n}"\r
-               \r
-       # TO ADD IN DEFAULT BLANK FEILDS TO KEY IN\r
-       print 'title,author,copyright1,copyright2,comments: ', (title,author,copyright1,copyright2,comments)\r
-       return header\r
-\r
-# Page Setup\r
-def getPageSetup(nwcData):\r
-       # ??\r
-       getMargins(nwcData)\r
-       #getContents(nwcData)\r
-       #getOptions(nwcData)\r
-       getFonts(nwcData)\r
-\r
-       \r
-def getMargins(nwcData):\r
-       readTill(nwcData,'\x01')\r
-       pad(nwcData,1)\r
-       # get string size 43\r
-       margins = readLn(nwcData)\r
-       print 'margins ', margins\r
-       #mirrorMargines\r
-       #UOM\r
-       return \r
-\r
-def getOptions(nwcData):\r
-       # page numbering, from\r
-       # title page info\r
-       # extend last system\r
-       # incrase note spacing for larger note duration\r
-       # staff size\r
-       # staff labels (none, first systems, top systems, all systems\r
-       # measure numbers none, plain, circled, boxed\r
-       # measure start\r
-       return\r
-\r
-def getFonts(nwcData):\r
-       # 12 Times\r
-       readTill(nwcData,'\xFF')\r
-       n = nwcData.read(1)\r
-       pad(nwcData,1)\r
-       for i in range (12):\r
-               # Font Name\r
-               font = readLn (nwcData)\r
-               \r
-               # 00\r
-               \r
-               # Style 'Regular' 'Italic' 'Bold' 'Bold Italic'\r
-               style = ord(nwcData.read(1)) & 3\r
-               \r
-               # Size\r
-               size = ord(nwcData.read(1))\r
-               \r
-               ## 00\r
-               nwcData.seek(1,1)\r
-               \r
-               # Typeface\r
-               # 00 Western, b1 Hebrew\r
-               typeface = nwcData.read(1)\r
-               \r
-               print 'Font detected' , font, 'size',size, 'style ', style, ' typeface',typeface\r
-               \r
-\r
-def findNoOfStaff(nwcData):\r
-       # Infomation on Staffs \x08 00 00 FF 00 00 n\r
-       data = 0;\r
-       \r
-       readTill(nwcData,'\xFF')\r
-       print "Where am I? ", nwcData.tell()\r
-       \r
-       \r
-       nwcData.read(2)\r
-       \r
-       layering = nwcData.read(1) # FF or 00\r
-       \r
-       noOfStaffs = ord(nwcData.read(1))\r
-       nwcData.read(1)\r
-       print noOfStaffs, " noOfStaffs found"\r
-       return noOfStaffs\r
-\r
-def findStaffInfo(nwcData):\r
-       # Properties for Staff\r
-               # General \r
-                       # Name.\r
-                       # Group\r
-                       # Ending Bar\r
-               # Visual\r
-                       # Verticle Upper Size\r
-                       # Verticle Lower Size\r
-                       # Style\r
-                       # Layer Next Staff\r
-                       # Color\r
-               # Midi\r
-                       # Part Volume\r
-                       # Stereo Pan\r
-                       # Transposition\r
-                       # Muted\r
-                       # PlayBack Device\r
-                       # Playback Channel\r
-               # Instrument\r
-                       # Patch Name\r
-                       # Patch List Type\r
-                       # Bank Select \r
-                       # Controller0\r
-                       # Controller32\r
-       # Staff Lyrics\r
-               # LineCount\r
-               # AlignSyllableRule\r
-               # StaffPlacementAligment\r
-               # StaffPlacementOffset\r
-               # StaffPropertiesVerticleSizeUpper\r
-               # StaffPropertiesVerticleSizeLower\r
-               \r
-       format = ''\r
-       staffName = readLn(nwcData)\r
-       format += "\\context Staff = %s " % staffName # or voice or lyrics \r
-       \r
-       groupName = readLn(nwcData) # HOW TO ORGANISE THEM??\r
-       \r
-       endbar = ord(nwcData.read(1)) # & (2^3-1)\r
-       #print 'end ',endbar\r
-       endingBar = ending[endbar] #  10 --> OC for lyrics?  10000 1100\r
-       \r
-       muted = ord(nwcData.read(1)) & 1\r
-       nwcData.read(1)\r
-       \r
-       channel = ord(nwcData.read(1)) + 1\r
-       nwcData.read(9)\r
-       \r
-       stafftype = staffType[ord(nwcData.read(1))&3]\r
-       nwcData.read(1)\r
-       \r
-       uppersize = 256 - ord(nwcData.read(1))  # - signed +1 )& 2^7-1 )\r
-       readTill(nwcData,'\xFF')\r
-       \r
-       lowersize = ord(nwcData.read(1))\r
-       ww = nwcData.read(1) \r
-       print '[uppersize,lowersize]',[uppersize,lowersize]\r
-       \r
-       noOfLines = ord(nwcData.read(1))\r
-       print '[staffName,groupName,endingBar,stafftype,noOfLines]', [staffName,groupName,endingBar,stafftype,noOfLines]\r
-       \r
-       layer = ord(nwcData.read(1)) & 1\r
-       \r
-       # signed transposition\r
-       # FF?\r
-       \r
-       partVolume = ord(nwcData.read(1))\r
-       ord(nwcData.read(1))\r
-       \r
-       stereoPan = ord(nwcData.read(1))\r
-       if nwcversion == 1.7:\r
-               nwcData.read(2)\r
-       else:\r
-               nwcData.read(3)\r
-       \r
-       nwcData.read(2)\r
-       #lyrics = ord(nwcData.read(1)) & 1\r
-       lyrics = readInt(nwcData)\r
-       noOfLyrics = readInt(nwcData)\r
-       \r
-       lyricsContent = ''\r
-       if lyrics:\r
-               lyricOptions = readInt(nwcData)\r
-               nwcData.read(3)\r
-               for i in range(noOfLyrics):\r
-                       print 'looping ',i, 'where', nwcData.tell()\r
-                       lyricsContent  += '\\ \lyricmode { ' # lyrics\r
-                       lyricsContent  += getLyrics(nwcData) #\r
-                       lyricsContent  += '}'\r
-               nwcData.read(1)\r
-       \r
-       nwcData.read(1)\r
-       color = ord(nwcData.read(1)) & 3 #12\r
-       \r
-       noOfTokens = readInt(nwcData)\r
-       print noOfTokens, " Tokens found", nwcData.tell()\r
-       return noOfTokens, format, lyricsContent\r
-       \r
-\r
-\r
-\r
-\r
-def pad(nwcData, length):\r
-       nwcData.seek(length,1)\r
-\r
-def readTill(nwcData, delimit):\r
-       data = ''\r
-       value = ''\r
-       while data!=delimit:\r
-               value += data\r
-               data = nwcData.read(1)\r
-               \r
-       return value\r
-       \r
-def readLn(nwcData):\r
-       return readTill (nwcData,'\x00')\r
-       # reads until 00 is hit\r
-       # od oa == \n\r
-\r
-def readInt(nwcData):\r
-       data = nwcData.read(2)\r
-       no = ord(data[0])\r
-       no += ord(data[1]) * 256\r
-       return no\r
-\r
-\r
-def getLyrics(nwcData):\r
-       \r
-       data = ''\r
-       print 'reach'\r
-       blocks = ord(nwcData.read(1))\r
-       if blocks==4: blocks = 1\r
-       if blocks==8: blocks = 2\r
-       if blocks == 0: return \r
-       \r
-       lyricsLen = readInt(nwcData)\r
-       \r
-       print 'blocks ',blocks, 'lyrics len', lyricsLen, 'at ', nwcData.tell()\r
-       \r
-       nwcData.read(1)\r
-       for i in range (blocks):\r
-               data += nwcData.read(1024)\r
-       \r
-       lyrics = data[1:lyricsLen-1]\r
-       print 'lyrics ', lyrics\r
-       return lyrics\r
-       \r
-def getDuration(data):\r
-       durationBit = ord(data[2]) & 7\r
-       durationDotBit = ord(data[6]) \r
-       \r
-       duration = durations[durationBit]\r
-       if (durationDotBit & 1<<2):\r
-               durationDot = '.'\r
-       elif (durationDotBit & 1):\r
-               durationDot = '..'\r
-       else :\r
-               durationDot = ''\r
-       return duration + durationDot\r
-\r
-def getKey(data):\r
-       data = binascii.hexlify(data)\r
-       \r
-       if (keysigs.has_key(data)):\r
-               return '\key ' + keysigs[data]\r
-       return '% unknown key'\r
-\r
-def getLocation(data):\r
-       offset = ord(data[8]);\r
-       if offset > 127 :\r
-               return 256-offset\r
-       if (ord(data[9])>>3 & 1):\r
-               return -offset\r
-       \r
-       return offset\r
-       #print 'offset ', offset\r
-       #print binascii.hexlify(data[8:9])\r
-\r
-def getAccidental(data):\r
-       data = ord(data)\r
-       data = (data & 7 )\r
-       return acdts[data]\r
-\r
-def getNote(data):\r
-       \r
-       # pitch\r
-       pitch = getLocation(data)\r
-       \r
-       # get Accidentals\r
-       accidental =  getAccidental(data[9])\r
-       \r
-       # get Relative Duration\r
-       duration = getDuration(data)\r
-       \r
-       # check stems\r
-       stem = ord(data[4])\r
-       stem = (stem >> 4) & 3\r
-       \r
-       # check beam\r
-       beam = ord(data[4]) & 3\r
-       \r
-       # triplets \r
-       triplet = triplets [ord(data[4])>>2 & 3 ]\r
-       \r
-       # check tie\r
-       tie = ''\r
-       if ord(data[6]) >> 4 & 1:\r
-               tie = '~'\r
-       \r
-       staccato = (ord(data[6]) >> 1) & 1\r
-       accent = (ord(data[6]) >> 5) & 1\r
-       \r
-       tenuto = (ord(data[7]) >> 2) & 1\r
-       slur = slurs[ord(data[7]) & 3 ]\r
-       grace = (ord(data[7]) >> 5) & 1\r
-       \r
-       # check slur\r
-       slur = slurs[ord(data[7]) & 3 ]\r
-       \r
-       \r
-       #TODO should use a dictionary\r
-       return (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto)\r
-\r
-def getRelativePitch(lastPitch, pitch):\r
-       octave = ''\r
-       diff = pitch - lastPitch\r
-       if diff>3:\r
-               for i in range((diff-4 + 7)/7):\r
-                       octave += "'"\r
-               if octave == '':\r
-                       octave += "'"\r
-       elif diff<-3:\r
-               for i in range((-diff-4 + 7)/7):\r
-                       octave += ","\r
-               if octave == '':\r
-                       octave += ","\r
-       return octave\r
-       \r
-def durVal(duration):\r
-       where = duration.find('.')\r
-       \r
-       if where>-1:\r
-               durVal = 128/int (duration[:where])\r
-               nextVal = durVal\r
-               for i in range(len(duration)-where):\r
-                       nextVal = nextVal / 2\r
-                       durVal += nextVal\r
-               \r
-       else:\r
-               durVal = 128/int (duration)\r
-       return durVal\r
-       \r
-def processStaff(nwcData):\r
-       keysigCount =0\r
-       timesigCount=0\r
-       noteCount=0\r
-       restCount=0\r
-       staffCount=0\r
-       barlineCount=0\r
-       clefCount=0\r
-       textCount =0\r
-       dynamicCount = 0\r
-       \r
-       lastPitch = scale.index('c')\r
-       lastDuration = 0\r
-       lastClef = scale.index(clefs[0])  # index referenced to note of last clef\r
-       lastStem = 0\r
-       lastTimesig = 1\r
-       \r
-       lastKey = { 'c': '', #c \r
-       'd': '', 'e': '', 'f': '', 'g': '', 'a': '', 'b': '' }\r
-       currentKey = lastKey.copy()\r
-       \r
-       data = 0\r
-       token = 1\r
-       \r
-       result = ""\r
-       result += "\n\t\\new Staff {\n\t\t"\r
-       lastChord = 0\r
-       lastGrace = 0;\r
-       \r
-       (noOfTokens,format, lyrics) = findStaffInfo(nwcData);\r
-       if lyrics!='':\r
-               #result += '\\lyricmode { ' + lyrics + '}'\r
-               result += '%%Lyrics %%{ ' + lyrics + '%%}'\r
-       \r
-       if relativePitch: \r
-               result+="\\relative c {"\r
-       else :\r
-               result+=" {"\r
-       result+="\n\t\t\n\n\t\t"\r
-       result+= '\n\t %% Staff %s \n\t' % staff \r
-       \r
-       #print "00112233445566778899\n"\r
-       extra = ''\r
-       # the juice\r
-       \r
-       while data!="":\r
-               \r
-               token += 1\r
-               if token==noOfTokens:\r
-                       result += "\n\t\t}\n\t}\n\t"\r
-                       print "going next staff! %s" % nwcData.tell()\r
-                       break\r
-               \r
-               \r
-               if nwcversion==1.7:\r
-                       nwcData.seek(2,1)\r
-               \r
-               data = nwcData.read(1)\r
-               #print 'test', data\r
-               \r
-               # clef\r
-               if data=='\x00':\r
-                       data = nwcData.read(6)\r
-                       clefCount += 1\r
-                       \r
-                       key = ord(data[2]) & 3  \r
-                       octave = ord(data[4]) & 3\r
-                       # print binascii.hexlify(data) , "CLEF? "\r
-                       lastClef = scale.index(clefs[key]) + octaves[octave]\r
-                       #TODO check for octave shifts _8\r
-                       lastClef += clefShift[octave]  \r
-                       result += '\clef "' + clefNames[key] + clefOctave[octave]+ '"\n\t\t'\r
-                       \r
-               # key signature\r
-               elif data=='\x01':\r
-                       data = nwcData.read(12)\r
-                       keysigCount = keysigCount + 1\r
-                       \r
-                       #\r
-                       flatBits = ord(data[2])\r
-                       sharpBits = ord(data[4])\r
-                       \r
-                       for note in lastKey.keys():\r
-                               noteInd = ['a','b','c','d','e','f','g'].index(note)\r
-                               if (flatBits >> noteInd & 1):\r
-                                       lastKey[note] = 'es'\r
-                               elif (sharpBits >> noteInd & 1):\r
-                                       lastKey[note] = 'is'\r
-                               else:\r
-                                       lastKey[note] = ''\r
-                       \r
-                       currentKey = lastKey.copy()\r
-                       result = result + getKey(data[1:5]) + "\n\t\t"\r
-                       \r
-                       #print "data", binascii.hexlify(data)\r
-                       #print "flat", binascii.hexlify(flatBits)\r
-                       #print "sharp", binascii.hexlify(data[4])\r
-                       #print getKey(data[1:5])\r
-                       \r
-               \r
-               # barline\r
-               elif data=='\x02':\r
-                       data = nwcData.read(4)\r
-                       barlineCount += 1\r
-                       \r
-                       currentKey = lastKey.copy()\r
-                       \r
-                       result += "|\n\t\t"\r
-                       if (barlineCount % barLinesComments == 0):\r
-                               result += "\n\t\t% Bar " + str(barlineCount + 1) + "\n\t\t" \r
-                               #print '.',\r
-                               print "Bar ",barlineCount, " completed, "\r
-               \r
-               # timesig\r
-               elif data=='\x05':\r
-                       data = nwcData.read(8)\r
-                       timesigCount = timesigCount + 1 \r
-                       beats = ord(data[2])\r
-                       beatValues = [ 1, 2, 4, 8 ,6, 32 ]\r
-                       beatValue = beatValues[ord(data[4])]\r
-                       timesig = str(beats) + "/"  + str(beatValue)\r
-                       lastTimesig = timesigValues[timesig]\r
-                       result += "\\time " + timesig + " "\r
-               # Tempo\r
-               elif data=='\x06':\r
-                       print "Tempo"\r
-                       data = nwcData.read(7)\r
-                       tempo = readLn(nwcData)\r
-                       result += '\n\t\t%%tempo %s\n\t\t' % tempo\r
-                       #tempoCount = tempoCount + 1    \r
-                       \r
-               # note\r
-               elif data=='\x08':\r
-                       data = nwcData.read(10)\r
-                       noteCount = noteCount + 1\r
-                       \r
-                       if debug: print binascii.hexlify(data) , noteCount , nwcData.tell()\r
-                       (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = getNote(data)\r
-                       \r
-                       \r
-                       articulate = ''\r
-                       if staccato: articulate+= '-.'\r
-                       if accent: articulate+= '->'\r
-                       if tenuto: articulate+= '--'\r
-                       \r
-                       beam = beams[beam]\r
-                       \r
-                       chordMatters = ''\r
-                       if lastChord>0 and beam==']' :\r
-                               chordMatters = ' } >> '\r
-                               lastChord = 0\r
-                       elif lastChord>0:\r
-                               \r
-                               print 'CHORd', durVal(duration), lastChord\r
-                               dur = durVal(duration)\r
-                               #lastChord = 1.0/((1.0 / lastChord) - (1.0/durVal(duration)))\r
-                               lastChord -= dur \r
-                               \r
-                               if lastChord <= 0 :\r
-                                       chordMatters = ' } >> '\r
-                                       lastChord = 0\r
-                                       \r
-                               \r
-                       \r
-                       if not insertBeaming: beam = ''\r
-                       \r
-                       # pitch\r
-                       pitch += lastClef\r
-                       note = scale[pitch]\r
-                       \r
-                       \r
-                       # get Accidentals\r
-                       #print 'accidental',accidental\r
-                       if (accidental!='auto'):\r
-                               currentKey[note[0]] = accidental\r
-                       accidental = currentKey[note[0]]\r
-                       \r
-                       if (relativePitch):\r
-                               octave = getRelativePitch(lastPitch, pitch)\r
-                               lastPitch = pitch\r
-                       else:\r
-                               octave = note[1:]\r
-                       pitch = note[0] + accidental + octave\r
-                       \r
-                       # get Relative Duration\r
-                       if (relativeDuration):\r
-                               if (lastDuration==duration):\r
-                                       duration = ''\r
-                               else:\r
-                                       lastDuration = duration\r
-                       \r
-                       # check stems\r
-                       if insertSteming and (stem!= lastStem) :\r
-                               lastStem = stem\r
-                               stem = stems[stem]\r
-                       else :\r
-                               stem = ''\r
-                       \r
-                       # normal note\r
-                       if extra!='':\r
-                               extra = '-"' + extra + '"'\r
-                       \r
-                       if grace and not lastGrace: result += "\\acciaccatura { "\r
-                       \r
-                       if not grace and lastGrace: result += " } "\r
-                       result += triplet[0] + stem + pitch + duration + articulate + extra \r
-                       result += slur + tie + beam  + triplet[1]  +chordMatters  +  " "\r
-                       \r
-                       \r
-                       # reset\r
-                       lastGrace = grace\r
-                       extra = ''\r
-               # rest\r
-               elif data=='\x09':\r
-                       data = nwcData.read(10)\r
-                       restCount = restCount + 1 \r
-                       \r
-                       # get Relative Duration\r
-                       duration = getDuration(data)\r
-                       if duration == '1':\r
-                               duration = lastTimesig\r
-                       if (relativeDuration):\r
-                               if (lastDuration==duration):\r
-                                       duration = ''\r
-                               else:\r
-                                       lastDuration = duration\r
-                                       \r
-                       result = result + 'r' + duration + " "\r
-\r
-               # text\r
-               elif data=='\x11':\r
-                       textCount = textCount + 1\r
-                       data = nwcData.read(2) #pad\r
-                       textpos = nwcData.read(1)\r
-                       data = nwcData.read(2) #pad\r
-                       text = ''\r
-                       data = nwcData.read(1)\r
-                       while data!='\x00':\r
-                               text += data\r
-                               data = nwcData.read(1)\r
-                       \r
-                       #if text.isdigit() : # check numbers\r
-                       #       text = "-\\markup -\\number "+ text \r
-                       #       #text = "-\\markup {\\number "+ text +"}"\r
-                       #else :\r
-                       #       text = '-"' + text + '"'\r
-                       \r
-                       extra += ' ' + text\r
-                       \r
-               # dynamics\r
-               elif data=='\x07':\r
-                       dynamicCount = dynamicCount + 1\r
-                       data = nwcData.read(9)\r
-               # chord\r
-               elif data=='\x0A' or data=='\x12':\r
-                       \r
-                       data = nwcData.read(12)\r
-                       \r
-                       chordAmt = ord(data[10])\r
-                       chords = []\r
-                       chordDur = getDuration(data)\r
-                       #print 'duration',chordDur\r
-                                               \r
-                       #print "WARNING Chord support is experimental", chordDur, chordAmt\r
-                       #print binascii.hexlify(data), 'barlines ', barlineCount\r
-                       #print 'no. of notes in chord' , chordAmt\r
-                       \r
-                       chord1 = []\r
-                       chord2 = []\r
-                       \r
-                       for i in range(chordAmt):\r
-                               # rest or note\r
-                               what = nwcData.read(1)\r
-                               \r
-                               data = nwcData.read(10)\r
-                               ha = getNote(data)\r
-                               #print 'data ', ha\r
-                               (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = ha\r
-                               # add to list\r
-                               if ha[2] == chordDur:\r
-                                       chord1.append( (pitch,accidental ) )\r
-                                       if beam==0 or beam ==4 :\r
-                                               lastChord = 0\r
-                       \r
-                                       \r
-                               else : # 2 voices\r
-                                       chord2.append(  (pitch,accidental, duration) )\r
-                                       lastChord = durVal(duration)  \r
-                                       \r
-                       \r
-                       if len(chord2)==0: # block chord\r
-                               result += ' <'\r
-                               for i in range(len(chord1)):\r
-                                       (pitch,accidental ) = chord1[i]\r
-                                       pitch += lastClef\r
-                                       note = scale[pitch]\r
-                                       \r
-                                       if (accidental!='auto'):\r
-                                               currentKey[note[0]] = accidental\r
-                                       accidental = currentKey[note[0]]\r
-                                       \r
-                                       if (relativePitch):\r
-                                               octave = getRelativePitch(lastPitch, pitch)\r
-                                               lastPitch = pitch\r
-                                       else:\r
-                                               octave = note[1:]\r
-                                       result += note[0] + accidental + octave + ' '\r
-                               result += '>' +chordDur +' '\r
-                               lastPitch = chord1[0][0] + lastClef\r
-                       else: # 2 voices\r
-                               result += ' << ' \r
-                               for i in range(len(chord2)):\r
-                                       (pitch,accidental,duration ) = chord2[i]\r
-                                       pitch += lastClef\r
-                                       note = scale[pitch]\r
-                                       \r
-                                       if (accidental!='auto'):\r
-                                               currentKey[note[0]] = accidental\r
-                                       accidental = currentKey[note[0]]\r
-                                       \r
-                                       if (relativePitch):\r
-                                               octave = getRelativePitch(lastPitch, pitch)\r
-                                               lastPitch = pitch\r
-                                       else:\r
-                                               octave = note[1:]\r
-                                       result += note[0] + accidental + octave + duration + ' '\r
-                               \r
-                               result += " \\\\ {"\r
-                               \r
-                               for i in range(len(chord1)):\r
-                                       (pitch,accidental ) = chord1[i]\r
-                                       pitch += lastClef\r
-                                       note = scale[pitch]\r
-                                       \r
-                                       if (accidental!='auto'):\r
-                                               currentKey[note[0]] = accidental\r
-                                       accidental = currentKey[note[0]]\r
-                                       \r
-                                       if (relativePitch):\r
-                                               octave = getRelativePitch(lastPitch, pitch)\r
-                                               lastPitch = pitch\r
-                                       else:\r
-                                               octave = note[1:]\r
-                                       result += note[0] + accidental + octave +chordDur + ' '\r
-                               if lastChord >0 : lastChord = durVal(duration) - durVal(chordDur)\r
-                               if lastChord==0: result += ' } >> '\r
-                               # end 2 voices\r
-                       lastDuration = chordDur\r
-                       \r
-                       # check if duration / stem  / same \r
-                               # < >duration ties,beam, slurs\r
-               \r
-               # Pedal\r
-               elif data=='\x0b':\r
-                       print 'Ped      '\r
-                       data = data = nwcData.read(5)\r
-               # midi control instruction / MPC\r
-               elif data=='\x0d':\r
-                       print 'midi control instruction'\r
-                       data = data = nwcData.read(36)\r
-               # fermata / Breath mark\r
-               elif data=='\x0E':\r
-                       print "Fermata"\r
-                       data = nwcData.read(6)\r
-                       extra += "\\fermata" \r
-               \r
-               # Dynamics\r
-               elif data=='\x0f':\r
-                       print "Dynamics"\r
-                       data = nwcData.read(5)\r
-               \r
-               # Performance Style\r
-               elif data=='\x10':\r
-                       print "Performance Style"\r
-                       data = nwcData.read(5)\r
-               \r
-               # Instrument Patch\r
-               elif data=='\x04':\r
-                       print "Instrument Patch"\r
-                       data = nwcData.read(10)\r
-               \r
-               \r
-               # todo\r
-               else :\r
-                       print "WARNING: Unrecognised token ",binascii.hexlify(data), " at #", nwcData.tell(), " at Token",  token\r
-                       \r
-                       \r
-                       \r
-       # output converted file?\r
-       print "\nStats"\r
-       print keysigCount, " keysigCount found"\r
-       print noteCount, " notes found"\r
-       print staffCount, " staffCount found"\r
-       print clefCount, " clefCount found"\r
-       print barlineCount, " barlineCount found"\r
-       print timesigCount, " timesigCount found"\r
-       print textCount, " textCount found"\r
-       print dynamicCount, " dynamicCount found"\r
-       print restCount, " restCount found"\r
-       \r
-       #print "\nLilypond format:\n"\r
-       return result\r
-       \r
-# Variables\r
-keysigs = {\r
-'00000000' : 'c \major % or a \minor' ,\r
-'00000020' : 'g \major % or e \minor' ,\r
-'00000024': 'd \major % or b \minor' ,\r
-'00000064' : 'a \major % or fis \minor' ,\r
-'0000006c' : 'e \major % or cis \minor' ,\r
-'0000006d' : 'b \major % or gis \minor' ,\r
-'0000007d' : 'fis \major % or dis \minor' ,\r
-'0000007f' : 'cis \major % or ais \minor' ,\r
-'00020000' : 'f \major % or d \minor' ,\r
-'00120000' : 'bes \major % or g \minor' ,\r
-'00130000' : 'ees \major % or c \minor' ,\r
-'001b0000' : 'aes \major % or f \minor' ,\r
-'005b0000' : 'des \major % or bes \minor' ,\r
-'005f0000' : 'ges \major % or ees \minor' ,\r
-'007f0000' : 'ces \major % or a \minor'\r
-}\r
-\r
-acdts = ( 'is', 'es', '' ,'isis', 'eses', 'auto'  ) \r
-\r
-clefs = { 0 : "b'",\r
-          1 : "d",\r
-          2 : "c'",\r
-          3 : "a'",\r
-        }\r
-\r
-clefNames = { 0: 'treble',\r
-          1: 'bass',\r
-          2: 'alto',\r
-          3: 'tenor',\r
-        }\r
-octaves = { 0: 0, 1:7, 2:-7 }\r
-scale = [   # this list is taken from lilycomp\r
-        "c,,,","d,,,","e,,,","f,,,","g,,,","a,,,","b,,,",\r
-        "c,,","d,,","e,,","f,,","g,,","a,,","b,,",\r
-        "c,","d,","e,","f,","g,","a,","b,",\r
-        "c","d","e","f","g","a","b",\r
-        "c'","d'","e'","f'","g'","a'","b'",\r
-        "c''","d''","e''","f''","g''","a''","b''",\r
-        "c'''","d'''","e'''","f'''","g'''","a'''","b'''",\r
-        "c''''","d''''","e''''","f''''","g''''","a''''","b''''",\r
-        ]\r
-\r
-stems = [ '\stemNeutral ', '\stemUp ', '\stemDown ']\r
-\r
-slurs = [ '', '(' , ')', '' ]\r
-\r
-triplets = [ \r
-       ('' , '' ),\r
-       ( '\\times 2/3 { ', '') ,\r
-       ('' , '' ),\r
-       ('' , ' }' ),\r
-       ]\r
-\r
-durations = ( '1','2','4','8','16','32','64' ) \r
-\r
-barlines = (\r
-     '|', # 'Single'\r
-     '||', # 'Double'\r
-     '.|', # SectionOpen\r
-     '|.', # SectionClose\r
-     '|:', # MasterRepeatOpen\r
-     ':|', # MasterRepeatClose\r
-     '|:', # LocalRepeatOpen\r
-     ':|', # LocalRepeatClose\r
-)\r
-\r
-ending = (\r
-'|.', # SectionClose\r
-':|', # MasterRepeatClose\r
-'|', # 'Single'\r
-'||', # 'Double'\r
-'' # Open hidden\r
-)\r
-\r
-staffType = (\r
-'Standard' , # Standard\r
-'Upper Grand Staff' , # Upper Grand Staff\r
-'Lower Grand Staff' , # Lower Grand Staff\r
-'Orchestra' , # Orchestra\r
-)\r
-\r
-\r
-beams = [ '', '[', '',']' ]\r
-\r
-\r
-# end ' \bar "|."'\r
-\r
-# Notation Properties\r
-# extra accidental spacing\r
-# extra note spacing\r
-# muted\r
-# no ledger lines\r
-# slurdirection\r
-# tiedirection\r
-# lyricsyllable\r
-# visability \r
-# show printed\r
-# item color\r
-\r
-#dynamics\r
-# cmd = DynamicVariance\r
-# Decrescendo \setTextCresc \<\r
-# setTextCresc Crescendo \>  setHairpinCresc\r
-# Dynamics stop '\! '\r
-# style = ff pp\r
-\r
-clefOctave = [ '' , '^8', '_8' , '' ]\r
-clefShift = [0,7,-7, 0]\r
-\r
-\r
-# '#(set-accidental-style '#39'modern-cautionary)'\r
-#(ly:set-point-and-click 'line-column)\r
-#(set-global-staff-size 20)\r
-\r
-timesigValues = { \r
-       '4/4' : '1', '3/4' : '2.', '2/4' : '2', '1/4' : '1',\r
-       '1/8' : '8', '2/8' : '4', '3/8' : '4.', '6/8' : '2.',\r
-       '4/8' : '2', '9/8' : '12', '12/8' : '1',\r
-       '2/2' : '1', '4/2' : '0', '1/2' : '2', \r
-        }\r
-\r
-print "python nwc2ly is running..."\r
-try:\r
-\r
-       nwcData = open( nwcfile,'rb')\r
-       \r
-       # check if its a readable nwc format\r
-       # compressed - [NWZ]\r
-       # uncompressed - [NoteWorthy ArtWare] [NoteWorthy Composer]\r
-       format = nwcData.read(5)\r
-       if format== '[NWZ]':\r
-               nwcData.seek(1,1)\r
-               print 'Compressed NWC detected!'\r
-               print 'Dumping to uncompressed NWC format and attemping conversion soon...'\r
-               uncompress = open ('uncompressed.nwc','wb')\r
-               uncompress.write(zlib.decompress(nwcData.read()))\r
-               uncompress.close()\r
-               print 'Inflating done. Now opening new file...'\r
-               nwcData.close()\r
-               nwcData = open( 'uncompressed.nwc','rb')\r
-               nwcData.seek(6)\r
-       elif format!= '[Note':\r
-               print 'Unknown format, please use an uncompress NWC format and try again.'  \r
-               sys.exit()\r
-       \r
-       \r
-       \r
-       resultFile = '%% Generated from python nwc2ly converter v%s by Joshua Koo (joshuakoo@myrealbox.com)' % nwc2lyversion\r
-       resultFile += '\n\n\\version "2.4.0"'\r
-       resultFile += "\n"\r
-       \r
-       \r
-       # START WORK\r
-       getFileFormat(nwcData)\r
-       resultFile+=getFileInfo(nwcData)\r
-       resultFile+= "\n\n\\score {"\r
-       resultFile+= "\n\t<<\n\t\t"\r
-       \r
-       getPageSetup(nwcData)\r
-       \r
-       noOfStaffs = findNoOfStaff(nwcData);\r
-       \r
-       for staff in range(1,noOfStaffs+1):\r
-               print "\n\nWorking on Staff", staff\r
-               result = processStaff(nwcData)\r
-               #print result\r
-               resultFile += result\r
-       \r
-       resultFile+= "\n\t>>"\r
-       resultFile+= "\n\t\layout {}"\r
-       resultFile+= "\n\t\midi {}"\r
-       resultFile+= "\n}"\r
-       nwcData.close()\r
-       \r
-       if lyfile=='':\r
-               print 'Dumping output file to screen'\r
-               print resultFile\r
-       else :\r
-               write = open( lyfile ,'w')\r
-               write.write (resultFile)\r
-               write.close()\r
-\r
-except IOError:\r
-       print 'File does not exist or an IO error occurred'\r
-except Exception, e: #KeyError\r
-       print "Error while reading data at ", nwcData.tell() ,"\n"\r
-       print 'Dumping whatever result first'\r
-       print resultFile\r
-       print result\r
-       print\r
-       traceback.print_exc()\r
-\r
-print\r
-print\r
-print "Please send all bugs and requests to joshuakoo@myrealbox.com"\r
+import binascii, sys, zlib, traceback 
+from ConfigParser import SafeConfigParser
+
+shortcopyleft = """
+nwc2ly - Converts NWC(v 1.75) to LY fileformat
+Copyright (C) 2005  Joshua Koo (joshuakoo @ myrealbox.com)
+and                 Hans de Rijck (hans @ octet.nl)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+"""
+
+##
+# most infomation obtained about the nwc format 
+# is by using noteworthycomposer and the somewhat like the french cafe method
+# (http://samba.org/ftp/tridge/misc/french_cafe.txt)
+#
+#
+## 
+# Revisions
+# 0.1  07 april 2005 initial hex parsing;
+# 0.2  13 april 2005 added multiple staff, keysig, dots, durations
+# 0.3  14 april 2005 clef, key sig detection, absolute notes pitching
+# 0.4   15 April 2005 Relative Pitchs, Durations, Accidentals, Stem Up/Down, Beam, Tie
+# 0.5   16 April 2005 Bug fixes, Generate ly score , Write to file, Time Sig, Triplets, Experimental chords
+# 0.6  17 April 2005 Compressed NWC file Supported!
+# 0.7  19 April 2005 Version detection, Header 
+#      20 April 2005 BUGS FiXes, small Syntax changes
+#      21 April 2005 Still fixing aimlessly 
+#      23 April 2005 Chords Improvement
+#      24 April 2005 staccato, accent, tenuto. dynamics, midi detection (but unsupported)
+# 0.8  24 April 2005 Experimental Lyrics Support
+# 0.9  29 April 2005 Workround for \acciaccatura, simple Check full bar rest adjustment
+# 1.0   10 July  2005 Hans de Rijck,
+#                      added dynamics, dynamic variance, tempo, tempo variance,
+#                      performance style, page layout properties
+#                      corrected barlines, lyrics, slurs, natural accidentals
+#                      using inifile for settings
+#                      limited support for NWC version 2.0
+#      
+## 
+# TODO
+# Proper syntax and structure for staffs, lyrics, layering
+# version 1.7 Support
+# nwc2ly in lilytool
+# 
+# Piano Staff
+# Chords
+# Midi Instruments
+# Visability
+# Lyrics
+# Context Staff
+# Staff layering / Merging
+##
+#
+# BUGS text markups, chords
+######
+# 
+# cd /cygdrive/c/development/nwc2ly
+# $ python nwc2ly.py lvb7th1\ uncompressed.nwc test.ly > convert.log
+#######
+
+#################################
+#           Options             #
+#################################
+    
+cp = SafeConfigParser()
+cp.read( 'C:\development\nwc2ly\hans version\nwc2ly.ini' )
+#/cygdrive/C/development/nwc2ly/hans\ version/
+debug                  = int(cp.get('settings', 'debug'))
+relativePitch          = int(cp.get('settings', 'relativePitch'))
+relativeDuration       = int(cp.get('settings', 'relativeDuration'))
+barLinesComments       = int(cp.get('settings', 'barLinesComments'))
+
+insertBeaming          = int(cp.get('settings', 'insertBeaming'))
+insertSteming          = int(cp.get('settings', 'insertSteming'))
+insertText             = int(cp.get('settings', 'insertText'))
+
+paperSize              = cp.get('settings', 'Papersize')
+fillLast               = int(cp.get('settings', 'fillLast'))
+
+LilyPondVersion                = cp.get('settings', 'LilyPondVersion') 
+
+stdGrace               = cp.get('settings', 'stdGrace')        
+accidentalStyle        = cp.get('settings', 'accidentalStyle') 
+
+#################################
+#          /Options             #
+#################################
+
+global measureStart
+global nwcversion
+
+nwc2lyversion = '1.0'
+
+##############
+
+args =  len(sys.argv)
+if args<2:
+       print "Syntax: python nwc2ly.py nwcfile [lyfile]"
+       sys.exit()
+nwcfile = sys.argv[1]
+
+if args<3:
+       lyfile = ''
+else:
+       lyfile = sys.argv[2]
+
+
+
+def getFileFormat(nwcData):
+       global nwcversion
+       #'[NoteWorthy ArtWare]'
+       #'[NoteWorthy Composer]'
+       nwcData.seek(0)
+       company = readLn(nwcData)
+       nwcData.seek(2,1) # pad
+       product = readLn(nwcData)
+       if debug: print "product: ", product
+       #version = readLn(nwcData)
+       
+       version = nwcData.read(3)
+       if debug: print " version: ", binascii.hexlify(version) 
+       huh = nwcData.read(1)
+       version = ord(version[0]) * 0.01 + ord(version[1])
+       nwcversion = version
+       print 'NWC file version', nwcversion, 'detected!'
+       pad(nwcData,2) # times saved
+       name1 = readLn(nwcData)
+       name2 = readLn(nwcData)
+       
+       pad(nwcData,8)
+       huh = nwcData.read(1)
+       pad(nwcData,1)
+       
+def getFileInfo(nwcData):
+       title = readLn(nwcData)
+       author = readLn(nwcData)
+       copyright1 = readLn(nwcData)
+       copyright2 = readLn(nwcData)
+       if nwcversion == 2.0 : whatsIt = readLn(nwcData)
+       comments = readLn(nwcData)
+       
+       header = "\\header {"
+       header += "\n\ttitle = \"%s\"" % title
+       header += "\n\tcomposer = \"%s\"" % author
+       header += "\n\tcopyright = \\markup \\teeny \"%s\"" % copyright1
+       header += "\n\tfooter = \"%s\"" % copyright2
+       header += "\n\t%%{ %s %%}" % comments
+       header += "\n}"
+               
+       # TO ADD IN DEFAULT BLANK FIELDS TO KEY IN
+       print 'title,author,copyright1,copyright2,comments: ', (title,author,copyright1,copyright2,comments)
+       return header
+
+# Page Setup
+def getPageSetup(nwcData):
+       # ??
+       margins = getMargins(nwcData)
+       #getContents(nwcData)
+       #getOptions(nwcData)
+       staffSize = getFonts(nwcData)
+       barlineCount = 0
+       return margins, staffSize
+       
+def getMargins(nwcData):
+       global measureStart
+       #readTill(nwcData,'\x01')       # not correct, should read 9 bytes (HdR)
+       temp = nwcData.read(9)
+       if debug : print "skipping ", binascii.hexlify(temp)
+       measureStart = ord( nwcData.read(1) )
+       pad(nwcData,1)
+       # get string size 43
+       margins = readLn(nwcData)
+       print 'Start measure ', measureStart
+       print 'margins ', margins
+    #mirrorMargines
+       #UOM
+       return margins 
+
+def getOptions(nwcData):
+       # page numbering, from
+       # title page info
+       # extend last system
+       # increase note spacing for larger note duration
+       # staff size
+       # staff labels (none, first systems, top systems, all systems
+       # measure numbers none, plain, circled, boxed
+       # measure start
+       return
+
+def getFonts(nwcData):
+       # 12 Times
+       #readTill(nwcData,'\xFF')       #not correct, should read 36 bytes (HdR)
+       nwcData.read(36)
+       n = nwcData.read(1)
+       print "Staff size: ", ord(n)
+       pad(nwcData,1)
+       for i in range (12):
+               # Font Name
+               font = readLn (nwcData)
+               
+               # 00
+               
+               # Style 'Regular' 'Italic' 'Bold' 'Bold Italic'
+               style = ord(nwcData.read(1)) & 3
+               
+               # Size
+               size = ord(nwcData.read(1))
+               
+               ## 00
+               nwcData.seek(1,1)
+               
+               # Typeface
+               # 00 Western, b1 Hebrew
+               typeface = nwcData.read(1)
+               
+               if debug: print 'Font detected' , font, 'size',size, 'style ', style, ' typeface',typeface
+               
+       return ord(n)
+                 
+def findNoOfStaff(nwcData):
+       # Infomation on Staffs \x08 00 00 FF 00 00 n
+       data = 0;
+       
+       readTill(nwcData,'\xFF')
+       if debug: print "Where am I? ", nwcData.tell()
+
+       nwcData.read(2)
+       
+       layering = nwcData.read(1) # FF or 00
+       
+       noOfStaffs = ord(nwcData.read(1))
+       nwcData.read(1)
+       if debug: print noOfStaffs, " noOfStaffs found"
+       return noOfStaffs
+
+def findStaffInfo(nwcData):
+       # Properties for Staff
+               # General 
+                       # Name.
+                       # Group
+                       # Ending Bar
+               # Visual
+                       # Verticle Upper Size
+                       # Verticle Lower Size
+                       # Style
+                       # Layer Next Staff
+                       # Color
+               # Midi
+                       # Part Volume
+                       # Stereo Pan
+                       # Transposition
+                       # Muted
+                       # PlayBack Device
+                       # Playback Channel
+               # Instrument
+                       # Patch Name
+                       # Patch List Type
+                       # Bank Select 
+                       # Controller0
+                       # Controller32
+       # Staff Lyrics
+               # LineCount
+               # AlignSyllableRule
+               # StaffPlacementAligment
+               # StaffPlacementOffset
+               # StaffPropertiesVerticleSizeUpper
+               # StaffPropertiesVerticleSizeLower
+               
+       format = ''
+       staffName = readLn(nwcData)
+       format += "\\context Staff = %s " % staffName # or voice or lyrics 
+       
+       groupName = readLn(nwcData) # HOW TO ORGANISE THEM??
+       
+       endbar = ord(nwcData.read(1)) & 7 # mask all but last bits
+       print 'end ',endbar
+       endingBar = ending[endbar] #  10 --> OC for lyrics?  10000 1100
+       
+       muted = ord(nwcData.read(1)) & 1
+       nwcData.read(1)
+       
+       channel = ord(nwcData.read(1)) + 1
+       nwcData.read(9)
+       
+       stafftype = staffType[ord(nwcData.read(1))&3]
+       nwcData.read(1)
+       
+       uppersize = 256 - ord(nwcData.read(1))  # - signed +1 )& 2^7-1 )
+       readTill(nwcData,'\xFF')
+       
+       lowersize = ord(nwcData.read(1))
+       ww = nwcData.read(1) 
+       print '[uppersize,lowersize]',[uppersize,lowersize]
+       
+       noOfLines = ord(nwcData.read(1))
+       print '[staffName,groupName,endingBar,stafftype,noOfLines]', [staffName,groupName,endingBar,stafftype,noOfLines]
+       
+       layer = ord(nwcData.read(1)) & 1
+       
+       # signed transposition
+       # FF?
+       
+       partVolume = ord(nwcData.read(1))
+       ord(nwcData.read(1))
+       
+       stereoPan = ord(nwcData.read(1))
+       if nwcversion == 1.7:
+               nwcData.read(2)
+       else:
+               nwcData.read(3)
+       
+       nwcData.read(2)
+       #lyrics = ord(nwcData.read(1)) & 1
+       lyrics = readInt(nwcData)
+       noOfLyrics = readInt(nwcData)
+       
+       lyricsContent = ''
+       if lyrics:
+               lyricOptions = readInt(nwcData)
+               nwcData.read(3)
+               for i in range(noOfLyrics):
+                       print 'looping ',i, 'where', nwcData.tell(), 'NoOfLyrics:', noOfLyrics
+                       #lyricsContent  += '\\ \lyricmode { ' # lyrics
+                       lyricsContent = str( getLyrics(nwcData) ) #
+                       #lyricsContent  += '}'
+               nwcData.read(1)
+       
+       nwcData.read(1)
+       color = ord(nwcData.read(1)) & 3 #12
+       
+       noOfTokens = readInt(nwcData)
+       print noOfTokens, " Tokens found", nwcData.tell()
+       return staffName, endingBar, noOfTokens, format, lyricsContent
+
+def pad(nwcData, length):
+       nwcData.seek(length,1)
+
+def readTill(nwcData, delimit):
+       data = ''
+       value = ''
+       while data!=delimit:
+               value += data
+               data = nwcData.read(1)
+               
+       return value
+       
+def readLn(nwcData):
+       return readTill (nwcData,'\x00')
+       # reads until 00 is hit
+       # od oa == \n
+
+def readInt(nwcData):
+       data = nwcData.read(2)
+       no = ord(data[0])
+       no += ord(data[1]) * 256
+       return no
+
+
+def getLyrics(nwcData):
+       
+       data = ''
+       print 'reach'
+       data = nwcData.read(1)
+       if data == '': return
+       blocks = ord( data )
+       if blocks==4: blocks = 1
+       if blocks==8: blocks = 2
+       if blocks == 0: return 
+       data = ''
+       lyricsLen = readInt(nwcData)
+       
+       print 'blocks ',blocks, 'lyrics len', lyricsLen, 'at ', nwcData.tell()
+       
+       nwcData.read(1)
+       for i in range (blocks):
+               data += nwcData.read(1024)
+       
+       lyrics = data[1:lyricsLen-1]
+                               
+       lyrics = lyrics.replace( "\x00", "_ " )
+
+       print 'lyrics ', lyrics
+       return lyrics
+       
+def getDuration(data):
+       durationBit = ord(data[2]) & 7
+       durationDotBit = ord(data[6]) 
+       
+       duration = durations[durationBit]
+       absDuration = revDurations[durationBit]
+       if (durationDotBit & 1<<2):
+               durationDot = '.'
+               absDuration += revDurations[durationBit + 1]
+       elif (durationDotBit & 1):
+               durationDot = '..'
+               absDuration += revDurations[durationBit + 1] + revDurations[durationBit + 1]
+       else :
+               durationDot = ''
+       return duration + durationDot
+
+def getKey(data):
+       data = binascii.hexlify(data)
+       
+       if (keysigs.has_key(data)):
+               return '\key ' + keysigs[data]
+       return '% unknown key'
+
+def getLocation(data):
+       offset = ord(data[8]);
+       if offset > 127 :
+               return 256-offset
+       
+       #next statement doesn't work for me     (HdR)   
+       #if (ord(data[9])>>3 & 1):
+       #       return -offset
+       
+       return -offset
+       
+       return offset
+
+def getAccidental(data):
+       data = ord(data)
+       data = (data & 7 )
+       return acdts[data]
+
+def getDynVariance(data):
+       data = ord(data)
+       data = (data & 7 )
+       return dynVariance[data]
+
+def getPerfStyle(data):
+       data = ord(data)
+       temp = '_\\markup {\\small \\italic \\bold {' + perfStyle[data] + '}}'
+       return temp
+
+def getTempoVariance(data):
+       data = ord(data)
+       if data == 0 or data == 1 :
+               temp = '\\' + tempoVariance[ data ]
+       else:
+               temp = '_\\markup {\\small \\italic \\bold {' + tempoVariance[data] + '}}'
+       return temp
+
+def getNote(data):
+       
+       # pitch
+       pitch = getLocation(data)
+       
+       # get Accidentals
+       accidental =  getAccidental(data[9])
+       
+       # get Relative Duration
+       duration = getDuration(data)
+       
+       # check stems
+       stem = ord(data[4])
+       stem = (stem >> 4) & 3
+       
+       # check beam
+       beam = ord(data[4]) & 3
+       
+       # triplets 
+       triplet = triplets [ord(data[4])>>2 & 3 ]
+       
+       # check tie
+       tie = ''
+       if ord(data[6]) >> 4 & 1:
+               tie = '~'
+       
+       staccato = (ord(data[6]) >> 1) & 1
+       accent = (ord(data[6]) >> 5) & 1
+       
+       tenuto = (ord(data[7]) >> 2) & 1
+       grace = (ord(data[7]) >> 5) & 1
+       
+       # check slur
+       slur = slurs[ord(data[7]) & 3 ]
+       #if debug: print "Slur ", ord(data[7]), slur
+       
+       #TODO should use a dictionary
+       return (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto)
+
+def getRelativePitch(lastPitch, pitch):
+       octave = ''
+       diff = pitch - lastPitch
+       if diff>3:
+               for i in range((diff-4 + 7)/7):
+                       octave += "'"
+               if octave == '':
+                       octave += "'"
+       elif diff<-3:
+               for i in range((-diff-4 + 7)/7):
+                       octave += ","
+               if octave == '':
+                       octave += ","
+       return octave
+       
+def durVal(duration):
+       where = duration.find('.')
+       
+       if where>-1:
+               durVal = 128/int (duration[:where])
+               nextVal = durVal
+               for i in range(len(duration)-where):
+                       nextVal = nextVal / 2
+                       durVal += nextVal
+               
+       else:
+               durVal = 128/int (duration)
+       return durVal
+       
+def processStaff(nwcData):
+       keysigCount =0
+       timesigCount=0
+       noteCount=0
+       restCount=0
+       staffCount=0
+       clefCount=0
+       textCount=0      
+       tempoCount=0
+       barlineCount = measureStart - 1
+       dynamicCount = 0
+       
+       lastPitch = scale.index('c')
+       lastDuration = 0
+       lastClef = scale.index(clefs[0])  # index referenced to note of last clef
+       lastStem = 0
+       lastTimesig = 1
+       
+       lastKey = { 'c': '', #c 
+       'd': '', 'e': '', 'f': '', 'g': '', 'a': '', 'b': '' }
+       currentKey = lastKey.copy()
+       
+       data = 0
+       token = 1
+       
+       result = ""
+       result += "\n\t\\new Staff {\n\t" + "#(set-accidental-style '" + accidentalStyle + ") "
+       lastChord = 0
+       lastGrace = 0;
+       lastSlur = ' ';
+       
+       (staffName, endingBar, noOfTokens, format, lyrics) = findStaffInfo(nwcData);
+       if debug: print "staff info: name, endingbar, noOfTokens, format, lyrics-"
+       if debug: print staffName, endingBar, noOfTokens, format, lyrics
+       
+       if relativePitch: 
+               result+="\\relative c {"
+       else :
+               result+=" {"
+
+       result+= '\n\n\t% Staff ' + str(staff) + '\t\t(' + staffName + ')\n\n\t'
+       result+= '\\set Staff.instrument = #\"' + staffName + '\"\n\t'
+       result+= '\\set Score.skipBars = ##t\n\n\t'
+
+       #print "00112233445566778899\n"
+       extra = ''
+       dynamic = ''
+       style = ''
+       # the juice
+       
+       dualVoice = 0
+       while data!="":
+               
+               token += 1
+               if token==noOfTokens:
+                       result += "\\bar \"" + endingBar + "\"\n\t\t"
+                       
+                       if dualVoice == 1:         # no beams and slurs with two voices
+                               result += "%Todo: check for slurs and beams in the bar above\n\t\t"
+                       dualVoice = 0
+                       
+                       result += "}\n\t"
+                       if lyrics!='':
+                               result += '\n\t\t\\addlyrics{ ' + lyrics + '}'
+                       result += "\n\t}\n\t"
+                       print "going next staff! %s" % nwcData.tell()
+                       break
+               
+               
+               if nwcversion==1.7:
+                       nwcData.seek(2,1)
+               
+               data = nwcData.read(1)
+               #print 'test', data
+               
+               # clef
+               if data=='\x00':
+                       data = nwcData.read(6)
+                       clefCount += 1
+                       if debug: print binascii.hexlify(data), '  = clef ',
+                       
+                       key = ord(data[2]) & 3  
+                       octave = ord(data[4]) & 3
+                       # print binascii.hexlify(data) , "CLEF? "
+                       lastClef = scale.index(clefs[key]) + octaves[octave]
+                       #TODO check for octave shifts _8
+                       #lastClef += clefShift[octave] # on ottava don't shift, just print 8va 
+                       if debug: print clefNames[key], clefOctave[octave]
+                       result += '\clef "' + clefNames[key] + clefOctave[octave]+ '"\n\t\t'
+                       
+               # key signature
+               elif data=='\x01':
+                       data = nwcData.read(12)
+                       keysigCount = keysigCount + 1
+                       if debug: print binascii.hexlify(data), '  = Key signature ',
+                       
+                       #
+                       flatBits = ord(data[2])
+                       sharpBits = ord(data[4])
+                       
+                       for note in lastKey.keys():
+                               noteInd = ['a','b','c','d','e','f','g'].index(note)
+                               if (flatBits >> noteInd & 1):
+                                       lastKey[note] = 'es'
+                               elif (sharpBits >> noteInd & 1):
+                                       lastKey[note] = 'is'
+                               else:
+                                       lastKey[note] = ''
+                       
+                       currentKey = lastKey.copy()
+                       if debug: print getKey(data[1:5])
+                       result = result + getKey(data[1:5]) + "\n\t\t"
+                       
+                       #print "data", binascii.hexlify(data)
+                       #print "flat", binascii.hexlify(flatBits)
+                       #print "sharp", binascii.hexlify(data[4])
+                       #print getKey(data[1:5])
+                       
+               
+               # barline
+               elif data=='\x02':
+                       data = nwcData.read(4)
+                       #if debug: print '  = Barline ', barlines[ ord(data[2]) ]
+                       #if debug: print binascii.hexlify(data)
+                       barlineCount += 1
+                       currentKey = lastKey.copy()
+                       
+                       if ( data[2] == '\x00' ):
+                               result += "|\n\t\t"
+                       else:
+                               result += "\\bar \"" + barlines[ ord(data[2]) ] + "\"\n\t\t"
+                       
+                       if dualVoice == 1:         # no beams and slurs with two voices
+                               result += "%Todo: check for slurs and beams in the bar above\n\t\t"
+                       
+                       if (barlineCount % barLinesComments == 0):
+                               result += "\n\t\t% Bar " + str(barlineCount + 1) + "\n\t\t" 
+                               #print '.',
+                               print 'Bar ', barlineCount, ' completed,'
+                       
+                       dualVoice = 0
+               # Repeat
+               
+               elif data=='\x03':
+                       if debug: print "Repeat",
+                       data = nwcData.read(4)
+                       if debug: print binascii.hexlify(data),
+                       if debug: print "  = repeat: ", ord( data[2] )
+                       result += "%Todo: place alternatives for \\repeat volta " + str(ord( data[2] )) + "\n\t\t"
+               
+               # Instrument Patch
+               elif data=='\x04':
+                       if debug: print "Instrument Patch",
+                       data = nwcData.read(10)
+                       if debug: print binascii.hexlify(data)
+                       #readLn(nwcData)
+                       #readLn(nwcData)
+                       #readLn(nwcData)
+       
+               # timesig
+               elif data=='\x05':
+                       data = nwcData.read(8)
+                       if debug: print binascii.hexlify(data),
+                       timesigCount = timesigCount + 1 
+                       beats = ord(data[2])
+                       beatValues = [ 1, 2, 4, 8 ,6, 32 ]
+                       beatValue = beatValues[ord(data[4])]
+                       timesig = str(beats) + "/"  + str(beatValue)
+                       if debug: print '  = Timesig', timesig
+                       lastTimesig = timesigValues[timesig]
+                       result += "\\time " + timesig + " "
+                       
+               # Tempo
+               elif data=='\x06':
+                       if debug: print "Tempo  ",
+                       data = nwcData.read(7)
+                       if debug: print binascii.hexlify(data)
+                       tempo = readLn(nwcData)
+               
+                       # byte 4 length, byte 6 note, 
+                       tempoNote = data[6]
+                       tempoDuration = ord(data[4])
+                       if debug: print "duration ", tempoDuration
+                       
+                       if ( data[6] == '\x00' ):
+                               tempoNote = '8'
+                               tempoMultiply = int( tempoDuration * 2)
+                       elif ( data[6] == '\x01' ):
+                               tempoNote = '8.'
+                               tempoMultiply = int( tempoDuration / 0.75 )
+                       elif ( data[6] == '\x02' ):
+                               tempoNote = '4'
+                               tempoMultiply = tempoDuration
+                       elif ( data[6] == '\x03' ):
+                               tempoNote = '4.'
+                               tempoMultiply = int( tempoDuration / 1.5)
+                       elif ( data[6] == '\x04' ):
+                               tempoNote = '2'
+                               tempoMultiply = int( tempoDuration / 2)
+                       elif ( data[6] == '\x05' ):
+                               tempoNote = '2.'
+                               tempoMultiply = int( tempoDuration / 3)
+
+                       result += '\n\t\t\\tempo ' + tempoNote + '=' + str( tempoMultiply ) + ' '
+                       tempoCount = tempoCount + 1     
+               
+               # dynamics
+               elif data=='\x07':
+                       dynamicCount = dynamicCount + 1
+                       data = nwcData.read(9)
+                       if debug: print binascii.hexlify(data),
+                       dynamic = dynamics[ ord(data[4]) & 7 ]
+                       if debug: print '  = Dynamic ' + dynamic
+                       
+               # note
+               elif data=='\x08':
+                       data = nwcData.read(10)
+                       noteCount = noteCount + 1
+                       
+                       if debug: print 'note  ', binascii.hexlify(data) , noteCount , nwcData.tell(),
+                       
+                       (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = getNote(data)
+                       
+                       if debug: print pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto
+                       
+                        
+                       articulate = ''
+                       if staccato: articulate+= '-.'
+                       if accent: articulate+= '->'
+                       if tenuto: articulate+= '--'
+                       
+                       beam = beams[beam]
+                       
+                       chordMatters = ''
+                       if lastChord>0 and beam==']' :
+                               if debug: print 'Chord ] ', durVal(duration), lastChord
+                               chordMatters = ' } >> '
+                               lastChord = 0
+                       elif lastChord>0:
+                               if debug: print 'Chord last ', durVal(duration), lastChord
+                               dur = durVal(duration)
+                               #lastChord = 1.0/((1.0 / lastChord) - (1.0/durVal(duration)))
+                               lastChord -= dur 
+                               
+                               if lastChord <= 0 :
+                                       chordMatters = ' } >> '
+                                       lastChord = 0
+                                       
+                               
+                       
+                       if not insertBeaming: beam = ''
+                       
+                       # pitch
+                       pitch += lastClef
+                       note = scale[pitch]
+                       
+                       natural = ''
+                                               
+                       # get Accidentals
+                       if ( accidental == '!' ) :                 # also do forced naturals
+                               natural = accidental
+                               accidental = ''
+                       
+                       if (accidental!='auto'):
+                               currentKey[note[0]] = accidental
+                               
+                       accidental = currentKey[note[0]]
+                       
+                       if (relativePitch):
+                               octave = getRelativePitch(lastPitch, pitch)
+                               lastPitch = pitch
+                       else:
+                               octave = note[1:]
+                       pitch = note[0] + accidental + octave
+                       
+                       # get Relative Duration
+                       if (relativeDuration):
+                               if (lastDuration==duration):
+                                       duration = ''
+                               else:
+                                       lastDuration = duration
+                       
+                       # check stems
+                       if insertSteming and (stem!= lastStem) :
+                               lastStem = stem
+                               stem = stems[stem]
+                       else :
+                               stem = ''
+                       
+                       # normal note
+                       if extra!='':
+                               extra = '-"' + extra + '"'
+                       
+                       if grace and not lastGrace: result += '\\' + stdGrace + " { "
+                       
+                       if nwcversion == 2.0:
+                               if ( slur == ' ' or slur == '' ) and lastSlur == '(' : 
+                                       slur = ')'
+                                       lastSlur = ' '
+                                       if debug : print ' slur closed'
+                               elif slur == '(' and lastSlur == '(' : 
+                                       slur = ' '
+                                       lastSlur = '('
+                                       if debug : print ' slur continued'
+                               elif slur == '(' and lastSlur == ' ' : 
+                                       slur = '('
+                                       lastSlur = '('
+                                       if debug : print ' slur opened'
+                                      
+                       if dualVoice == 1:         # no beams and slurs with two voices
+                               beam = ''
+                               slur = ''
+
+                       if not grace and lastGrace: result += " } "
+                       result += triplet[0] + stem + pitch + natural + duration + articulate + dynamic + style + extra 
+                       result += slur + tie + beam + triplet[1]  +chordMatters  +  " "
+                       
+                       
+                       # reset
+                       lastGrace = grace
+                       extra = ''
+                       dynamic = ''
+                       style = ''
+               # rest
+               elif data=='\x09':
+                       data = nwcData.read(10)
+                       if debug: print 'rest  ', binascii.hexlify(data) , noteCount , nwcData.tell()
+                       (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = getNote(data)
+                       
+                       restCount = restCount + 1 
+                       
+                       # get Relative Duration
+                       duration = getDuration(data)
+                       if duration == '1':
+                               duration = lastTimesig
+                       if (relativeDuration):
+                               if (lastDuration==duration):
+                                       duration = ''
+                               else:
+                                       lastDuration = duration
+                                       
+                       result = result + triplet[0] + 'r' + str(duration) + dynamic + triplet[1] + " "
+                       dynamic = ''
+
+               #chord starting with a rest
+               elif data == '\x12':
+                       data = nwcData.read(12)        # rest info now in data      
+                        print binascii.hexlify(data), "Chord started with rest. Rest skipped for now"
+                       (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = getNote(data)
+                       result += "\n\t\t\\mark \\markup  {r" + duration + "}\n\t\t%Todo: Above rest must be added to next chord\n\t\t"
+                       token -= 1      #doesn't count as token
+                       
+               # chord
+               elif data=='\x0A' : # or data=='\x12':
+                       if data == '\x0a' :
+                               data = nwcData.read(12)
+                       
+                       chordAmt = ord(data[10])
+                       chords = []
+                       chordDur = getDuration(data)
+                       #print 'duration',chordDur
+                                               
+                        print binascii.hexlify(data), "Chord ", chordDur, chordAmt
+                       #print 'no. of notes in chord' , chordAmt
+                       
+                       chord1 = []
+                       chord2 = []
+                       
+                       for i in range(chordAmt):
+                               # rest or note
+                               what = nwcData.read(1)
+                               data = nwcData.read(10)
+                               ha = getNote(data)
+
+                               noteCount = noteCount + 1
+                               if debug: print 'chord ', binascii.hexlify(data) , noteCount , nwcData.tell(),
+                               (pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto) = ha
+                               if debug: print pitch, accidental, duration, stem, beam, triplet, slur, tie, grace, staccato, accent, tenuto
+                               
+                               # add to list
+                               if ha[2] == chordDur or len(chord2) > 0:
+                                       chord1.append( (pitch,accidental ) )
+                                       if beam==0 or beam ==4 :
+                                               lastChord = 0
+                               else : # 2 voices
+                                       chord2.append(  (pitch,accidental, duration) )
+                                       lastChord = durVal(duration)  
+                       
+                       if len(chord2)==0: # block chord
+                               result += triplet[0] + ' <'
+                               for i in range(len(chord1)):
+                                       (pitch,accidental ) = chord1[i]
+                                       pitch += lastClef
+                                       note = scale[pitch]
+                                       
+                                       natural = ''
+                                       
+                                       # get Accidentals
+                                       if ( accidental == '!' ) :                 # also do forced naturals
+                                               natural = accidental
+                                               accidental = ''
+                                       
+                                       if (accidental!='auto'):
+                                               currentKey[note[0]] = accidental
+                                               
+                                       accidental = currentKey[note[0]]
+                                       
+                                       if (relativePitch):
+                                               octave = getRelativePitch(lastPitch, pitch)
+                                               lastPitch = pitch
+                                       else:
+                                               octave = note[1:]
+                                       result += note[0] + accidental + octave + natural + ' '
+                                       
+                               if dualVoice == 1:         # no beams and slurs with two voices
+                                       slur = ''
+
+                               result += '>' + chordDur + slur  + triplet[1] + ' ' # added slur (HdR)
+                               lastPitch = chord1[0][0] + lastClef
+                       else: # 2 voices  Beware, this is experimental and not working good.
+                               dualVoice = 1
+                               result += ' << ' 
+                               for i in range(len(chord2)):
+                                       (pitch,accidental,duration ) = chord2[i]
+                                       pitch += lastClef
+                                       note = scale[pitch]
+                                       
+                                       if ( accidental == '!' ) :                 # also do forced naturals
+                                               natural = accidental
+                                               accidental = ''
+                                       
+                                       if (accidental!='auto'):
+                                               currentKey[note[0]] = accidental
+                                               
+                                       accidental = currentKey[note[0]]
+                                       
+                                       if (relativePitch):
+                                               octave = getRelativePitch(lastPitch, pitch)
+                                               lastPitch = pitch
+                                       else:
+                                               octave = note[1:]
+                                       result += note[0] + accidental + octave + duration + ' '  #no slur, must be done manually
+                               
+                               result += " \\\\ {"
+                               
+                               for i in range(len(chord1)):
+                                       (pitch,accidental ) = chord1[i]
+                                       pitch += lastClef
+                                       note = scale[pitch]
+                                       
+                                       if ( accidental == '!' ) :                 # also do forced naturals
+                                               natural = accidental
+                                               accidental = ''
+                                       
+                                       if (accidental!='auto'):
+                                               currentKey[note[0]] = accidental
+                                               
+                                       accidental = currentKey[note[0]]
+                                       
+                                       if (relativePitch):
+                                               octave = getRelativePitch(lastPitch, pitch)
+                                               lastPitch = pitch
+                                       else:
+                                               octave = note[1:]
+                                       result += note[0] + accidental + octave + chordDur + ' '   # no slur, must be done manually
+                               if lastChord >0 : lastChord = durVal(duration) - durVal(chordDur)
+                               if lastChord==0: result += ' } >> '
+                               # end 2 voices
+                       lastDuration = chordDur
+                       # check if duration / stem  / same 
+                               # < >duration ties,beam, slurs
+               
+               # Pedal
+               elif data=='\x0b':
+                       data = data = nwcData.read(5)
+                       if data[4] == '\x01':
+                               style += '\\sustainDown'
+                       elif data[4] == '\x00':
+                               style += '\\sustainUp'
+                       if debug: print binascii.hexlify(data),
+                       if debug: print '  = Pedal, style: ', style
+               
+               # midi control instruction / MPC
+               elif data=='\x0d':
+                       if debug: print 'midi control instruction',
+                       data = data = nwcData.read(36)
+                       if debug: print binascii.hexlify(data)
+               
+               # fermata / Breath mark
+               elif data=='\x0e':
+                       data = nwcData.read(6)
+                       style += getTempoVariance( data[4] )
+                       if debug: print binascii.hexlify(data),
+                       if debug: print "  = tempo variance, style: ", style
+               
+               # Dynamic variance
+               elif data=='\x0f':
+                       data = nwcData.read(5)
+                       style += getDynVariance( data[4] ) 
+                       if debug: print binascii.hexlify(data),
+                       if debug: print "  = Dynamic variance, style: ", style
+       
+               # Performance Style
+               elif data=='\x10':
+                       data = nwcData.read(5)
+                       style += getPerfStyle( data[4] ) 
+                       if debug: print binascii.hexlify(data),
+                       if debug: print "  = Performance Style, style: ", style
+               
+               # text
+               elif data=='\x11':
+                       textCount = textCount + 1
+                       data = nwcData.read(2) #pad
+                       textpos = nwcData.read(1)
+                       data = nwcData.read(2) #pad
+                       text = ''
+                       data = nwcData.read(1)
+                       while data!='\x00':
+                               text += data
+                               data = nwcData.read(1)
+                       
+                       #if text.isdigit() : # check numbers
+                       #       text = "-\\markup -\\number "+ text 
+                       #       #text = "-\\markup {\\number "+ text +"}"
+                       #else :
+                       #       text = '-"' + text + '"'
+                       
+                       if text == 'tr':
+                               style += '\\trill'
+                       else :                            
+                               if insertText :                   
+                                       extra += ' ' + text
+                       
+               
+               # todo
+               else :
+                       print "WARNING: Unrecognised token ",binascii.hexlify(data), " at #", nwcData.tell(), " at Token",  token
+                       
+                       
+                       
+       # output converted file?
+       print "\nStats"
+       print keysigCount, " keysigCount found"
+       print noteCount, " notes found"
+       print staffCount, " staffCount found"
+       print clefCount, " clefCount found"
+       print barlineCount, " barlineCount found"
+       print timesigCount, " timesigCount found"
+       print textCount, " textCount found"
+       print tempoCount, " tempoCount found"
+       print dynamicCount, " dynamicCount found"
+       print restCount, " restCount found"
+       
+       return result
+       
+# Variables
+keysigs = {
+'00000000' : 'c \major % or a \minor' ,
+'00000020' : 'g \major % or e \minor' ,
+'00000024': 'd \major % or b \minor' ,
+'00000064' : 'a \major % or fis \minor' ,
+'0000006c' : 'e \major % or cis \minor' ,
+'0000006d' : 'b \major % or gis \minor' ,
+'0000007d' : 'fis \major % or dis \minor' ,
+'0000007f' : 'cis \major % or ais \minor' ,
+'00020000' : 'f \major % or d \minor' ,
+'00120000' : 'bes \major % or g \minor' ,
+'00130000' : 'ees \major % or c \minor' ,
+'001b0000' : 'aes \major % or f \minor' ,
+'005b0000' : 'des \major % or bes \minor' ,
+'005f0000' : 'ges \major % or ees \minor' ,
+'007f0000' : 'ces \major % or a \minor'
+}
+
+acdts = ( 'is', 'es', '!' ,'isis', 'eses', 'auto'  ) 
+
+dynVariance = ( '\\<',   # crescendo
+                               '\\>',   # decrescendo
+                               '\\>',   # diminuendo
+                               '\\rfz', # rinforzando
+                               '\\sfz'  # sforzando
+                               )
+
+perfStyle =   ( 'ad lib.',
+                               'animato',
+                               'cantabile',
+                               'con brio',
+                               'dolce',
+                               'espressivo',
+                               'grazioso',
+                               'legato',
+                               'maestoso',
+                               'marcato',
+                               'meno mosso',
+                               'poco a poco',
+                               'piu mosso',
+                               'semplice',
+                               'simile',
+                               'solo',
+                               'sostenuto',
+                               'sotto voce',
+                               'staccato',
+                               'subito',
+                               'tenuto',
+                               'tutti',
+                               'volta subito'
+                               )
+
+clefs = { 0 : "b'",
+          1 : "d",
+          2 : "c'",
+          3 : "a'",
+        }
+
+clefNames = { 0: 'treble',
+          1: 'bass',
+          2: 'alto',
+          3: 'tenor',
+        }
+octaves = { 0: 0, 1:7, 2:-7 }
+scale = [   # this list is taken from lilycomp
+        "c,,,","d,,,","e,,,","f,,,","g,,,","a,,,","b,,,",
+        "c,,","d,,","e,,","f,,","g,,","a,,","b,,",
+        "c,","d,","e,","f,","g,","a,","b,",
+        "c","d","e","f","g","a","b",
+        "c'","d'","e'","f'","g'","a'","b'",
+        "c''","d''","e''","f''","g''","a''","b''",
+        "c'''","d'''","e'''","f'''","g'''","a'''","b'''",
+        "c''''","d''''","e''''","f''''","g''''","a''''","b''''",
+        "c'''''","d'''''","e'''''","f'''''","g'''''","a'''''","b'''''",
+        ]
+
+stems = [ '\stemNeutral ', '\stemUp ', '\stemDown ']
+
+# what is slur  3? continuation of existing slur? (HdR)                                                   
+slurs = [ '', '(' , ')', '' ]
+
+tempoVariance = ['breathe',
+               'fermata',
+               'accel.',
+               'allarg.',
+               'rall.',
+               'ritard.',
+               'rit.',
+               'rubato',
+               'string.'
+                ]
+dynamics = [    '\\ppp ',
+               '\\pp ',
+               '\\p ',
+               '\\mp ',
+               '\\mf ',
+               '\\f ',
+               '\f ',
+               '\\fff '
+               ]
+triplets = [ 
+       ('' , '' ),
+       ( '\\times 2/3 { ', '') ,
+       ('' , '' ),
+       ('' , ' }' ),
+       ]
+
+durations    = ( '1','2','4','8','16','32','64' ) 
+revDurations = (  64, 32, 16,  8,   4,   2,   1 ) 
+
+barlines = (
+     '|', # 'Single'
+     '||', # 'Double'
+     '.|', # SectionOpen
+     '|.', # SectionClose
+     '|:', # MasterRepeatOpen
+     ':|', # MasterRepeatClose
+     '|:', # LocalRepeatOpen
+     ':|', # LocalRepeatClose
+)
+
+ending = (
+'|.', # SectionClose
+':|', # MasterRepeatClose
+'|', # 'Single'
+'||', # 'Double'
+'' # Open hidden
+)
+
+staffType = (
+'Standard' , # Standard
+'Upper Grand Staff' , # Upper Grand Staff
+'Lower Grand Staff' , # Lower Grand Staff
+'Orchestra' , # Orchestra
+)
+
+
+beams = [ '', '[', '',']' ]
+
+
+# end ' \bar "|."'
+
+# Notation Properties
+# extra accidental spacing
+# extra note spacing
+# muted
+# no ledger lines
+# slurdirection
+# tiedirection
+# lyricsyllable
+# visability 
+# show printed
+# item color
+
+#dynamics
+# cmd = DynamicVariance
+# Decrescendo \setTextCresc \<
+# setTextCresc Crescendo \>  setHairpinCresc
+# Dynamics stop '\! '
+# style = ff pp
+
+clefOctave = [ '' , '^8', '_8' , '' ]
+clefShift = [0,7,-7, 0]
+
+
+# '#(set-accidental-style '#39'modern-cautionary)'
+#(ly:set-point-and-click 'line-column)
+#(set-global-staff-size 20)
+
+timesigValues = { 
+       '4/4' : '1', '3/4' : '2.', '2/4' : '2', '1/4' : '1', '6/4' : '2.', '5/4' : 1,
+       '1/8' : '8', '2/8' : '4', '3/8' : '4.', '6/8' : '2.',
+       '4/8' : '2', '9/8' : '12', '12/8' : '1',
+       '2/2' : '1', '4/2' : '0', '1/2' : '2', 
+        }
+
+print "python nwc2ly is running..."
+try:
+
+       nwcData = open( nwcfile,'rb')
+       
+       # check if its a readable nwc format
+       # compressed - [NWZ]
+       # uncompressed - [NoteWorthy ArtWare] [NoteWorthy Composer]
+       format = nwcData.read(5)
+       if format== '[NWZ]':
+               nwcData.seek(1,1)
+               print 'Compressed NWC detected!'
+               print 'Dumping to uncompressed NWC format and attemping conversion soon...'
+               uncompress = open ('uncompressed.nwc','wb')
+               uncompress.write(zlib.decompress(nwcData.read()))
+               uncompress.close()
+               print 'Inflating done. Now opening new file...'
+               nwcData.close()
+               nwcData = open( 'uncompressed.nwc','rb')
+               nwcData.seek(6)
+       elif format!= '[Note':
+               print 'Unknown format, please use an uncompress NWC format and try again.'  
+               sys.exit()
+       
+       
+       if debug: print "Getting file format"
+       getFileFormat(nwcData)
+       if debug: print "Getting file info"
+       fileInfo = getFileInfo(nwcData)
+       if debug: print "Getting page setup"
+       (margins, staffSize) = getPageSetup(nwcData)
+       
+       #0.09850000 0.20094000 0.29944000 0.50037998
+       #0123456789012345678901234567890123456789012345
+       topMargin = margins[0:9]
+       leftMargin = margins[11:20]
+       rightMargin = margins[22:31]
+       bottomMargin = margins[33:42]
+       
+       topMargin = round( float(topMargin), 2 )
+       bottomMargin = round( float(bottomMargin), 2)
+       leftMargin = round( float(leftMargin), 2 )
+       rightMargin = round( float(rightMargin), 2 )
+       if debug: print "top ", str(topMargin)
+       if debug: print "bottom ", str(bottomMargin)
+       if debug: print "left ", str(leftMargin)
+       if debug: print "right ", str(rightMargin)
+       
+       resultFile = '%% Generated from python nwc2ly converter v%s by Joshua Koo (joshuakoo@myrealbox.com)' % nwc2lyversion
+       resultFile += '\n\\paper \n{\n'
+       resultFile += '\t#(set-paper-size "' + paperSize + '")\n'
+       resultFile += '\t#(set-global-staff-size ' + str(staffSize) + ')\n'
+       resultFile += '\ttopmargin = ' + str(topMargin) + '\\in\n'
+       resultFile += '\tleftmargin = ' + str(leftMargin) + '\\in\n'
+       resultFile += '\trightmargin = ' + str(rightMargin) + '\\in\n'
+       resultFile += '\tbottommargin = ' + str(bottomMargin) + '\\in\n'
+       resultFile += '\traggedlastbottom = ##'
+       if fillLast: 
+               resultFile += 'f\n' 
+       else: 
+               resultFile += 't\n'
+       resultFile += '}'
+       resultFile += '\n\n\\version "' + LilyPondVersion + '"'
+       resultFile += "\n"
+       
+   # START WORK
+       resultFile+= fileInfo
+       resultFile+= "\n\n\\score {"
+       resultFile+= "\n\t<<\n\t\t"
+       
+    
+       noOfStaffs = findNoOfStaff(nwcData);
+       
+       for staff in range(1,noOfStaffs+1):
+               print "\n\nWorking on Staff", staff
+               result = processStaff(nwcData)
+               #print result
+               resultFile += result
+       
+       resultFile+= "\n\t>>"
+#      resultFile+= "\n\t\layout {}"
+#      resultFile+= "\n\t\midi {}"
+       resultFile+= "\n}"
+       nwcData.close()
+       
+       if lyfile=='':
+               print 'Dumping output file to screen'
+               print resultFile
+       else :
+               write = open( lyfile ,'w')
+               write.write (resultFile)
+               write.close()
+
+except IOError:
+       print 'File does not exist or an IO error occurred'
+except Exception, e: #KeyError
+       print "Error while reading data at ", nwcData.tell() ,"\n"
+       print 'Dumping whatever result first'
+       print resultFile
+       print Exception, e
+       traceback.print_exc()
+
+print
+print
+print "Please send all bugs and requests to joshuakoo@myrealbox.com"