Show
Ignore:
Timestamp:
09/03/08 19:46:38 (4 months ago)
Author:
tasuku
Message:

top to filename...

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/python/mid2flmml/trunk/mid2flmml.py

    r18700 r18744  
     1FILE_NAME = 'tekito.mid' 
     2 
    13import midi 
    24 
    35notes = ['C', 'C+', 'D', 'D+', 'E', 'F', 'F+', 'G', 'G+', 'A', 'A+', 'B'] 
    46globals = [] 
    5 channels = [[] for d in 16 * [None]] 
     7channels = [[] for d in 17 * [None]] 
    68channel_stats = [{ 
    79  'note': None, 
    810  'note_on_time': None, 
     11  'note_off_time': None, 
    912  'velocity': None, 
    1013  'octave': None, 
    11 } for d in 16 * [None]] 
     14} for d in 17 * [None]] 
    1215 
    1316def pitch_to_octave_and_note(pitch): 
    1417  return [pitch / 12, notes[pitch % 12]] 
    1518 
    16 def add_octave_and_note(event, octave, pitch): 
     19def add_length(e, note, from_time, tpq): 
     20  if not note: 
     21    raise 'note is none' 
     22  td = e.time - from_time 
     23  if td == 0: 
     24    if note != 'R': 
     25      raise 'no time diff' 
     26    return 
     27  while td > tpq: 
     28    channels[e.channel].append(note) 
     29    td -= tpq 
     30    if td > 0: 
     31      channels[e.channel].append('&') 
     32  if td > 0: 
     33    channels[e.channel].append(note) 
     34    channels[e.channel].append(str(int(((tpq / td) * 4)))) 
     35 
     36def add_octave_and_note(event, octave, pitch, tpq): 
     37  if channel_stats[e.channel]['note_on_time']: 
     38    print 'WARNING!: detect waon.' 
     39    return 
     40  cmd = '' 
     41  if channel_stats[e.channel]['note_off_time']: 
     42    add_length(e, 'R', channel_stats[e.channel]['note_off_time'], tpq) 
    1743  if channel_stats[e.channel]['velocity'] != e.velocity: 
    1844    channels[e.channel].append('@V%d' % e.velocity) 
     45    channel_stats[e.channel]['velocity'] = e.velocity 
    1946  octave, note = pitch_to_octave_and_note(e.pitch) 
    2047  if channel_stats[e.channel]['octave']: 
     
    2249  else: 
    2350    od = None 
     51  channel_stats[e.channel]['octave'] = octave 
    2452 
    2553  if od == 1: 
     
    2856    pass 
    2957  elif od == -1: 
    30     channels[e.channel].append('<') 
     58    channels[e.channel].append('>') 
    3159  else: 
    3260    channels[e.channel].append('O%d' % octave) 
    33   channels[e.channel].append(note) 
    3461  channel_stats[e.channel]['note'] = note 
    3562  channel_stats[e.channel]['note_on_time'] = e.time 
     63  channel_stats[e.channel]['note_off_time'] = None 
     64 
     65def note_off(e, tpq): 
     66  add_length(e, channel_stats[e.channel]['note'], channel_stats[e.channel]['note_on_time'], tpq) 
     67  channel_stats[e.channel]['note'] = None 
     68  channel_stats[e.channel]['note_on_time'] = None 
     69  channel_stats[e.channel]['note_off_time'] = e.time 
    3670 
    3771mid = midi.MidiFile() 
    38 mid.open('dora_h.mid') 
     72mid.open(FILE_NAME) 
    3973mid.read() 
    4074for track in mid.tracks: 
     
    4781      pass 
    4882    elif e.type == 'SET_TEMPO': 
    49       secPerQuarterNote = 1000000.0 / midi.getNumber(e.data, 3)[0] 
     83      secPerQuarterNote = midi.getNumber(e.data, 3)[0] / 1000000.0 
    5084      if mid.ticksPerQuarterNote: 
    51         tpq = mid.ticksPerQuarterNote 
     85        print "tpq: %d" % mid.ticksPerQuarterNote 
     86        tpq = float(mid.ticksPerQuarterNote) 
    5287      else: 
    53         tpq = mid.ticksPerSecond / secPerQuarterNote 
     88        print "tps: %d" % mid.ticksPerSecond 
     89        tpq = mid.ticksPerSecond * secPerQuarterNote 
    5490      tempo = 60.0 / secPerQuarterNote 
     91      print "tempo: %d" % tempo 
    5592      globals.append('T%d' % tempo) 
    5693    elif e.type == 'PROGRAM_CHANGE': 
    57       globals.append('/* program change ' + str(e.data) + ' */') 
     94      # TODO: http://noike.info/~kenzi/cgi-bin/mml2mp3/doc/FlMML_to_mml2mid.html 
     95      # globals.append('/* program change ' + str(e.data) + ' */') 
     96      pass 
    5897    elif e.type == 'CONTROLLER_CHANGE': 
    59       # TODO: NOTE_ON tochu change taiou 
     98      # TODO: like PITCH_BEND 
    6099      pass 
    61100    elif e.type == 'PITCH_BEND': 
     101      if channel_stats[e.channel]['note_on_time']: 
     102        if channel_stats[e.channel]['note_on_time'] != e.time: 
     103          note_off(e, tpq) 
     104          channels[e.channel].append('&') 
    62105      octave, note = pitch_to_octave_and_note(e.pitch) 
    63       add_octave_and_note(e, octave, note) 
     106      add_octave_and_note(e, octave, note, tpq) 
    64107    elif e.type == 'NOTE_ON': 
    65108      octave, note = pitch_to_octave_and_note(e.pitch) 
    66       add_octave_and_note(e, octave, note) 
     109      add_octave_and_note(e, octave, note, tpq) 
    67110    elif e.type == 'NOTE_OFF': 
    68       td = e.time - channel_stats[e.channel]['note_on_time'] 
    69       while td > tpq: 
    70         channels[e.channel].append('&') 
    71         channels[e.channel].append(channes_stats[e.channel]['note']) 
    72         td -= tpq 
    73       if td > 0: 
    74         channels[e.channel].append(str((tpq / td) * 4)) 
     111      note_off(e, tpq) 
    75112    elif e.type == 'END_OF_TRACK': 
    76113      pass