nimphea

Search:
Group by:
Source   Edit  

Nimphea - Nim wrapper for the Daisy Audio Platform Hardware Abstraction Library

This module provides Nim bindings to the Daisy Audio Platform (via libDaisy C++ library) by Electro-Smith. It enables easy access to audio, controls, GPIO, MIDI, USB, and more.

Basic Example:

import nimphea
useNimpheaNamespace()  # Required: sets up C++ interop

proc main() =
  var daisy = initDaisy()
  daisy.setLed(true)
  daisy.delay(500)
  daisy.setLed(false)

when isMainModule:
  main()

Audio Example:

import nimphea
useNimpheaNamespace()  # Required: sets up C++ interop

proc audioCallback(input, output: AudioBuffer, size: int) {.cdecl.} =
  for i in 0..<size:
    output[0][i] = input[0][i]  # Left channel passthrough
    output[1][i] = input[1][i]  # Right channel passthrough

proc main() =
  var daisy = initDaisy()
  daisy.startAudio(audioCallback)
  while true:
    discard

when isMainModule:
  main()

Note: The useNimpheaNamespace() macro automatically generates all necessary C++ interop code at compile time. You just need to call it once after your imports!

Types

AdcHandle {.importcpp: "daisy::AdcHandle".} = object
Source   Edit  
Ak4556 {.importcpp: "daisy::Ak4556".} = object
Source   Edit  
AudioBuffer = ptr UncheckedArray[ptr UncheckedArray[cfloat]]
Multi-channel audio buffer (non-interleaved) Source   Edit  
AudioCallback = proc (input, output: AudioBuffer; size: int) {.cdecl, ...raises: [].}
Nim-friendly multi-channel audio callback Source   Edit  
AudioCallbackC = proc (input: ConstFloatPtrPtr; output: FloatPtrPtr;
                       size: csize_t) {.cdecl.}
Source   Edit  
AudioConfig {.importcpp: "daisy::AudioHandle::Config", bycopy.} = object
  blocksize* {.importc: "blocksize".}: csize_t
  samplerate* {.importc: "samplerate".}: SampleRate
  postgain* {.importc: "postgain".}: cfloat
  output_compensation* {.importc: "output_compensation".}: cfloat
Source   Edit  
AudioHandle {.importcpp: "daisy::AudioHandle".} = object
Source   Edit  
AudioResult {.importcpp: "daisy::AudioHandle::Result", size: 4.} = enum
  AUDIO_OK = 0, AUDIO_ERR
Source   Edit  
BoardVersion {.importcpp: "daisy::DaisySeed::BoardVersion", size: 4.} = enum
  BOARD_DAISY_SEED = 0, BOARD_DAISY_SEED_1_1, BOARD_DAISY_SEED_2_DFM
Source   Edit  
ConstFloatPtr = ptr cfloat
Source   Edit  
ConstFloatPtrPtr = ptr ptr cfloat
Source   Edit  
DacHandle {.importcpp: "daisy::DacHandle".} = object
Source   Edit  
DaisySeed {.importcpp: "daisy::DaisySeed".} = object
  qspi* {.importc: "qspi".}: QSPIHandle
  qspi_config* {.importc: "qspi_config".}: QSPIConfig
  sdram_handle* {.importc: "sdram_handle".}: SdramHandle
  audio_handle* {.importc: "audio_handle".}: AudioHandle
  adc* {.importc: "adc".}: AdcHandle
  dac* {.importc: "dac".}: DacHandle
  usb_handle* {.importc: "usb_handle".}: UsbHandle
  led* {.importc: "led".}: GPIO
  testpoint* {.importc: "testpoint".}: GPIO
  system* {.importc: "system".}: System
  codec* {.importc: "codec".}: Ak4556
Source   Edit  
FloatPtr = ptr cfloat
Source   Edit  
FloatPtrPtr = ptr ptr cfloat
Source   Edit  
GPIO {.importcpp: "daisy::GPIO".} = object
Source   Edit  
GPIOMode {.importcpp: "daisy::GPIO::Mode", size: 4.} = enum
  INPUT = 0, OUTPUT, OPEN_DRAIN, ANALOG
Source   Edit  
GPIOPort {.importcpp: "daisy::GPIOPort", size: 4.} = enum
  PORTA = 0, PORTB, PORTC, PORTD, PORTE, PORTF, PORTG, PORTH, PORTI, PORTJ,
  PORTK, PORTX
Source   Edit  
GPIOPull {.importcpp: "daisy::GPIO::Pull", size: 4.} = enum
  NOPULL = 0, PULLUP, PULLDOWN
Source   Edit  
GPIOSpeed {.importcpp: "daisy::GPIO::Speed", size: 4.} = enum
  LOW = 0, MEDIUM, HIGH, VERY_HIGH
