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
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