text: import midi
  import numpy as np
  import audiolazy as audio
  
  
  lowerBound = 24
  upperBound = 102
  span = upperBound-lowerBound
  
  
  def midiToNoteStateMatrix(midifile, squash=True, span=span):
      pattern = midi.read_midifile(midifile)
  
      timeleft = [track[0].tick for track in pattern]
  
      posns = [0 for track in pattern]
  
      statematrix = []
      time = 0
  
      state = [[0,0] for x in range(span)]
      statematrix.append(state)
      condition = True
      while condition:
          if time % (pattern.resolution / 4) == (pattern.resolution / 8):
              # Crossed a note boundary. Create a new state, defaulting to holding notes
              oldstate = state
              state = [[oldstate[x][0],0] for x in range(span)]
              statematrix.append(state)
  
          for i in range(len(timeleft)): #For each track
              if not condition:
                  break
              while timeleft[i] == 0:
                  track = pattern[i]
                  pos = posns[i]
  
                  evt = track[pos]
                  if isinstance(evt, midi.NoteEvent):
                      if (evt.pitch < lowerBound) or (evt.pitch >= upperBound):
                          pass
                          # print "Note {} at time {} out of bounds (ignoring)".format(evt.pitch, time)
                      else:
  
                          if isinstance(evt, midi.NoteOffEvent) or evt.velocity == 0:
                              state[evt.pitch-lowerBound] = [0, 0]
                          else:
                              state[evt.pitch-lowerBound] = [1, 1]
                  elif isinstance(evt, midi.TimeSignatureEvent):
                      if evt.numerator not in (2, 4):
                          # We don't want to worry about non-4 time signatures. Bail early!
                          # print "Found time signature event {}. Bailing!".format(evt)
                          out =  statematrix
                          condition = False
                          break
                  try:
                      timeleft[i] = track[pos + 1].tick
                      posns[i] += 1
                  except IndexError:
                      timeleft[i] = None
  
              if timeleft[i] is not None:
                  timeleft[i] -= 1
  
          if all(t is None for t in timeleft):
              break
  
          time += 1
  
      S = np.array(statematrix)
      statematrix = np.hstack((S[:, :, 0], S[:, :, 1]))
      statematrix = np.asarray(statematrix).tolist()
      return statematrix
  
  def noteStateMatrixToMidi(statematrix, name="example", span=span):
      statematrix = np.array(statematrix)
      if not len(statematrix.shape) == 3:
          statematrix = np.dstack((statematrix[:, :span], statematrix[:, span:]))
      statematrix = np.asarray(statematrix)
      pattern = midi.Pattern()
      track = midi.Track()
      pattern.append(track)
      print (statematrix.shape)
      span = upperBound-lowerBound
      tickscale = 100
  
      lastcmdtime = 0
      prevstate = [[0,0] for x in range(span)]
      for time, state in enumerate(statematrix + [prevstate[:]]):
          offNotes = []
          onNotes = []
          for i in range(span):
              n = state[i]
              p = prevstate[i]
              if p[0] == 1:
                  if n[0] == 0:
                      offNotes.append(i)
                  elif n[1] == 1:
                      # offNotes.append(i)
                      onNotes.append(i)
              elif n[0] == 1:
                  onNotes.append(i)
          for note in offNotes:
              pt = note+lowerBound
              noteoff = midi.NoteOffEvent(tick=(time - lastcmdtime) * tickscale, pitch=pt)
              track.append(noteoff)
              lastcmdtime = time
              print(noteoff)
              # print(audio.midi2str(pt))
          for note in onNotes:
              pt = note + lowerBound
              track.append(midi.NoteOnEvent(tick=(time-lastcmdtime)*tickscale, velocity=40, pitch=pt))
              lastcmdtime = time
              # print(audio.midi2str(pt))
  
          prevstate = state
  
      eot = midi.EndOfTrackEvent(tick=1)
      track.append(eot)
  
  
      midi.write_midifile("{}.midi".format(name), pattern)
  