Source   Edit  
InterleavedAudioBuffer = ptr UncheckedArray[cfloat]
Interleaved audio buffer Source   Edit  
InterleavingAudioCallback = proc (input, output: InterleavedAudioBuffer;
                                  size: int) {.cdecl, ...raises: [].}
Nim-friendly interleaved audio callback Source   Edit  
InterleavingAudioCallbackC = proc (input: ConstFloatPtr; output: FloatPtr;
                                   size: csize_t) {.cdecl.}
Source   Edit  
Pin {.importcpp: "daisy::Pin".} = object
  port* {.importc: "port".}: GPIOPort
  pin* {.importc: "pin".}: uint8
Source   Edit  
QSPIConfig {.importcpp: "daisy::QSPIHandle::Config", bycopy.} = object
  device* {.importc: "device".}: QSPIDevice
  mode* {.importc: "mode".}: QSPIMode
Source   Edit  
QSPIDevice {.importcpp: "daisy::QSPIHandle::Config::Device", size: 4.} = enum
  IS25LP080D = 0,           ## 8 Mbit (1 MB)
  IS25LP064A = 1             ## 64 Mbit (8 MB)
Source   Edit  
QSPIHandle {.importcpp: "daisy::QSPIHandle".} = object
Source   Edit  
QSPIMode {.importcpp: "daisy::QSPIHandle::Config::Mode", size: 4.} = enum
  MEMORY_MAPPED = 0,        ## Read-only memory-mapped access
  INDIRECT_POLLING = 1       ## Full read/write/erase access
Source   Edit  
SaiHandle {.importcpp: "daisy::SaiHandle".} = object
Source   Edit  
SampleRate {.importcpp: "daisy::SaiHandle::Config::SampleRate", size: 4.} = enum
  SAI_8KHZ = 0, SAI_16KHZ, SAI_32KHZ, SAI_48KHZ, SAI_96KHZ
Source   Edit  
SdramHandle {.importcpp: "daisy::SdramHandle".} = object
Source   Edit  
System {.importcpp: "daisy::System".} = object
Source   Edit  
UsbHandle {.importcpp: "daisy::UsbHandle".} = object
Source   Edit  

Procs

proc audioSaiHandle(daisy: DaisySeed): SaiHandle {....raises: [], tags: [],
    forbids: [].}

Get the SAI handle for the Daisy Seed audio interface.

This can be useful when adding a secondary codec - the result of this function can be passed to AudioHandle.init() with an SAI2 configuration.

Source   Edit  
proc blockSize(daisy: var DaisySeed): int {....raises: [], tags: [], forbids: [].}
Get the current audio block size Source   Edit  
proc boardVersion(daisy: var DaisySeed): BoardVersion {....raises: [], tags: [],
    forbids: [].}
Check which version of Daisy Seed board is connected Source   Edit  
proc callbackRate(daisy: DaisySeed): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc changeAudioCallback(daisy: var DaisySeed; callback: AudioCallback) {.
    ...raises: [], tags: [], forbids: [].}
Change the audio callback while audio is running Source   Edit  
proc changeAudioCallback(daisy: var DaisySeed;
                         callback: InterleavingAudioCallback) {....raises: [],
    tags: [], forbids: [].}
Change the interleaved audio callback while audio is running Source   Edit  
proc deinit(audio: var AudioHandle): AudioResult {....raises: [], tags: [],
    forbids: [].}
Stop and deinitialize audio. Source   Edit  
proc deinit(daisy: var DaisySeed) {....raises: [], tags: [], forbids: [].}
Deinitialize the Daisy Seed hardware Source   Edit  
proc deinit(gpio: var GPIO) {....raises: [], tags: [], forbids: [].}
Deinitialize a GPIO pin Source   Edit  
proc delay(daisy: var DaisySeed; milliseconds: int) {....raises: [], tags: [],
    forbids: [].}
Delay for a specified number of milliseconds Source   Edit  
proc floatToS16(x: float32): int16 {.inline, ...raises: [], tags: [], forbids: [].}
Converts float to signed 16-bit Source   Edit  
proc floatToS24(x: float32): int32 {.inline, ...raises: [], tags: [], forbids: [].}
Converts float to signed 24-bit Source   Edit  
proc getChannels(audio: AudioHandle): int {....raises: [], tags: [], forbids: [].}

Get the number of audio channels.

Returns 2 when using a single SAI, 4 when using two SAI, 0 if not initialized.

Source   Edit  
proc getConfig(audio: AudioHandle): AudioConfig {....raises: [], tags: [],
    forbids: [].}
