Simple test

Test each waveform type provided by this library. Provide a 16-bit WAV file in the root directory called “test.wav” to test the relic_waveform.from_wav() function.

examples/waveform_simpletest.py
 1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
 2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
 3#
 4# SPDX-License-Identifier: Unlicense
 5
 6import ulab.numpy as np
 7
 8import relic_waveform
 9
10SIZE = 8
11TYPE = np.float
12
13print(relic_waveform.sine(size=SIZE, dtype=TYPE))
14print(relic_waveform.triangle(size=SIZE, dtype=TYPE))
15print(relic_waveform.saw(size=SIZE, dtype=TYPE))
16print(relic_waveform.square(size=SIZE, dtype=TYPE))
17print(relic_waveform.noise(size=SIZE, dtype=TYPE))
18print(
19    relic_waveform.mix(
20        relic_waveform.sine(size=SIZE, dtype=TYPE),
21        (relic_waveform.noise(size=SIZE, dtype=TYPE), 0.5),
22    )
23)
24print(relic_waveform.from_wav("test.wav", SIZE))

synthio

Generate a waveform to be used with a synthio.Note object.

examples/waveform_synthio.py
 1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
 2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
 3#
 4# SPDX-License-Identifier: Unlicense
 5
 6import audiopwmio
 7import board
 8import synthio
 9
10import relic_waveform
11
12audio = audiopwmio.PWMAudioOut(board.A0)
13synth = synthio.Synthesizer()
14audio.play(synth)
15synth.press(synthio.Note(440, waveform=relic_waveform.sine()))

Oscilloscope

View and manipulate waveform options with a rotary encoder and SSD1306 display.

examples/waveform_oscilloscope.py
  1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
  2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
  3#
  4# SPDX-License-Identifier: Unlicense
  5
  6import adafruit_debouncer
  7import adafruit_ssd1306
  8import board
  9import busio
 10import digitalio
 11import displayio
 12import rotaryio
 13import ulab.numpy as np
 14
 15import relic_waveform
 16
 17displayio.release_displays()
 18
 19WIDTH = 128
 20HEIGHT = 64
 21INCREMENT = 0.1
 22
 23i2c = busio.I2C(board.GP1, board.GP0)
 24display = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c)
 25
 26data = None
 27
 28current_type = 0
 29current_index = 0
 30values = [1.0, 0.0, 1.0, 0.5]  # amplitude, phase, frequency, duty cycle/reverse
 31
 32
 33def update():
 34    if current_type == 0:
 35        data = relic_waveform.sine(
 36            amplitude=values[0],
 37            phase=values[1],
 38            frequency=values[2],
 39            size=WIDTH,
 40            dtype=np.float,
 41        )
 42    elif current_type == 1:
 43        data = relic_waveform.triangle(
 44            amplitude=values[0],
 45            phase=values[1],
 46            frequency=values[2],
 47            size=WIDTH,
 48            dtype=np.float,
 49        )
 50    elif current_type == 2:
 51        data = relic_waveform.saw(
 52            amplitude=values[0],
 53            phase=values[1],
 54            frequency=values[2],
 55            reverse=values[3] > 0.5,
 56            size=WIDTH,
 57            dtype=np.float,
 58        )
 59    elif current_type == 3:
 60        data = relic_waveform.square(
 61            amplitude=values[0],
 62            phase=values[1],
 63            frequency=values[2],
 64            duty_cycle=values[3],
 65            size=WIDTH,
 66            dtype=np.float,
 67        )
 68    elif current_type == 4:
 69        data = relic_waveform.noise(
 70            amplitude=values[0],
 71            size=WIDTH,
 72            dtype=np.float,
 73        )
 74
 75    # Draw waveform on screen
 76    display.fill(0)
 77    for i in range(data.size):
 78        y1 = min(int((HEIGHT - data[i] * HEIGHT) / 2), HEIGHT - 1)
 79        y2 = min(int((HEIGHT - data[(i + 1) % WIDTH] * HEIGHT) / 2), HEIGHT - 1)
 80        if y1 == y2:
 81            display.pixel(i, y1, 1)
 82        else:
 83            display.vline(i, min(y1, y2), abs(y1 - y2), 1)
 84    display.show()
 85
 86
 87switch_pin = digitalio.DigitalInOut(board.GP4)
 88switch_pin.direction = digitalio.Direction.INPUT
 89switch_pin.pull = digitalio.Pull.UP
 90switch = adafruit_debouncer.Button(switch_pin)
 91
 92encoder = rotaryio.IncrementalEncoder(board.GP2, board.GP3)
 93last_position = encoder.position
 94
 95update()
 96
 97while True:
 98    switch.update()
 99    if switch.short_count == 2:
100        current_type = (current_type + 1) % 5
101        update()
102    elif switch.short_count == 1:
103        current_index = (current_index + 1) % len(values)
104
105    position = encoder.position
106    if position != last_position:
107        values[current_index] += (position - last_position) * INCREMENT
108        last_position = position
109        update()