3131from ev3dev2 import is_micropython
3232import os
3333import re
34+ from time import sleep
3435
3536if not is_micropython ():
3637 import shlex
@@ -43,7 +44,7 @@ def _make_scales(notes):
4344 for note , freq in notes :
4445 freq = round (freq )
4546 for n in note .split ('/' ):
46- res [n ] = freq
47+ res [n . upper () ] = freq
4748 return res
4849
4950
@@ -77,14 +78,18 @@ class Sound(object):
7778
7879 Examples::
7980
81+ from ev3dev2.sound import Sound
82+
83+ spkr = Sound()
84+
8085 # Play 'bark.wav':
81- Sound .play_file('bark.wav')
86+ spkr .play_file('bark.wav')
8287
8388 # Introduce yourself:
84- Sound .speak('Hello, I am Robot')
89+ spkr .speak('Hello, I am Robot')
8590
8691 # Play a small song
87- Sound .play_song((
92+ spkr .play_song((
8893 ('D4', 'e3'),
8994 ('D4', 'e3'),
9095 ('D4', 'e3'),
@@ -406,6 +411,7 @@ def play_song(self, song, tempo=120, delay=0.05):
406411 and duration.
407412
408413 It supports symbolic notes (e.g. ``A4``, ``D#3``, ``Gb5``) and durations (e.g. ``q``, ``h``).
414+ You can also specify rests by using ``R`` instead of note pitch.
409415
410416 For an exhaustive list of accepted note symbols and values, have a look at the ``_NOTE_FREQUENCIES``
411417 and ``_NOTE_VALUES`` private dictionaries in the source code.
@@ -429,7 +435,9 @@ def play_song(self, song, tempo=120, delay=0.05):
429435
430436 >>> # A long time ago in a galaxy far,
431437 >>> # far away...
432- >>> Sound.play_song((
438+ >>> from ev3dev2.sound import Sound
439+ >>> spkr = Sound()
440+ >>> spkr.play_song((
433441 >>> ('D4', 'e3'), # intro anacrouse
434442 >>> ('D4', 'e3'),
435443 >>> ('D4', 'e3'),
@@ -471,41 +479,39 @@ def play_song(self, song, tempo=120, delay=0.05):
471479 delay_ms = int (delay * 1000 )
472480 meas_duration_ms = 60000 / tempo * 4 # we only support 4/4 bars, hence "* 4"
473481
474- def beep_args (note , value ):
475- """ Builds the arguments string for producing a beep matching
476- the requested note and value.
477-
478- Args:
479- note (str): the note note and octave
480- value (str): the note value expression
481- Returns:
482- str: the arguments to be passed to the beep command
483- """
484- freq = self ._NOTE_FREQUENCIES .get (note .upper (), self ._NOTE_FREQUENCIES [note ])
482+ for (note , value ) in song :
483+ value = value .lower ()
485484
486485 if '/' in value :
487486 base , factor = value .split ('/' )
488- duration_ms = meas_duration_ms * self ._NOTE_VALUES [base ] / float (factor )
487+ factor = float (factor )
488+
489489 elif '*' in value :
490490 base , factor = value .split ('*' )
491- duration_ms = meas_duration_ms * self ._NOTE_VALUES [base ] * float (factor )
491+ factor = float (factor )
492+
492493 elif value .endswith ('.' ):
493494 base = value [:- 1 ]
494- duration_ms = meas_duration_ms * self ._NOTE_VALUES [base ] * 1.5
495+ factor = 1.5
496+
495497 elif value .endswith ('3' ):
496498 base = value [:- 1 ]
497- duration_ms = meas_duration_ms * self ._NOTE_VALUES [base ] * 2 / 3
499+ factor = float (2 / 3 )
500+
498501 else :
499- duration_ms = meas_duration_ms * self ._NOTE_VALUES [value ]
502+ base = value
503+ factor = 1.0
500504
501- return '-f %d -l %d -D %d' % (freq , duration_ms , delay_ms )
505+ try :
506+ duration_ms = meas_duration_ms * self ._NOTE_VALUES [base ] * factor
507+ except KeyError :
508+ raise ValueError ('invalid note (%s)' % base )
502509
503- try :
504- return self .beep (' -n ' .join (
505- [beep_args (note , value ) for (note , value ) in song ]
506- ))
507- except KeyError as e :
508- raise ValueError ('invalid note (%s)' % e )
510+ if note == "R" :
511+ sleep (duration_ms / 1000 + delay )
512+ else :
513+ freq = self ._NOTE_FREQUENCIES [note .upper ()]
514+ self .beep ('-f %d -l %d -D %d' % (freq , duration_ms , delay_ms ))
509515
510516 #: Note frequencies.
511517 #:
0 commit comments