From 2759f47631ea8de9e51071ce31049eda3f4da590 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 10:53:58 -0600 Subject: [PATCH 1/8] Added square wave functionality to play tone. Added code to enable square tone. This turns out to be much louder. In this addition, the variable names that referred to sine waves were generalized to _wave and _wave sample. --- .../circuit_playground_base.py | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index f34722b..8aacdc5 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -102,8 +102,8 @@ def __init__(self): self._speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) self._speaker_enable.switch_to_output(value=False) self._sample = None - self._sine_wave = None - self._sine_wave_sample = None + self._wave = None + self._wave_sample = None # Initialise tap: self._detect_taps = 1 @@ -689,23 +689,40 @@ def red_led(self, value): @staticmethod def _sine_sample(length): tone_volume = (2**15) - 1 + # Amplitude shift up in order to not have negative numbers shift = 2**15 for i in range(length): yield int(tone_volume * math.sin(2 * math.pi * (i / length)) + shift) - def _generate_sample(self, length=100): + @staticmethod + def _square_sample(length): + # Square waves are MUCH louder than then sine + tone_volume = (2**16) - 1 + half_length = length // 2 + for i in range(half_length): + yield int(tone_volume) + for i in range(half_length): + yield 0 + + def _generate_sample(self, length=100, waveform="sine"): if self._sample is not None: return - self._sine_wave = array.array("H", self._sine_sample(length)) - self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable - self._sine_wave_sample = audiocore.RawSample(self._sine_wave) + if waveform == "square": + self._wave = array.array("H", self._square_sample(length)) + self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable + self._wave_sample = audiocore.RawSample(self._wave) + else: + self._wave = array.array("H", self._sine_sample(length)) + self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable + self._wave_sample = audiocore.RawSample(self._wave) - def play_tone(self, frequency, duration): + def play_tone(self, frequency, duration, waveform="sine"): """Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz :param float duration: The duration of the tone in seconds + :param str waveform: Type of waveform to be generated [sine, square]. Default = sine. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker @@ -719,15 +736,16 @@ def play_tone(self, frequency, duration): cp.play_tone(440, 1) """ # Play a tone of the specified frequency (hz). - self.start_tone(frequency) + self.start_tone(frequency, waveform) time.sleep(duration) self.stop_tone() - def start_tone(self, frequency): + def start_tone(self, frequency, waveform="sine"): """Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz + :param str waveform: Type of waveform to be generated [sine, square]. Default = sine. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker @@ -750,11 +768,11 @@ def start_tone(self, frequency): length = 100 if length * frequency > 350000: length = 350000 // frequency - self._generate_sample(length) + self._generate_sample(length, waveform) # Start playing a tone of the specified frequency (hz). - self._sine_wave_sample.sample_rate = int(len(self._sine_wave) * frequency) + self._wave_sample.sample_rate = int(len(self._wave) * frequency) if not self._sample.playing: - self._sample.play(self._sine_wave_sample, loop=True) + self._sample.play(self._wave_sample, loop=True) def stop_tone(self): """Use with start_tone to stop the tone produced. From 1fa20bbfebbc68726658e522f281d1d4d971b969 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 11:31:31 -0600 Subject: [PATCH 2/8] Fixing pylint statement because of black. --- adafruit_circuitplayground/circuit_playground_base.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 8aacdc5..2f9599d 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -700,7 +700,7 @@ def _square_sample(length): tone_volume = (2**16) - 1 half_length = length // 2 for i in range(half_length): - yield int(tone_volume) + yield tone_volume for i in range(half_length): yield 0 @@ -709,11 +709,15 @@ def _generate_sample(self, length=100, waveform="sine"): return if waveform == "square": self._wave = array.array("H", self._square_sample(length)) - self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable + self._sample = self._audio_out( # pylint: disable=not-callable + board.SPEAKER + ) self._wave_sample = audiocore.RawSample(self._wave) else: self._wave = array.array("H", self._sine_sample(length)) - self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable + self._sample = self._audio_out( # pylint: disable=not-callable + board.SPEAKER + ) self._wave_sample = audiocore.RawSample(self._wave) def play_tone(self, frequency, duration, waveform="sine"): From 36bbb56dfba8b4a3cc77c45985372df55d804c21 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 11:35:09 -0600 Subject: [PATCH 3/8] Removing unncessary variable. --- adafruit_circuitplayground/circuit_playground_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 2f9599d..7b480e7 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -699,9 +699,9 @@ def _square_sample(length): # Square waves are MUCH louder than then sine tone_volume = (2**16) - 1 half_length = length // 2 - for i in range(half_length): + for _ in range(half_length): yield tone_volume - for i in range(half_length): + for _ in range(half_length): yield 0 def _generate_sample(self, length=100, waveform="sine"): From dd3b5a32117080c87b74c3429f8b88489705ac76 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 11:51:33 -0600 Subject: [PATCH 4/8] Removing duplicate code. --- .../circuit_playground_base.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 7b480e7..14b2084 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -709,16 +709,12 @@ def _generate_sample(self, length=100, waveform="sine"): return if waveform == "square": self._wave = array.array("H", self._square_sample(length)) - self._sample = self._audio_out( # pylint: disable=not-callable - board.SPEAKER - ) - self._wave_sample = audiocore.RawSample(self._wave) else: self._wave = array.array("H", self._sine_sample(length)) - self._sample = self._audio_out( # pylint: disable=not-callable - board.SPEAKER - ) - self._wave_sample = audiocore.RawSample(self._wave) + self._sample = self._audio_out( # pylint: disable=not-callable + board.SPEAKER + ) + self._wave_sample = audiocore.RawSample(self._wave) def play_tone(self, frequency, duration, waveform="sine"): """Produce a tone using the speaker. Try changing frequency to change From b508e65d1c4a741fec7665860cd677cb5c888ff3 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 11:53:07 -0600 Subject: [PATCH 5/8] Blackened. --- adafruit_circuitplayground/circuit_playground_base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 14b2084..f054d33 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -711,9 +711,7 @@ def _generate_sample(self, length=100, waveform="sine"): self._wave = array.array("H", self._square_sample(length)) else: self._wave = array.array("H", self._sine_sample(length)) - self._sample = self._audio_out( # pylint: disable=not-callable - board.SPEAKER - ) + self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable self._wave_sample = audiocore.RawSample(self._wave) def play_tone(self, frequency, duration, waveform="sine"): From eb52ceaf3ef812d68a810088de067a288d43a33f Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 13:36:20 -0600 Subject: [PATCH 6/8] Adding SPDX line for myself. --- adafruit_circuitplayground/circuit_playground_base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index f054d33..4fb2f86 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2016 Scott Shawcroft for Adafruit Industries # SPDX-FileCopyrightText: 2017-2019 Kattni Rembor for Adafruit Industries +# SPDX-FileCopyrightText: 2022 Ryan Keith for Adafruit Industries # # SPDX-License-Identifier: MIT @@ -15,7 +16,7 @@ * `Circuit Playground Express `_ * `Circuit Playground Bluefruit `_. -* Author(s): Kattni Rembor, Scott Shawcroft +* Author(s): Kattni Rembor, Scott Shawcroft, Ryan Keith """ import math From 74b8dd3c31c36ce7f75be431f6392619e540e069 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 15:57:50 -0600 Subject: [PATCH 7/8] Changing from string to number format for waveform selection. --- .../circuit_playground_base.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 4fb2f86..05d1a16 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -36,7 +36,6 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground.git" - class Photocell: """Simple driver for analog photocell on the Circuit Playground Express and Bluefruit.""" @@ -55,6 +54,8 @@ class CircuitPlaygroundBase: # pylint: disable=too-many-public-methods """Circuit Playground base class.""" _audio_out = None + SINE_WAVE = 0 + SQUARE_WAVE = 1 def __init__(self): # Define switch: @@ -705,23 +706,23 @@ def _square_sample(length): for _ in range(half_length): yield 0 - def _generate_sample(self, length=100, waveform="sine"): + def _generate_sample(self, length=100, waveform=SINE_WAVE): if self._sample is not None: return - if waveform == "square": + if waveform == self.SQUARE_WAVE: self._wave = array.array("H", self._square_sample(length)) else: self._wave = array.array("H", self._sine_sample(length)) self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable self._wave_sample = audiocore.RawSample(self._wave) - def play_tone(self, frequency, duration, waveform="sine"): + def play_tone(self, frequency, duration, waveform=SINE_WAVE): """Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz :param float duration: The duration of the tone in seconds - :param str waveform: Type of waveform to be generated [sine, square]. Default = sine. + :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. Default = SINE_WAVE. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker @@ -739,12 +740,12 @@ def play_tone(self, frequency, duration, waveform="sine"): time.sleep(duration) self.stop_tone() - def start_tone(self, frequency, waveform="sine"): + def start_tone(self, frequency, waveform=SINE_WAVE): """Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz - :param str waveform: Type of waveform to be generated [sine, square]. Default = sine. + :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. Default = SINE_WAVE. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker From 3a4b2b36750abbea6d874848d9b22d0b09ff3f15 Mon Sep 17 00:00:00 2001 From: Ryan Keith Date: Tue, 3 May 2022 16:04:21 -0600 Subject: [PATCH 8/8] Fixed linting error. Blackened. --- adafruit_circuitplayground/circuit_playground_base.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/adafruit_circuitplayground/circuit_playground_base.py b/adafruit_circuitplayground/circuit_playground_base.py index 05d1a16..9a12f82 100755 --- a/adafruit_circuitplayground/circuit_playground_base.py +++ b/adafruit_circuitplayground/circuit_playground_base.py @@ -36,6 +36,7 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground.git" + class Photocell: """Simple driver for analog photocell on the Circuit Playground Express and Bluefruit.""" @@ -722,7 +723,9 @@ def play_tone(self, frequency, duration, waveform=SINE_WAVE): :param int frequency: The frequency of the tone in Hz :param float duration: The duration of the tone in seconds - :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. Default = SINE_WAVE. + :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. + + Default is SINE_WAVE. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker @@ -745,7 +748,9 @@ def start_tone(self, frequency, waveform=SINE_WAVE): the pitch of the tone. :param int frequency: The frequency of the tone in Hz - :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. Default = SINE_WAVE. + :param str waveform: Type of waveform to be generated [SINE_WAVE, SQUARE_WAVE]. + + Default is SINE_WAVE. .. image :: ../docs/_static/speaker.jpg :alt: Onboard speaker