def annotate(path):
  midi = representation.MidiFile(path)
  (name, version, track, singletrack) = midi.parsename(midi.name)
  key = '{0}-{1}-{2}'.format(name, version, track)

  parts = ['percussion', 'bass', 'accompaniment', 'melody', None]
  part = None
  choice = -1

  index = rbsearch.load_file('data/realbooks/index.csv')
  hits = rbsearch.find(index, name.replace('_', ' '))

  score = 'No score found'
  if len(hits) > 0:
    score = 'Scores found'

  header = '>>> [{0}]\t[#{1}: {2}]\t[{3}]\t({4})'.format(name, track, midi['1'].name.strip(), midi['1'][1].instrument(), score)
  while choice not in [5, 6]:
    # Show options: play file,don't add to corpus
    choice = commandline.menu(header, ['Play file', 'Annotate', 'View info', 'Drop to shell', 'Search score', 'Save and next', 'Skip', 'Abort'])
    # Play file
    if choice == 0:
      midi['1'].play(gui=True)
    # Annotate
    elif choice == 1:

      part = parts[commandline.menu('Choose value for \'part\' attribute.', parts)]
    # View info
    elif choice == 2:
      print 'Name:\t\t{0}\nPath:\t\t{1}\nInstrument:\t{2}\n'.format(\
        midi.name, path, midi['1'][0].instrument())
    # Drop to shell
    elif choice == 3:
      code.interact(local=locals())
    elif choice == 4:
      if len(hits) == 0:
        print 'Sorry! No score found'
        if raw_input('Would you like to search manually? (y/n) ') == 'y':
          query = raw_input('Search for: ')
          hits2 = rbsearch.find(index, query)
          if len(hits2) == 0:
            print 'No results'
            continue
          (song, book) = rbsearch.choose_book(index, hits2)
          rbsearch.view(song, book, 'data/realbooks/songs/')
        continue
      (song, book) = rbsearch.choose_book(index, hits)
      rbsearch.view(song, book, 'data/realbooks/songs/')
    # Abort
    elif choice == 7:
      if raw_input('Are you sure? (y/n) ') is 'y':
        exit(0)
  if choice == 5:
    return {'path':path, 'part':part}
  if choice == 6:
    return None
