Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get a note at the time its suposed to play #155

Closed
Wall3rHM2 opened this issue Aug 19, 2018 · 2 comments
Closed

Get a note at the time its suposed to play #155

Wall3rHM2 opened this issue Aug 19, 2018 · 2 comments

Comments

@Wall3rHM2
Copy link

Can someone help me get a note at the time its suposed to play in reading a file?
e.g: After 2 secs a C note plays then after 1 sec, a G note.

@MaurizioB
Copy link

MaurizioB commented Aug 20, 2018

First, you need to know the tick resolution from Pattern.resolution, which is the resolution per beat (the smallest fraction of a beat in which events can happen). It is better to convert all the pattern to absolute ticks, as they are relative by default, using Pattern.make_ticks_abs(). Then you have to iter through all events in all tracks to map all tempo events SetTempoEvents and then interpolate those changes.
It's not that easy if there are tempo changes in the file.
If you are lucky and only have one tempo event (or none, which means tempo is default, 120bpm) it's not that hard, as you can compute everything by dividing 60 by bpm and resolution just once; here's a simple example:

notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
#uncomment this if you want absolute time
#pattern.make_ticks_abs()

tickLength = None
for track in pattern:
    for event in track:
        if isinstance(event, midi.SetTempoEvent):
            tickLength = 60. / event.bpm / pattern.resolution
            break
    else:
        continue
    break
else:
    tickLength = .5 / pattern.resolution

def getSeconds(tick):
    return tickLength * tick

for track in pattern:
    for event in track:
        if isinstance(event, midi.NoteEvent):
            octave, note = divmod(event.pitch, 12)
            print('Note {}{} plays at {:.02f} seconds'.format(
                notes[note], octave, getSeconds(event.tick)))

Also, have a look at this: #62

@Wall3rHM2
Copy link
Author

Thank you very much, there was before an related issue in the original python-midi but i couldn't get help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants