earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
2.04k stars 434 forks source link

WAV Output to mixer stub blocks loop() #247

Open thijsdebont opened 4 years ago

thijsdebont commented 4 years ago

I'm working on a sketch to learn the mixer ins-n-outs. I found that playing a WAV audio file (from SD) to a mixer stub instead of the regular output, blocks the main loop() as long as the file is playing. Output straight to I2S works as expected (not blocking). Tried increasing the buffer, but no dice. Big chance the fault is user error, so sketch below:

#include <Preferences.h> 
#include <Bounce2.h>

#include "AudioFileSourceSD.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"
#include "AudioOutputMixer.h"

#define POWER_SD  15
#define POWER_5V  17
#define PWR_BTN   35

// Audio variables
volatile bool playing = 0;
float fCurrentVolume  = 80;
float fMainVolume     = 50;

AudioGeneratorWAV *wav[2];
AudioFileSourceSD *file[2];
AudioOutputI2S *out;
AudioOutputMixer *mixer;
AudioOutputMixerStub *stub[2];

Bounce debouncer = Bounce();                                      // Tap button debouncer

Preferences pref;

void setup() {
  pinMode(PWR_BTN, INPUT_PULLDOWN);
  pinMode(POWER_5V, OUTPUT);
  pinMode(POWER_SD, OUTPUT);
  digitalWrite(POWER_5V, HIGH);         // Apply power to 5V supply (LED's and amplifier)

  Serial.begin(115200);
  delay(50);

  digitalWrite(POWER_SD, HIGH);
  delay(200);                                       // Wait for SD card to initialize
  SD.begin();                                       // Start SD card

  debouncer.attach(PWR_BTN);
  debouncer.interval(25);

  out = new AudioOutputI2S();
  mixer = new AudioOutputMixer(128, out);
  stub[0] = mixer->NewInput();

  file[0] = new AudioFileSourceSD();
  wav[0] = new AudioGeneratorWAV();

  stub[0]->SetGain(fMainVolume/100);
}

void loop() {
  fnHandleButton();

  if(wav[0]->isRunning()) {
    if (!wav[0]->loop()) {
      stub[0]->stop();
      wav[0]->stop();
    }
  }
}

void fnPlay (String stFile) {
  if(wav[0]->isRunning()) {
    fnStop();
  }

  if(stFile.indexOf("/") != 0) {
    stFile = "/" + stFile;
  }

  file[0]->open((char*)stFile.c_str());
  wav[0]->begin(file[0], stub[0]);
}

void fnStop() {
  if(wav[0]->isRunning()) {
    stub[0]->stop();
    wav[0]->stop();
  }
}

void fnHandleButton() {
  debouncer.update();
  if(debouncer.rose()) {
    fnPlay("rhodes.wav");
  }
  if(debouncer.fell()) {
    Serial.println("Stop button");
    fnStop();
  }
}
ChuckMash commented 10 months ago

I've run into the same issue using ESP8266 D1 Mini. The solution for me was to decrease the size of the buffer rather than increase it.

For ESP32 I was using

mixer = new AudioOutputMixer(1024, out);

For ESP8266, to fix the blocking

mixer = new AudioOutputMixer(64, out);

All in all though, not having much success with the ESP8266 and mixer.