Get the current AudioHandle configuration. Source   Edit  
proc getPin(pinIndex: int): Pin {....raises: [], tags: [], forbids: [].}
Get a Pin object by its index (0-32) Source   Edit  
proc getSampleRate(audio: var AudioHandle): float {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc init(audio: var AudioHandle; config: AudioConfig; sai1, sai2: SaiHandle): AudioResult {.
    ...raises: [], tags: [], forbids: [].}

Initialize AudioHandle with two SAI, each configured in stereo I2S mode.

This is an advanced API - most users should use DaisySeed's built-in audio methods.

Source   Edit  
proc init(audio: var AudioHandle; config: AudioConfig; sai: SaiHandle): AudioResult {.
    ...raises: [], tags: [], forbids: [].}

Initialize AudioHandle with a single SAI configured in stereo I2S mode.

This is an advanced API - most users should use DaisySeed's built-in audio methods.

Source   Edit  
proc init(daisy: var DaisySeed; boost: bool = false) {....raises: [], tags: [],
    forbids: [].}
Initialize the Daisy Seed hardware Source   Edit  
proc initDaisy(boost: bool = false): DaisySeed {....raises: [], tags: [],
    forbids: [].}

Initialize a Daisy Seed board

Parameters: boost: Enable clock boost mode for higher performance

Example:

var daisy = initDaisy()

Source   Edit  
proc initGpio(pin: Pin; mode: GPIOMode = OUTPUT; pull: GPIOPull = NOPULL;
              speed: GPIOSpeed = LOW): GPIO {....raises: [], tags: [], forbids: [].}

Initialize a GPIO pin

Parameters: pin: The pin to configure (use D0(), D1(), A0(), etc.) mode: INPUT, OUTPUT, OPEN_DRAIN, or ANALOG pull: NOPULL, PULLUP, or PULLDOWN speed: LOW, MEDIUM, HIGH, or VERY_HIGH

Example:

var led = initGpio(D7(), OUTPUT)
led.write(true)

Source   Edit  
proc newPin(port: GPIOPort; pin: uint8): Pin {.importcpp: "daisy::Pin(@)",
    constructor, header: "daisy_seed.h", ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc now(daisy: var DaisySeed): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc printLine() {.inline, ...raises: [], tags: [], forbids: [].}
Print a newline. Source   Edit  
proc printLine(f: float) {.inline, ...raises: [], tags: [], forbids: [].}
Print a float with newline. Source   Edit  
proc printLine(i: int) {.inline, ...raises: [], tags: [], forbids: [].}
Print an integer with newline. Source   Edit  
proc printLine(text: cstring) {.importcpp: "daisy::DaisySeed::PrintLine(@)",
                                header: "daisy_seed.h", varargs, ...raises: [],
                                tags: [], forbids: [].}

Print a formatted debug log message with automatic line termination.

Example:

printLine("Hello from Daisy!")

Source   Edit  
proc read(gpio: var GPIO): bool {....raises: [], tags: [], forbids: [].}
Read a digital value from a GPIO pin Source   Edit  
proc s16ToFloat(x: int16): float32 {.inline, ...raises: [], tags: [], forbids: [].}
Converts signed 16-bit to float Source   Edit  
proc s24ToFloat(x: int32): float32 {.inline, ...raises: [], tags: [], forbids: [].}
Converts signed 24-bit to float Source   Edit  
proc sampleRate(daisy: var DaisySeed): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc setBlockSize(audio: var AudioHandle; size: int): AudioResult {....raises: [],
    tags: [], forbids: [].}
Set the block size after initialization. Source   Edit  
proc setBlockSize(daisy: var DaisySeed; size: int) {....raises: [], tags: [],
    forbids: [].}
Set the audio block size (number of samples per callback) Source   Edit  
proc setLed(daisy: var DaisySeed; state: bool) {....raises: [], tags: [],
    forbids: [].}

Set the built-in LED state

Parameters: state: true = ON, false = OFF

Source   Edit  
proc setOutputCompensation(audio: var AudioHandle; compensation: float): AudioResult {.
    ...raises: [], tags: [], forbids: [].}

Set an additional amount of gain compensation at the end of the callback.

Useful if the hardware input/output levels are not equal.

To calculate the value:

  1. Measure the input signal level (vin)
  2. Measure the output signal level with compensation set to 1.0 (vout)
  3. Calculate: compensation = 1.0 / (vout / vin)

Parameters: compensation: Output compensation factor

Source   Edit  
proc setOutputCompensation(daisy: var DaisySeed; compensation: float): AudioResult {.
    ...raises: [], tags: [], forbids: [].}
Convenience wrapper to set output compensation on the DaisySeed's audio handle. Source   Edit  
proc setPostGain(audio: var AudioHandle; gain: float): AudioResult {....raises: [],
    tags: [], forbids: [].}

Set the amount of gain adjustment to perform before and after callback.

Useful if the hardware has additional headroom and the nominal value shouldn't be 1.0. The hardware will clip at the reciprocal of this value.

Parameters: gain: Gain adjustment amount

Example:

daisy.audio_handle.setPostGain(0.5)  # Allow signals up to 2.0 without clipping

Source   Edit  
proc setPostGain(daisy: var DaisySeed; gain: float): AudioResult {....raises: [],
    tags: [], forbids: [].}
Convenience wrapper to set post-gain on the DaisySeed's audio handle. Source   Edit  
proc setSampleRate(audio: var AudioHandle; samplerate: SampleRate): AudioResult {.
    ...raises: [], tags: [], forbids: [].}
Set the sample rate and reinitialize the SAI as needed. Source   Edit  
proc setSampleRate(daisy: var DaisySeed; rate: SampleRate) {....raises: [],
    tags: [], forbids: [].}

Set the audio sample rate

Available rates: SAI_8KHZ, SAI_16KHZ, SAI_32KHZ, SAI_48KHZ, SAI_96KHZ

Source   Edit  
proc setTestPoint(daisy: var DaisySeed; state: bool) {....raises: [], tags: [],
    forbids: [].}
Set the test point pin state (for oscilloscope debugging) Source   Edit  
proc startAudio(daisy: var DaisySeed; callback: AudioCallback) {....raises: [],
    tags: [], forbids: [].}

Start audio processing with a multi-channel (non-interleaved) callback

The callback receives separate channels as arrays of float samples.

Example:

proc audioCallback(input, output: AudioBuffer, size: int) {.cdecl.} =
  for i in 0..<size:
    output[0][i] = input[0][i] * 0.5  # Left channel, reduce volume
    output[1][i] = input[1][i] * 0.5  # Right channel

daisy.startAudio(audioCallback)

Source   Edit  
proc startAudio(daisy: var DaisySeed; callback: InterleavingAudioCallback) {.
    ...raises: [], tags: [], forbids: [].}

Start audio processing with an interleaved callback

The callback receives interleaved samples (L, R, L, R, ...)

Source   Edit  
proc startLog(waitForPC: bool = false) {.
    importcpp: "daisy::DaisySeed::StartLog(@)", header: "daisy_seed.h",
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc stopAudio(daisy: var DaisySeed) {....raises: [], tags: [], forbids: [].}
Stop audio processing Source   Edit  
proc toggle(gpio: var GPIO) {....raises: [], tags: [], forbids: [].}
Toggle a GPIO pin state Source   Edit  
proc toggleLed(daisy: var DaisySeed) {....raises: [], tags: [], forbids: [].}
Toggle the built-in LED (uses GPIO toggle internally) Source   Edit  
proc write(gpio: var GPIO; state: bool) {....raises: [], tags: [], forbids: [].}
Write a digital value to a GPIO pin Source   Edit  

Templates

template A0(): Pin
Source   Edit  
template A1(): Pin
Source   Edit  
template A2(): Pin
Source   Edit  
template A3(): Pin
Source   Edit  
template A4(): Pin
Source   Edit  
template A5(): Pin
Source   Edit  
template A6(): Pin
Source   Edit  
template A7(): Pin
Source   Edit  
template A8(): Pin
Source   Edit  
template A9(): Pin
Source   Edit  
template A10(): Pin
Source   Edit  
template A11(): Pin
Source   Edit  
template A12(): Pin
Source   Edit  
template A13(): Pin
Source   Edit  
template D0(): Pin
Source   Edit  
template D1(): Pin
Source   Edit  
template D2(): Pin
Source   Edit  
template D3(): Pin
Source   Edit  
template D4(): Pin
Source   Edit  
template D5(): Pin
Source   Edit  
template D6(): Pin
Source   Edit  
template D7(): Pin
Source   Edit  
template D8(): Pin
Source   Edit  
template D9(): Pin
Source   Edit  
template D10(): Pin
Source   Edit  
template D11(): Pin
Source   Edit  
template D12(): Pin
Source   Edit  
template D13(): Pin
Source   Edit  
template D14(): Pin
Source   Edit  
template D15(): Pin
Source   Edit  
template D16(): Pin
Source   Edit  
template D17(): Pin
Source   Edit  
template D18(): Pin
Source   Edit  
template D19(): Pin
Source   Edit  
template D20(): Pin
Source   Edit  
template D21(): Pin
Source   Edit  
template D22(): Pin
Source   Edit  
template D23(): Pin
Source   Edit  
template D24(): Pin
Source   Edit  
template D25(): Pin
Source   Edit  
template D26(): Pin
Source   Edit  
template D27(): Pin
Source   Edit  
template D28(): Pin
Source   Edit  
template D29(): Pin
Source   Edit  
template D30(): Pin
Source   Edit  
template D31(): Pin
Source   Edit  
template D32(): Pin
Source   Edit