Skip to content

Commit a6b5b88

Browse files
authored
Merge pull request #116 from ryanskeith/add_square_wave
Added square wave functionality to play tone.
2 parents a33b7b8 + 3a4b2b3 commit a6b5b88

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

adafruit_circuitplayground/circuit_playground_base.py

+35-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-FileCopyrightText: 2016 Scott Shawcroft for Adafruit Industries
22
# SPDX-FileCopyrightText: 2017-2019 Kattni Rembor for Adafruit Industries
3+
# SPDX-FileCopyrightText: 2022 Ryan Keith for Adafruit Industries
34
#
45
# SPDX-License-Identifier: MIT
56

@@ -15,7 +16,7 @@
1516
* `Circuit Playground Express <https://www.adafruit.com/product/3333>`_
1617
* `Circuit Playground Bluefruit <https://www.adafruit.com/product/4333>`_.
1718
18-
* Author(s): Kattni Rembor, Scott Shawcroft
19+
* Author(s): Kattni Rembor, Scott Shawcroft, Ryan Keith
1920
"""
2021

2122
import math
@@ -54,6 +55,8 @@ class CircuitPlaygroundBase: # pylint: disable=too-many-public-methods
5455
"""Circuit Playground base class."""
5556

5657
_audio_out = None
58+
SINE_WAVE = 0
59+
SQUARE_WAVE = 1
5760

5861
def __init__(self):
5962
# Define switch:
@@ -102,8 +105,8 @@ def __init__(self):
102105
self._speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
103106
self._speaker_enable.switch_to_output(value=False)
104107
self._sample = None
105-
self._sine_wave = None
106-
self._sine_wave_sample = None
108+
self._wave = None
109+
self._wave_sample = None
107110

108111
# Initialise tap:
109112
self._detect_taps = 1
@@ -689,23 +692,40 @@ def red_led(self, value):
689692
@staticmethod
690693
def _sine_sample(length):
691694
tone_volume = (2**15) - 1
695+
# Amplitude shift up in order to not have negative numbers
692696
shift = 2**15
693697
for i in range(length):
694698
yield int(tone_volume * math.sin(2 * math.pi * (i / length)) + shift)
695699

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):
697711
if self._sample is not None:
698712
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))
700717
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)
702719

703-
def play_tone(self, frequency, duration):
720+
def play_tone(self, frequency, duration, waveform=SINE_WAVE):
704721
"""Produce a tone using the speaker. Try changing frequency to change
705722
the pitch of the tone.
706723
707724
:param int frequency: The frequency of the tone in Hz
708725
: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.
709729
710730
.. image :: ../docs/_static/speaker.jpg
711731
:alt: Onboard speaker
@@ -719,15 +739,18 @@ def play_tone(self, frequency, duration):
719739
cp.play_tone(440, 1)
720740
"""
721741
# Play a tone of the specified frequency (hz).
722-
self.start_tone(frequency)
742+
self.start_tone(frequency, waveform)
723743
time.sleep(duration)
724744
self.stop_tone()
725745

726-
def start_tone(self, frequency):
746+
def start_tone(self, frequency, waveform=SINE_WAVE):
727747
"""Produce a tone using the speaker. Try changing frequency to change
728748
the pitch of the tone.
729749
730750
: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.
731754
732755
.. image :: ../docs/_static/speaker.jpg
733756
:alt: Onboard speaker
@@ -750,11 +773,11 @@ def start_tone(self, frequency):
750773
length = 100
751774
if length * frequency > 350000:
752775
length = 350000 // frequency
753-
self._generate_sample(length)
776+
self._generate_sample(length, waveform)
754777
# 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)
756779
if not self._sample.playing:
757-
self._sample.play(self._sine_wave_sample, loop=True)
780+
self._sample.play(self._wave_sample, loop=True)
758781

759782
def stop_tone(self):
760783
"""Use with start_tone to stop the tone produced.

0 commit comments

Comments
 (0)