Close

Sound effects

A project log for TARDIS Themed Board Game Cabinet

Board game cabinet with a Doctor Who TARDIS theme with door sensors, LED strips, roof light and sound

cafelizardocafelizardo 04/04/2022 at 08:520 Comments

I really like the Robertson WAVE shield from Adafruit that can play multiple channels at the same time. Initially I used individual digital output pins from the Arduino to pull the level inputs on the WAV board but I eventually switched to using the MIDI interface. I wanted to preserver the ability to upload new code into the Arduino using the default serial port so I needed another serial port which is when I upgraded to an Arduino Mega board.   The code assumes particular tracks are stored on the SD card on the shield.


Code snippet for controlling audio playback

/*
 * tardis_audio.h
 * Claude Felizardo 2018-08-29
 * 
 * uses Wave Trigger library for Robertson WavTrigger board from Adafruit
 */

#ifndef _tardis_audio_h_
#define _tardis_audio_h_

#if 1
// Wave trigger library using software UART
// https://github.com/robertsonics/WAV-Trigger-Arduino-Serial-Library
#include <Metro.h>            // Timer class used by AltSoftSerial
#include <AltSoftSerial.h>    // Software serial on Uno uses 16-bit timer, Rx8, Tx9, PWM10 not available
// https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
#define __WT_USE_ALTSOFTSERIAL__
#else
#define __WT_USE_SERIAL3__
#endif
#include <wavTrigger.h>     // wave trigger library

#define TARDIS_AUDIO_VERSION "$Id$"


class List {
    int* array;
    int count;
    int index;
    enum {ORDERED, SHUFFLED, RANDOM} order;
  public:
    List(int list[], int count)
    {
      this->array = (int*)calloc(count, sizeof(int));
      this->count = count;
      this->index = 0;
      this->order = ORDERED;
      for (int idx = 0; idx < this->count; idx++) this->array[idx] = list[idx];
    }
    int size() {
      return this->count;
    }
    int getNext() {
      if (this->index >= this->count) {
        switch (this->order) {
          case SHUFFLED:
          case RANDOM: shuffle();
            break;
        } // switch
        this->index = 0;
      }
      return this->array[this->index++];
    }
    void shuffle() {
      for (int idx = 0; idx < this->count; idx++) {
        int r = random(idx, this->count);
        int temp = this->array[idx];
        this->array[idx] = this->array[r];
        this->array[r] = temp;
      }
      this->order = SHUFFLED;
    }
    void print(const char* name) {
        char buffer[200];
        sprintf(buffer, "%s num tracks is %d", name, size());
        Serial.println(buffer);
        for (int i = 0; i < size(); i++) {
            int z = getNext();
            sprintf(buffer, "%d: track=%d", i, z);
            Serial.println(buffer);
        }
    }
}; // class List

int TARDIS_tracks[] = {1009, 1010, 1011, 1012};
List TARDIS_list(TARDIS_tracks, sizeof(TARDIS_tracks) / sizeof(int));
int Theme_tracks[] = {2009, 2010, 2011, 2012};
List Theme_list(Theme_tracks, sizeof(Theme_tracks) / sizeof(int));
int Num_tracks[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
List Num_list(Num_tracks, 9);//sizeof(Num_tracks) / sizeof(int));
int Alt_tracks[] = {500, 501, 502, 503, 504, 505};
List Alt_list(Alt_tracks, sizeof(Alt_tracks) / sizeof(int));

class TardisAudio
{
static wavTrigger wTrig;    // Our WAV Trigger object

public:

    static void setup()
    {
        Serial.println("TardisAudio::setup(): calling wTrig.start()");
        // WAV Trigger startup at 57600
        wTrig.start();

        // If the Uno is powering the WAV Trigger, we should wait for the WAV Trigger
        //  to finish reset before trying to send commands.
        Serial.println("TardisAudio::setup(): waiting for WAV trigger to start");
        delay(1000);

        // If we're not powering the WAV Trigger, send a stop-all command in case it
        //  was already playing tracks. If we are powering the WAV Trigger, it doesn't
        //  hurt to do this.
        Serial.println(F("TardisAudio::setup(): calling stopAllTracks"));
        wTrig.stopAllTracks();

        TARDIS_list.shuffle();
        TARDIS_list.print("TARDIS");

        Theme_list.shuffle();
        Theme_list.print("Theme");

        Num_list.shuffle();
        Num_list.print("Num");

        Alt_list.shuffle();
        Alt_list.print("Alt");

        TardisAudio::stopAll();

        Serial.println("TardisAudio::setup(): returning");
    } // setup

    static void stopAll()
    {
        Serial.println("Stopping audio");
        wTrig.stopAllTracks();
    } // stopAll

    static void playTrack(int track)
    {
        wTrig.trackPlaySolo(track);
    } // playTrack

    static int sound_bank;
    static void change_sound_bank()
    {
        sound_bank = 1 - sound_bank;
        Serial.print(F("sound_bank="));Serial.println(sound_bank, DEC);
    } // change_sound_bank

}; // class TardisAudio

wavTrigger TardisAudio::wTrig;    // Our WAV Trigger object
int TardisAudio::sound_bank = 0;

#endif // _tardis_audio_h_

Discussions