Example #2
0
 def realbook(self, stdscr=None):
     from jazzr.tools import rbsearch
     from jazzr.corpus import midi
     name = self.name.split('-')[0]
     index = rbsearch.load_file()
     hits = rbsearch.find(index, name.replace('_', ' '))
     if len(hits) > 0:
         (song, book) = rbsearch.choose_book(index, hits, stdscr=stdscr)
         rbsearch.view(song, book)
  def execute(self, match):
    props = match.groupdict()
    if self.mode == self.INSERT:
      self.refreshAnnotation = True
      if props['command'] == ' ' or props['command'] == 'r':
        for (quarters, midipos, pitch, type) in self.annotations:
          if self.cursor == self.quarters2units(quarters) and not type in [Annotation.GRACE, Annotation.ERROR]:
            index = self.annotations.index((quarters, midipos, pitch, type))
            del self.annotations[index]
            self.midipos = midipos
            if props['command'] == ' ':
              return True
            else: break
      if props['command'] == ' ':
        self.addNote()
        self.midipos += 1
        self.seq.control(self.seq.STOP, None)
        self.seq.control(self.seq.SETEVENTS, self.midifile.nonemptytrack().toEvents(self.midipos-1, self.midipos))
        self.seq.control(self.seq.PLAY, True)
      elif props['command'] == 'r':
        # Add rest
        self.addNote(type=Annotation.REST)
      elif props['command'] == 'g':
        # Add gracenote
        self.addNote(type=Annotation.GRACE)
        self.midipos += 1
      elif props['command'] == 'e':
        # Add end marker
        self.addNote(type=Annotation.END)
      elif props['command'] == 'w':
        # Add end marker
        self.addNote(type=Annotation.SWUNG)
        self.midipos += 1
      elif props['command'] == 's':
        # Skip and mark as error
        self.addNote(type=Annotation.ERROR)
        self.midipos += 1
      elif re.match('t[0-9]+$', props['command']):
        # Add a triplet
        division = int(props['arg'])
        if not division: 
          cgui.alert(self.stdscr, 'Enter a beatdivision: t<beatdivision>', block=True)
          return True
        allowed = [math.pow(2, p) for p in range(int(math.log(1/float(self.resolution))/math.log(2)-1))]
        if not division in allowed:
            cgui.alert(self.stdscr, 'Beatdivision {0} is invalid.\n'.format(division) +\
                'Either the resolution doesn\'t allow it (try :set resolution <division>)\n' +\
                'or it\'s not a power of two.\n' +\
                'allowed divisions: {0}'.format(allowed), block=True)
            return True
        pattern = cgui.prompt(self.stdscr, 'Enter notes for a triplet with duration 1/{0}'.format(division), length=3)
        exp = re.compile('([ nr])([ nr])([ nr])$')
        m = exp.match(pattern)
        if m:
          self.refreshAnnotation = True
          for g in range(3):
            position = self.units2quarters(self.cursor) + self.notelength2quarters(g*(1/float(division))/3.0)
            if m.group(g+1) == 'n':
              self.addNote(position=position)
              self.midipos += 1
            elif m.group(g+1) == 'r':
              self.addNote(type=Annotation.REST, position=position)
            elif m.group(g+1) == ' ':
              pass
          self.cursor += self.notelength2units(1/float(division))
        else:
          cgui.alert(self.stdscr, 'Couldn\'t parse input.', block=True)
    elif props['action']:
      if props['action'] == 'q':
        return False
      elif props['action'] == 'i':
        self.mode = self.INSERT
        self.status = 'Entering insert mode'
      elif props['action'] == 'r':
        self.mode = self.INSERT
        self.status = 'Entering insert mode'
      elif props['action'] == 'p':
        if self.mode == self.PLAYING:
          self.seq.control(self.seq.STOP, None)
          self.seq.control(self.seq.LOADFILE, self.midifile)
          self.seq.control(self.seq.SETEVENTS, self.midifile.nonemptytrack().toEvents(self.midipos))
          self.seq.control(self.seq.PLAY, True)
        elif self.mode == self.ANNOTATING:
          mid = generator.annotations2midi([(quarters, pitch, type) for (quarters, midipos, pitch, type) in self.annotations], meter=self.meter, bpm=self.bpm)
          if mid.nonemptytrack():
            self.seq.control(self.seq.STOP, None)
            self.seq.control(self.seq.LOADFILE, mid)
            self.seq.control(self.seq.SETEVENTS, mid.nonemptytrack().toEvents(self.notepos))
            self.seq.control(self.seq.PLAY, True)
        self.status = 'Playing'
      elif props['action'] == 's':
        self.seq.control(self.seq.STOP, None)
      elif props['action'] == 'x' and self.mode == self.ANNOTATING:
        if len(self.annotations) > 0:
          del self.annotations[self.notepos]
          self.refreshAnnotation = True
      elif props['action'] == 's' and self.mode == self.PLAYING:
        pass
    else:
      if props['command'] == 'set ':
        if props['arg1'] == 'correction':
          self.viewcorrection = int(props['arg2'])
          self.refreshMidi = True
          self.status = 'Transposing {0} semitone(s)'.format(props['arg2'])
        elif props['arg1'] == 'beatdiv':
          self.meter.beatdiv = int(props['arg2'])
          self.refreshAnnotation = True
          self.status = 'Changed beatdivision'
        elif props['arg1'] == 'beatsperbar':
          self.meter.beatspb = int(props['arg2'])
          self.refreshAnnotation = True
          self.status = 'Changed beats per bar'
        elif props['arg1'] == 'resolution':
          if not self.setresolution(1/float(props['arg2'])):
            cgui.alert(self.stdscr, 'Invalid resolution.')
          self.refreshMidi = True
          self.refreshAnnotation = True
      elif props['command'] == 'restore':
        if cgui.menu(self.stdscr, 'Restore last session?', ['No', 'Yes']) == 1:
          if not self.load('autosave', 'lastsession'):
            cgui.alert(self.stdscr, 'No session found')
      elif props['command'] == 'save':
        self.save()
      elif props['command'] == 'strip':
        self.strip()
      elif props['command'] == 'subtract':
        self.subtract()
      elif props['command'] == 'score':
        (name, version, track, singletrack) = midi.parsename(self.name)
        index = rbsearch.load_file()
        hits = rbsearch.find(index, name.replace('_', ' '))
        if len(hits) > 0:
          (song, book) = rbsearch.choose_book(index, hits, stdscr=self.stdscr)
          rbsearch.view(song, book)
      elif props['command'] == 'load':
        if not self.load(name=self.name):

          cgui.alert(self.stdscr, 'No annotations found!')
      elif props['command'] == 'q':
        return False
    return True
      standards[name] = m.group(1)


for s in standards.keys():
  parses = []
  exp = re.compile('{0}-parse_([0-9])+.pdf'.format(s))
  pdffiles = []
  print s
  for f in files:
    m = exp.match(f)
    if m:
      pdffiles.append((int(m.group(1)), m.group(0)))
  pdffiles = sorted(pdffiles, key=lambda x: x[0])
  print '{0} parses found.'.format(len(pdffiles))
  for (part, pdf) in pdffiles:
    print 'Loading score'
    index = rbsearch.load_file()
    hits = rbsearch.find(index, s.split('-')[0].replace('_', ' '))
    if len(hits) > 0:
      (song, book) = rbsearch.choose_book(index, hits)
      rbsearch.view(song, book)
    print 'Showing parsetree'
    os.system('evince "{0}/{1}"'.format(directory, pdf))
    if raw_input('Correct parse? (y/n) ') == 'y':
      path = '{0}/{1}-parse_{2}'.format(directory, s, part)
      command = 'cp "{0}" "../Data/corpus/annotated/annotations/{1}/{2}-parse.pickle"'.format(path, standards[s], s)
      os.system(command)
      break