Skip to content

Instantly share code, notes, and snippets.

@sdygt
Last active October 16, 2016 11:58
Show Gist options
  • Save sdygt/4479f425ea5fb970e8d92af720ce014e to your computer and use it in GitHub Desktop.
Save sdygt/4479f425ea5fb970e8d92af720ce014e to your computer and use it in GitHub Desktop.
NokiaBeeper
8#d4 8f4 8#f4 8#g4 4#a4 8#d5 8#c5
4#a4 4#d4 8#a4 8#g4 8#f4 8f4
8#d4 8f4 8#f4 8#g4 4#a4 8#g4 8#f4
8f4 8#d4 8f4 8#f4 8f4 8#d4 8#c4 8f4
8#d4 8f4 8#f4 8#g4 4#a4 8#d5 8#c5
4#a4 4#d4 8#a4 8#g4 8#f4 8f4
8#d4 8f4 8#f4 8#g4 4#a4 8#g4 8#f4
4f4 4#f4 4#g4 4#a4
8#c5 8#d5 8#a4 8#g4 4#a4 8#g4 8#a4
8#c5 8#d5 8#a4 8#g4 4#a4 8#g4 8#a4
8#g4 8#f4 8f4 8#c4 4#d4 8#c4 8#d4
8f4 8#f4 8#g4 8#a4 4#d4 8#a4 8#c5
8#c5 8#d5 8#a4 8#g4 4#a4 8#g4 8#a4
8#c5 8#d5 8#a4 8#g4 4#a4 8#d5 8f5
8#f5 8f5 8#d5 8#c5 4#a4 8#g4 8#a4
8#g4 8#f4 8f4 8#c4 4#d4
# -*- coding:utf-8 -*-
M = 2**(1 / 12)
C0 = 440 / 16 / (M**9)
freq = {}
freq['C0'] = C0
n = 0
for pitch in ['C', '#C', 'D', '#D', 'E', 'F', '#F', 'G', '#G', 'A', '#A', 'B']:
freq[pitch + '0'] = C0 * M**n
n = n + 1
for pitch in ['C', '#C', 'D', '#D', 'E', 'F', '#F', 'G', '#G', 'A', '#A', 'B']:
for octo in range(1, 9):
freq[pitch + str(octo)] = freq[pitch + '0'] * 2**octo
offset = {'C': 255, '#C': 241, 'D': 227, '#D': 214, 'E': 202, 'F': 195,
'#F': 180, 'G': 170, '#G': 161, 'A': 152, '#A': 143, 'B': 135, '-': 255}
n = 0
code = {}
for pitch in ['C', '#C', 'D', '#D', 'E', 'F', '#F', 'G', '#G', 'A', '#A', 'B', '-']:
code[pitch] = n
n = n + 1
# -*- coding:utf-8 -*-
import re
import winsound
from time import sleep
from data import freq, offset, code
# 编译EEPROM数据方法:
# 在下面的代码中设置输入输出的文件名,
# 确认main()函数中compile(objarrScore)一行没被注释(没有井号)
# Sublime Text按Ctrl+B启动编译(或者用命令行手动运行)
# 检查文件管理器中的文件大小,应当略小于或等于256字节
# 用WinHEX或者HexEdit拼接三份二进制乐谱时注意,如果某乐谱长度不足256字节,
# 不要把下一份乐谱紧贴此份之后,每份乐谱首地址应当是256字节的整数倍
# 此外由于乐曲选择器输出0b00时为空闲状态,
# 所以第一份乐谱首字节位置应当是0x0100(16进制),第二份0x0200,第三份0x0300
TEMPO = 139 # 每分钟的四分音符数
TICK = 16 # 最小计时单位为十六分音符
FILE = 'badapple.txt' # 乐谱的文件名
OUT = 'badapple.bin' # 输出二进制文件名
class Note(object):
def __init__(self, note):
note = note.upper()
self.note = note
if '-' in note: # 一个休止符 4-
self.pause = True
self.dur = re.search('^.*?(?=-)', note).group(0)
self.pitch = '-'
self.eecode = 64 # 0b01001100
else: # eg. 8.#G3
self.pause = False
self.dur = re.search('^.*?(?=[a-gA-G#])', note).group(0) # '8.'
self.pitch = re.search('#?[a-gA-G]{1}', note).group(0) # '#G'
self.octave = re.search('\d{1}$', note).group(0) # '3'
self.tune = self.pitch + self.octave # '#G3'
self.freq = freq[self.tune] # 207.65
self.eecode = ((int(self.octave) - 3) << 4) + code[self.pitch]
if '.' in self.dur: # 一个延长音符
self.tick = int(1.5 * TICK / int(re.search('^\d', self.dur).group(0)))
else:
self.tick = int(TICK / int(self.dur))
self.time = int(1000 * (60 / (TEMPO * TICK / 4)) * self.tick)
self.offset = offset[self.pitch] # EEPROM预置数
def __str__(self):
return self.note
def beep(self):
if self.pause:
sleep(self.time / 1000)
else:
winsound.Beep(int(self.freq), self.time)
def getEECODE(self):
return self.eecode
def compile(arrNote):
arrBytes = []
# addr = 0
for note in arrNote:
for tick in range(0, note.tick):
arrBytes.append(note.eecode)
# addr = addr + 1
arrBytes.append(128)
# print(bytes(arrBytes))
f = open(OUT, 'wb') # 第一个参数填入输出二进制文件的文件名
f.write(bytes(arrBytes))
f.close()
# for n in arrNote:
# arrBytes.append(n.getEECODE())
# print(bytes(arrBytes))
def main():
txtScore = open(FILE).read()
txtScore = re.sub('\/\*(.*?)\*\/', ' ', txtScore)
txtScore = txtScore.strip() # Strip out comments
objarrScore = map(lambda n: Note(n), re.split('\s+', txtScore))
# 注释下面一行,
compile(objarrScore)
# 并且取消注释下面三行用电脑试听
# for n in objarrScore:
# print(n)
# n.beep()
if __name__ == '__main__':
main()
4a4 4c5 8.d5 8.c5 8d5 /*zankoku na *//*6.12.1 1 2 ⑦ */
8d5 8d5 8g5 8f5 16e5 8d5 4e5 /*tenshi no TEEZE*//*2 2 5 4 32 33 ⑧*/
4e5 4g5 8.a5 8.d5 8c5 /*madobe kara *//*3 5 6.221 ⑨*/
8b4 8b4 8a4 8b4 16d5 8.c5 4c5 /*yaga te dobitotsu*//*7767 2111 ⑩*/ /*7767 2111 十四节*/
4a4 4c5 8.d5 8.c5 8d5 /*kono sora wo *//*6 1 2.112 十五节*/
8d5 8d5 8g5 8f5 16e5 8d5 8.e5 16- /*daite kagayaku*//*2 2 5 4 32 33 十六节*/
4e5 4g5 8.a5 8.d5 8c5 /*shounen yo *//*3 5 6.221 十七*/
8g5 8g5 8e5 8g5 8.g5 8.a5 8-/*shinwa ni nare*//*5535 5.66 十八*/
8.c5 8.c5 8b4 8.c5 8.c5 8b4 /* daketo itsuka *//*1.117 ① 1.117*/
8.d5 8.d5 8c5 8.b4 8.a4 8b4 /*kizuku deshou*//*2.221 ② 7.667*/
8.c5 8.c5 8b4 8.d5 8.b4 8a4 /* sono se nakani*//*1.117 ③ 2.776*/
8.g4 4- 4- 4- /*wa*/
8.c5 8.c5 8b4 8.c5 8.c5 8b4 /*haruka mirai *//*1.117 ④ 1.117*/
8.d5 8.d5 8c5 8.b4 8.c5 8d5 /*mezasu tameno*//*2.221 ⑤ 7.112*/
8.e5 8.f5 8e5 8.d5 8.c5 8d5 /*hame ga aru ko*//*3.443 ⑥ 2.112*/
4.e5 8- 4- 4- /*to*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment