Skip to content

Sound & Music

The Cyber Fidget has a speaker for output and a microphone for input. You can play tones at any frequency, control volume, and react to sound levels in your apps.


What is this?

The device includes:

  • Speaker — Plays tones and sounds. You set a frequency (pitch) and volume.
  • Microphone — Listens to ambient sound. You can read how loud it is and react to it.

Both are opt-in: enable the mic when your app needs it, and disable it when you're done to save power.


Concepts

Playing tones

You play a tone by specifying its frequency in Hertz (Hz). Higher Hz = higher pitch. Musical notes have standard frequencies:

Note Frequency (Hz)
C4 261.63
D4 293.66
E4 329.63
F4 349.23
G4 392.00
A4 440.00
B4 493.88
C5 523.25

Octaves

Each octave doubles the frequency. C5 is twice C4. Use freq * pow(2, octave) to shift notes up or down.

Volume

Volume is a float from 0.0 (silent) to 1.0 (full). The framework clamps values in this range.

Microphone input

The mic is opt-in. Call enableMic(true) in begin() and enableMic(false) in end(). While enabled:

  • getMicVolumeLinear() — Returns 0.0 to 1.0 (linear amplitude).
  • getMicVolumeDb() — Returns dBFS (decibels below full scale), typically negative (e.g. -60 to 0).

Code example: melody and sound reaction

#include "HAL.h"

void begin() {
    HAL::audioManager().enableMic(true);  // Turn on mic for reactive mode
    HAL::audioManager().setVolume(0.7f); // 70% volume
}

void update() {
    // Play a short melody (C4, E4, G4)
    static unsigned long lastNote = 0;
    static int noteIndex = 0;
    float notes[] = { 261.63f, 329.63f, 392.00f };
    if (millis() - lastNote > 500) {
        HAL::audioManager().playTone(notes[noteIndex], 200);
        noteIndex = (noteIndex + 1) % 3;
        lastNote = millis();
    }

    // React to mic: dim LEDs when quiet, bright when loud
    float micLin = HAL::audioManager().getMicVolumeLinear();
    uint8_t brightness = (uint8_t)(micLin * 255);
    HAL::setRgbLed(pixel_Front_Top, brightness, 0, 0, 0);
    updateStrip();
}

void end() {
    HAL::audioManager().stopTone();
    HAL::audioManager().enableMic(false);
}

Always disable the mic in end()

Call enableMic(false) in your app's end() to stop the mic task and free resources.


Framework details

AudioManager

The AudioManager singleton (accessed via HAL::audioManager()) handles:

  • Tone outputSineWaveGeneratorVolumeStream → I2S → MAX98357A amplifier
  • Mic input — ICS-43434 I2S mic → VolumeMeter → atomic level (0..1)

I2S

Audio uses the ESP32's I2S peripherals:

  • I2S0 — Speaker (TX) on pins 27 (LRCLK), 26 (BCLK), 14 (DOUT)
  • I2S1 — Microphone (RX) on pins 25 (LRCLK), 32 (BCLK), 33 (DATA IN)

The mic runs in a separate FreeRTOS task and publishes micVolumeAtomic roughly every 20 ms.

API summary

Method Description
setVolume(float) 0.0..1.0
playTone(float freq, int durationMs) 0 = indefinite
stopTone() Stops current tone
enableMic(bool on) Opt-in mic
getMicVolumeLinear() 0.0..1.0
getMicVolumeDb() dBFS (≤ 0)