CHGame 0.3.0
Libraries for the CHGame handheld
Loading...
Searching...
No Matches
Audio.h File Reference

Sound and the status LED: a small sequencer for the piezo. More...

#include <stdint.h>

Go to the source code of this file.

Classes

struct  audio::Step
 An effect step in three bytes. More...
 
struct  audio::Effect
 An effect: its steps, and its priority with flags. Write them with AUDIO_EFFECT(). More...
 
struct  audio::Melody
 A melody: one line of notes, easy to write by hand. More...
 

Namespaces

namespace  audio
 Sound effects, music and the status LED.
 

Macros

#define AUDIO_STEP(hz, end, ms)    { (uint8_t)(((hz) + 10) / 20), (uint8_t)(((end) + 10) / 20), (uint8_t)(((ms) + 1) / 2) }
 An effect step: a pitch, the pitch it sweeps to, a length.
 
#define AUDIO_REST(ms)   { 0, 0, (uint8_t)(((ms) + 1) / 2) }
 A silent effect step.
 
#define AUDIO_STEPS(name)   static const audio::Step name[] __attribute__((section(".rodata.audio." #name)))
 Declare an effect's step table, kept in flash.
 
#define AUDIO_EFFECT(steps, flags)   { steps, (uint8_t)(sizeof(steps) / sizeof((steps)[0])), (uint8_t)(flags) }
 An entry of the effects table.
 

Enumerations

enum  : uint8_t {
  audio::SOFT = 0x10 ,
  audio::GLIDE = 0x20
}
 Flags ORed into an effect's priority (0-15). More...
 
enum  audio::MusicMode : uint8_t {
  audio::MUSIC_OFF ,
  audio::ARPEGGIO ,
  audio::LEAD
}
 How music is rendered on the one pin. More...
 
enum  audio::Led : uint8_t {
  audio::LED_OFF ,
  audio::LED_BLINK ,
  audio::LED_TRIPLE ,
  audio::LED_PARTY
}
 Status LED (PB9) patterns, for wins. Timed in update() ticks. More...
 

Functions

void audio::begin (const Effect *effects, uint8_t count, bool on=true)
 Set up the speaker, the LED pin and the timer, with the game's effects.
 
void audio::setOn (bool on)
 Turn sound on or off.
 
bool audio::on ()
 Whether sound is on.
 
void audio::sfx (uint8_t id)
 Play an effect.
 
void audio::sfx (uint8_t id, uint8_t semitones)
 Play an effect raised in pitch: a combo that climbs.
 
template<class E >
void audio::sfx (E e)
 Play an effect named by the game's enum.
 
template<class E >
void audio::sfx (E e, uint8_t semitones)
 Play an effect named by the game's enum, raised in pitch.
 
void audio::blip (uint16_t hz, uint16_t ms, bool soft=false)
 One note made up on the spot (a typewriter, a click, a counter rolling).
 
void audio::note (uint16_t hz, uint16_t ms, uint8_t priority)
 One note at a priority, like an effect.
 
bool audio::playing ()
 Whether an effect is sounding.
 
void audio::setMusic (uint8_t mode)
 Choose how music is rendered.
 
void audio::music (const uint8_t *score, bool loop=true)
 Play a Playtune score under the effects.
 
void audio::melody (const Melody &m, bool loop=true)
 Play a melody under the effects (it replaces any score).
 
void audio::stopMusic ()
 Stop the music.
 
void audio::loopMusic (bool on)
 Whether the music repeats.
 
bool audio::musicPlaying ()
 Whether music is playing.
 
void audio::update ()
 Run the LED patterns: once per logic tick.
 
void audio::led (Led pattern)
 Start an LED pattern (replacing the one running).
 

Detailed Description

Sound and the status LED: a small sequencer for the piezo.

One pin plays one note at a time, driven by TIM1 channel 2 on PB10 and stepped by the core's 1 kHz SysTick hook, so no other timer is used. It plays two kinds of thing at once:

  • effects: short step lists (a pitch, the pitch it sweeps to, a length), each with a priority: a new effect is refused while one of higher priority sounds, and cuts off any other;
  • music, under the effects: a Playtune score (several voices; tools/make_music.py writes them), rendered as a lead line or an arpeggio, or a melody (one line of notes, easy to write by hand).

The simulator is silent: the same interface with no hardware, which remembers the last effect asked for (audio::simLast) for scripts and tests. The game's tools/audio preview renders the real thing to WAV.

Macro Definition Documentation

◆ AUDIO_STEP

#define AUDIO_STEP (   hz,
  end,
  ms 
)     { (uint8_t)(((hz) + 10) / 20), (uint8_t)(((end) + 10) / 20), (uint8_t)(((ms) + 1) / 2) }

An effect step: a pitch, the pitch it sweeps to, a length.

Parameters
hzStart pitch in Hz (rounded to 20 Hz).
endThe pitch to sweep to in Hz, or 0 to hold hz.
msLength in milliseconds (rounded to 2 ms; at most 510).

◆ AUDIO_REST

#define AUDIO_REST (   ms)    { 0, 0, (uint8_t)(((ms) + 1) / 2) }

A silent effect step.

Parameters
msLength in milliseconds (rounded to 2 ms; at most 510).

◆ AUDIO_STEPS

#define AUDIO_STEPS (   name)    static const audio::Step name[] __attribute__((section(".rodata.audio." #name)))

Declare an effect's step table, kept in flash.

Parameters
nameThe table's name, for AUDIO_EFFECT().

Use it as AUDIO_STEPS(WIN) = { AUDIO_STEP(...), ... };. (A plain static const table of 8 bytes or less is "small data" to the compiler, and this core's link script copies small data into SRAM.)

◆ AUDIO_EFFECT

#define AUDIO_EFFECT (   steps,
  flags 
)    { steps, (uint8_t)(sizeof(steps) / sizeof((steps)[0])), (uint8_t)(flags) }

An entry of the effects table.

Parameters
stepsA table declared with AUDIO_STEPS().
flagsThe priority (0-15), ORed with SOFT and GLIDE if wanted.