Tiny MML
Posted feedbacks - Python
とりあえずbeepで。win専用。
1 2 3 4 5 6 7 8 9 10 11 | import winsound
import time
def play(mmf):
toi = lambda x: int(ord(x))
for n in mmf:
if n == 'r': time.sleep(0.5)
else : winsound.Beep(play.fq[toi(n)-toi('a')], 500)
play.fq = [440, 494, 262, 294, 330, 349, 392]
play("cdefedcrefgagfercrcrcrcrcdefedcr")
|
上のと同じコードを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()
|
ordの返り値は元からintなのでtoiを定義する必要はないですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import winsound
import time
PLAY_FQ = [440, 494, 262, 294, 330, 349, 392]
def play(mmf):
for n in mmf:
if n == 'r':
time.sleep(0.5)
else:
winsound.Beep(
PLAY_FQ[ord(n) - ord('a')], 500)
play("cdefedcrefgagfercrcrcrcrcdefedcr")
|
#1433をヒントにして、自前で正弦波を生成しました。 式は適当ですが、一応それっぽい音はします。 利用パッケージの都合で、Linuxと*BSD(?)のみ対応です。 8分音符は0.5秒にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import math
import struct
import ossaudiodev
def sw(r, f, t):
return struct.pack('h', int(math.sin((t/(float(r)/f))*2*math.pi)*0x7fff))
wav = {
'c': ''.join([sw(8000, 262, i) for i in range(4000)]),
'd': ''.join([sw(8000, 294, i) for i in range(4000)]),
'e': ''.join([sw(8000, 330, i) for i in range(4000)]),
'f': ''.join([sw(8000, 349, i) for i in range(4000)]),
'g': ''.join([sw(8000, 392, i) for i in range(4000)]),
'a': ''.join([sw(8000, 440, i) for i in range(4000)]),
'b': ''.join([sw(8000, 494, i) for i in range(4000)]),
'r': '\x00\x00' * 4000
}
dsp = ossaudiodev.open('w')
dsp.setparameters(ossaudiodev.AFMT_S16_LE, 1, 8000)
dsp.writeall(''.join([wav[c] for c in 'cdefedcrefgagfercrcrcrcrcdefedcr']))
dsp.flush()
dsp.close()
|





にしお
#3387()
Rating0/0=0.00
入力はcがド、dがレ、eがミ、fがファ、gがソ、aがラ、bがシ、rが休符とします。この8文字以外の文字は入力に含まれていないと仮定して構いません。おのおのの音符・休符は八分音符・八分休符とします。
オクターブや音の長さの変更、同時発音などの機能は不要です。
サンプル入力(カエルの歌)
[ reply ]