1
1
# SPDX-FileCopyrightText: 2016 Scott Shawcroft for Adafruit Industries
2
2
# SPDX-FileCopyrightText: 2017-2019 Kattni Rembor for Adafruit Industries
3
+ # SPDX-FileCopyrightText: 2022 Ryan Keith for Adafruit Industries
3
4
#
4
5
# SPDX-License-Identifier: MIT
5
6
15
16
* `Circuit Playground Express <https://www.adafruit.com/product/3333>`_
16
17
* `Circuit Playground Bluefruit <https://www.adafruit.com/product/4333>`_.
17
18
18
- * Author(s): Kattni Rembor, Scott Shawcroft
19
+ * Author(s): Kattni Rembor, Scott Shawcroft, Ryan Keith
19
20
"""
20
21
21
22
import math
@@ -54,6 +55,8 @@ class CircuitPlaygroundBase: # pylint: disable=too-many-public-methods
54
55
"""Circuit Playground base class."""
55
56
56
57
_audio_out = None
58
+ SINE_WAVE = 0
59
+ SQUARE_WAVE = 1
57
60
58
61
def __init__ (self ):
59
62
# Define switch:
@@ -102,8 +105,8 @@ def __init__(self):
102
105
self ._speaker_enable = digitalio .DigitalInOut (board .SPEAKER_ENABLE )
103
106
self ._speaker_enable .switch_to_output (value = False )
104
107
self ._sample = None
105
- self ._sine_wave = None
106
- self ._sine_wave_sample = None
108
+ self ._wave = None
109
+ self ._wave_sample = None
107
110
108
111
# Initialise tap:
109
112
self ._detect_taps = 1
@@ -689,23 +692,40 @@ def red_led(self, value):
689
692
@staticmethod
690
693
def _sine_sample (length ):
691
694
tone_volume = (2 ** 15 ) - 1
695
+ # Amplitude shift up in order to not have negative numbers
692
696
shift = 2 ** 15
693
697
for i in range (length ):
694
698
yield int (tone_volume * math .sin (2 * math .pi * (i / length )) + shift )
695
699
696
- def _generate_sample (self , length = 100 ):
700
+ @staticmethod
701
+ def _square_sample (length ):
702
+ # Square waves are MUCH louder than then sine
703
+ tone_volume = (2 ** 16 ) - 1
704
+ half_length = length // 2
705
+ for _ in range (half_length ):
706
+ yield tone_volume
707
+ for _ in range (half_length ):
708
+ yield 0
709
+
710
+ def _generate_sample (self , length = 100 , waveform = SINE_WAVE ):
697
711
if self ._sample is not None :
698
712
return
699
- self ._sine_wave = array .array ("H" , self ._sine_sample (length ))
713
+ if waveform == self .SQUARE_WAVE :
714
+ self ._wave = array .array ("H" , self ._square_sample (length ))
715
+ else :
716
+ self ._wave = array .array ("H" , self ._sine_sample (length ))
700
717
self ._sample = self ._audio_out (board .SPEAKER ) # pylint: disable=not-callable
701
- self ._sine_wave_sample = audiocore .RawSample (self ._sine_wave )
718
+ self ._wave_sample = audiocore .RawSample (self ._wave )
702
719
703
- def play_tone (self , frequency , duration ):
720
+ def play_tone (self , frequency , duration , waveform = SINE_WAVE ):
704
721
"""Produce a tone using the speaker. Try changing frequency to change
705
722
the pitch of the tone.
706
723
707
724
:param int frequency: The frequency of the tone in Hz
708
725
:param float duration: The duration of the tone in seconds
726
+ :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE].
727
+
728
+ Default is SINE_WAVE.
709
729
710
730
.. image :: ../docs/_static/speaker.jpg
711
731
:alt: Onboard speaker
@@ -719,15 +739,18 @@ def play_tone(self, frequency, duration):
719
739
cp.play_tone(440, 1)
720
740
"""
721
741
# Play a tone of the specified frequency (hz).
722
- self .start_tone (frequency )
742
+ self .start_tone (frequency , waveform )
723
743
time .sleep (duration )
724
744
self .stop_tone ()
725
745
726
- def start_tone (self , frequency ):
746
+ def start_tone (self , frequency , waveform = SINE_WAVE ):
727
747
"""Produce a tone using the speaker. Try changing frequency to change
728
748
the pitch of the tone.
729
749
730
750
:param int frequency: The frequency of the tone in Hz
751
+ :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE].
752
+
753
+ Default is SINE_WAVE.
731
754
732
755
.. image :: ../docs/_static/speaker.jpg
733
756
:alt: Onboard speaker
@@ -750,11 +773,11 @@ def start_tone(self, frequency):
750
773
length = 100
751
774
if length * frequency > 350000 :
752
775
length = 350000 // frequency
753
- self ._generate_sample (length )
776
+ self ._generate_sample (length , waveform )
754
777
# Start playing a tone of the specified frequency (hz).
755
- self ._sine_wave_sample .sample_rate = int (len (self ._sine_wave ) * frequency )
778
+ self ._wave_sample .sample_rate = int (len (self ._wave ) * frequency )
756
779
if not self ._sample .playing :
757
- self ._sample .play (self ._sine_wave_sample , loop = True )
780
+ self ._sample .play (self ._wave_sample , loop = True )
758
781
759
782
def stop_tone (self ):
760
783
"""Use with start_tone to stop the tone produced.
0 commit comments