Comment detail

Tiny MML (Nested Flatten)

This comment is reply for 1432 ocean: MIDIマッパーを使って再生。Windo...(Tiny MML). Go to thread root.

上のと同じコードをPython+ctypesを使って記述。音の長さは他の人のコードを参考にして0.25秒に変更しました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import ctypes
import time
import sys

MIDI_MAPPER = -1
MMSYSERR_NOERROR = 0
CALLBACK_NULL = 0

class Midi:
    def __init__(self):
        self._dll = ctypes.windll.winmm
        self._h = ctypes.c_void_p()
        self._call("midiOutOpen", ctypes.byref(self._h), MIDI_MAPPER, 0, 0, CALLBACK_NULL)

    def __del__(self):
        self._call("midiOutClose", self._h)

    def play(self, note):
        self._call("midiOutShortMsg", self._h, self._msg(0x9, 0, note, 100))
        self.wait()
        self._call("midiOutReset", self._h)

    def wait(self):
        time.sleep(0.25)

    def _call(self, name, *args):
        ret = getattr(self._dll, name)(*args)
        if ret != MMSYSERR_NOERROR:
            raise RuntimeError("mmsystem error (%s)" % hex(ret))

    def _msg(self, status, channel, data1, data2):
        return (status<<4) | channel | (data1<<8) | (data2<<16)

def play(s):
    m = Midi()
    notes = {'c': 60, 'd': 62, 'e': 64, 'f': 65,
             'g': 67, 'a': 69, 'b': 71}
    for c in s:
        if c == 'r':
            m.wait()
        else:
            m.play(notes[c])

def main():
    if len(sys.argv) == 2:
        play(sys.argv[1])
    else:
        play("cdefedcrefgagfercrcrcrcrcdefedcr")

if __name__ == '__main__':
    main()

Index

Feed

Other

Link

Pathtraq

loading...