1- # Author: qiren123
2- # This file is part of MicroPython MIDI Music
3- # Copyright (c) 2018 qiren123
4- #
5- # Licensed under the MIT license:
6- # http://www.opensource.org/licenses/mit-license.php
7- #
81
92DADADADUM = ['r4:2' , 'g' , 'g' , 'g' , 'eb:8' , 'r:2' , 'f' , 'f' , 'f' , 'd:8' ]
103
2821]
2922
3023NYAN = [
31- 'f#5:2 ' , 'g#' , 'c#:1' , 'd#:2' , 'b4:1' , 'd5:1' , 'c#' , 'b4:2' , 'b' , 'c#5' ,
24+ 'f#5:1 ' , 'g#' , 'c#:1' , 'd#:2' , 'b4:1' , 'd5:1' , 'c#' , 'b4:2' , 'b' , 'c#5' ,
3225 'd' , 'd:1' , 'c#' , 'b4:1' , 'c#5:1' , 'd#' , 'f#' , 'g#' , 'd#' , 'f#' , 'c#' , 'd' ,
3326 'b4' , 'c#5' , 'b4' , 'd#5:2' , 'f#' , 'g#:1' , 'd#' , 'f#' , 'c#' , 'd#' , 'b4' ,
3427 'd5' , 'd#' , 'd' , 'c#' , 'b4' , 'c#5' , 'd:2' , 'b4:1' , 'c#5' , 'd#' , 'f#' , 'c#' ,
5851]
5952
6053BIRTHDAY = [
61- 'c4:3 ' , 'c:1' , 'd:4' , 'c:4' , 'f' , 'e:8' , 'c:3' , 'c:1' , 'd:4' , 'c:4' , 'g' ,
54+ 'c5:4 ' , 'c:1' , 'd:4' , 'c:4' , 'f' , 'e:8' , 'c:3' , 'c:1' , 'd:4' , 'c:4' , 'g' ,
6255 'f:8' , 'c:3' , 'c:1' , 'c5:4' , 'a4' , 'f' , 'e' , 'd' , 'a#:3' , 'a#:1' , 'a:4' ,
6356 'f' , 'g' , 'f:8'
6457]
10598
10699POWER_DOWN = ['g5:1' , 'd#' , 'c' , 'g4:2' , 'b:1' , 'c5:3' ]
107100
108- octave = {
101+ normal_tone = {
109102 'A1' : 55 , 'B1' : 62 , 'C1' : 33 , 'D1' : 37 , 'E1' : 41 , 'F1' : 44 , 'G1' : 49 ,
110103
111104 'A2' : 110 , 'B2' : 123 , 'C2' : 65 , 'D2' : 73 , 'E2' : 82 , 'F2' : 87 , 'G2' : 98 ,
122115
123116 'A8' : 7040 , 'B8' : 7902 , 'C8' : 4186 , 'D8' : 4699 , 'E8' : 5274 , 'F8' : 5588 , 'G8' : 6271 ,
124117
125- 'A9' : 14080 , 'B9' : 15804 , 'R' : 1
118+ 'A9' : 14080 , 'B9' : 15804
126119}
127120
128121rising_tone = {
162155
163156 'B8' : 7459 , 'D8' : 4435 , 'E8' : 4978 , 'G8' : 5920 , 'A8' : 6645 ,
164157
165- 'B9' : 14917 ,
158+ 'B9' : 14917
166159}
167160
168161Letter = 'ABCDEFG#R'
@@ -174,62 +167,71 @@ def set_tempo(self, ticks=4, bpm=120):
174167 self .bpm = bpm
175168 self .beat = 60000 / self .bpm / self .ticks
176169
170+ def set_octave (self , octave = 4 ):
171+ self .octave = octave
172+
173+ def set_duration (self , duration = 4 ):
174+ self .duration = duration
175+
177176 def reset (self ):
178- self .duration = 1
179- self .octave = 5
177+ self .set_duration ()
178+ self .set_octave ()
180179 self .set_tempo ()
181180
182181 def __init__ (self ):
183- self .freq = 1
184182 self .reset ()
185- self .tim = self .beat * 4
186183
187- def seek_tone (self , tone , dic ):
188- tone_size = len (tone )
189- self .tim = self .beat * self .duration
190- if tone_size == 1 :
191- self .freq = dic [(tone + str (self .octave ))]
184+ def parse (self , tone , dict ):
185+ # print(tone)
186+ time = self .beat * self .duration
187+ pos = tone .find (':' )
188+ if pos != - 1 :
189+ time = self .beat * int (tone [(pos + 1 ):])
190+ tone = tone [:pos ]
191+ # print(tone)
192+ freq , tone_size = 1 , len (tone )
193+ if 'R' in tone :
194+ freq = 1
195+ elif tone_size == 1 :
196+ freq = dict [tone [0 ] + str (self .octave )]
192197 elif tone_size == 2 :
193- self .freq = dic [(tone )]
194- elif ':' in tone :
195- tem = tone .find (':' )
196- self .tim = self .beat * int (tone [tem + 1 :])
197- self .freq = dic [(
198- tone [0 ] + str (self .octave ))] if tem == 1 else dic [tone [0 :2 ]]
198+ freq = dict [tone ]
199+ self .set_octave (tone [1 :])
200+ return int (freq ), int (time )
199201
200202 def midi (self , tone ):
201- self . tim = self . beat * self . duration
202- if '#' in tone :
203- tem = tone . find ( '#' )
204- tone = tone [ 0 : tem ] + tone [ tem + 1 :]
205- self . seek_tone ( tone , rising_tone )
206- elif len ( tone ) != 1 and tone [ 1 ] == 'B' :
207- tem = tone .find ('B' )
208- tone = tone [ 0 : tem ] + tone [ tem + 1 :]
209- self . seek_tone ( tone , falling_tone )
210- elif 'R' in tone :
211- self . freq = 1
212- if ':' in tone :
213- tem = tone . find ( ':' )
214- self . tim = self . beat * int ( tone [tem + 1 :])
215- else :
216- self .seek_tone (tone , octave )
203+ # print(tone)
204+ pos = tone . find ( '#' )
205+ if pos != - 1 :
206+ return self . parse ( tone . replace ( '#' , '' ), rising_tone )
207+ pos = tone . find ( 'B' )
208+ if pos != - 1 and pos != 0 :
209+ return self . parse ( tone .replace ('B' , '' ), falling_tone )
210+ return self . parse ( tone , normal_tone )
211+
212+ def set_default ( self , tone ) :
213+ pos = tone . find ( ':' )
214+ if pos != - 1 :
215+ self . set_duration ( int ( tone [( pos + 1 ):]) )
216+ tone = tone [: pos ]
217+ if len ( tone ) == 2 :
218+ self .set_octave (tone [ 1 :] )
217219
218220 def play (self , tune , pin = 25 ):
219221 from machine import Pin , PWM
220222 from utime import sleep_ms
221223
222224 try :
223225 pwm = PWM (Pin (pin ))
226+ self .set_default (tune [0 ])
224227 for tone in tune :
225- tone = tone .upper () # 全部转为大写
228+ tone = tone .upper () # all to upper
226229 if tone [0 ] not in Letter :
227230 continue
228- self .midi (tone )
229- # print('freq=%d,tim=%d' % (self.freq, self.tim))
230- pwm .freq (self .freq ) # set frequency
231- pwm .duty (int (self .tim )) # set duty cycle
232- sleep_ms (int (self .tim ))
231+ midi = self .midi (tone )
232+ pwm .freq (midi [0 ]) # set frequency
233+ pwm .duty (midi [1 ]) # set duty cycle
234+ sleep_ms (midi [1 ])
233235 finally :
234236 pwm .deinit ()
235237
@@ -250,19 +252,20 @@ def unit_test():
250252 print ('The unit test code is as follows' )
251253 print ('\n \
252254 music = MIDI()\n \
255+ music.play(BIRTHDAY)\n \
256+ music.play(NYAN)\n \
253257 music.play(PRELUDE)\n \
254258 music.play(PYTHON)\n \
255- music.play(NYAN)\n \
256- music.play(NYAN)\n \
257259 for freq in range(880, 1760, 16):\n \
258260 music.pitch(freq, 30)\n \
259261 for freq in range(1760, 880, -16):\n \
260262 music.pitch(freq, 30)\n \
261263 ' )
262264 music = MIDI ()
265+ music .play (BIRTHDAY )
266+ music .play (NYAN )
263267 music .play (PRELUDE )
264268 music .play (PYTHON )
265- music .play (NYAN )
266269 for freq in range (880 , 1760 , 16 ):
267270 music .pitch (freq , 30 )
268271 for freq in range (1760 , 880 , - 16 ):
0 commit comments