Problem Using AudioPlaySdRaw's play() Function

Status
Not open for further replies.

gtrmstr53

Member
Hi there,

I'm trying to build a device that can record short sound snippets and play them back on command. I'm using a Teensy 3.6, and put together the following code to try and test the core functionality:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Bounce.h>
#include <SerialFlash.h>

#define REC_PIN_0             7
#define INPUT_PIN             A1
#define TRIG_PIN_0            8
#define SAMPLE_NAME           "TstAudIO.raw"
#define SDCARD_CS_PIN         BUILTIN_SDCARD


AudioInputAnalog              input(INPUT_PIN);
AudioRecordQueue              recQueue;
AudioPlaySdRaw                samplePlayer;
AudioOutputAnalogStereo       outputs;

AudioConnection               in2Rec(input, 0, recQueue, 0);
AudioConnection               samp2Outs(samplePlayer, 0, outputs, 0);

Bounce recButton = Bounce(REC_PIN_0, 10);
Bounce trigIn = Bounce(TRIG_PIN_0, 10);


void setup() {
  //Audio Setup
  AudioMemory(80);

  //Serial Setup
  Serial.begin(9600);
  while (!Serial) {}

  //Trig/Rec Setup
  pinMode(REC_PIN_0, INPUT_PULLUP);
  pinMode(TRIG_PIN_0, INPUT_PULLUP);

  //SD Setup
  while (!(SD.begin(SDCARD_CS_PIN))) {
    Serial.println("Unable to access the SD card");
    delay(500);
  }

  analogReadResolution(16);

  Serial.println("setup() complete");
  Serial.println("Version with 16bit res");  
}


void loop() {
  updateRecButtons();

  updateTrigIns();
}


void updateRecButtons() {
  recButton.update();
  if (recButton.fallingEdge()) {
    Serial.println("Record Botton Pressed");
    record();
  }
}


void updateTrigIns() {
  trigIn.update();
  if (trigIn.fallingEdge()) {
    Serial.println("Sample Triggered");
    playSample();
  }
}


void record() {
  Serial.println("Entering record()");

  //Setup file to record into
  if(SD.exists(SAMPLE_NAME)) {
    SD.remove(SAMPLE_NAME);
    Serial.print("Deleting ");
    Serial.println(SAMPLE_NAME);
  }
  File file = SD.open(SAMPLE_NAME, FILE_WRITE);
  if(!file) {
    Serial.println("Error: File Not Found");
    while (digitalRead(REC_PIN_0) == LOW) {}
    return;
  }

  //Start Recording
  Serial.println("Starting to Record");
  recQueue.begin();
  while (!recButton.risingEdge()) {
    recButton.update();
    
    if (recQueue.available() >= 2) {
      byte buffer[512];
      
      memcpy(buffer, recQueue.readBuffer(), 256);
      recQueue.freeBuffer();
      memcpy(buffer+256, recQueue.readBuffer(), 256);
      recQueue.freeBuffer();
      
      file.write(buffer, 512);
    }
  }

  //Finish Recording
  Serial.println("Record Button Released");
  recQueue.end();
  while (recQueue.available() >= 2) {
    file.write((byte*)recQueue.readBuffer(), 256);
    recQueue.freeBuffer();
  }  
  file.close();
  Serial.println("Exiting record()");
}


void playSample() {
  if (!SD.exists(SAMPLE_NAME)) {
    Serial.print("File ");
    Serial.print(SAMPLE_NAME);
    Serial.println(" not found");
  } else {
    Serial.println("Playing sample");
    samplePlayer.stop();
    samplePlayer.play(SAMPLE_NAME);
  }
}

REC_PIN_0 and TRIG_PIN_0 are both connected to mechanical switches that control recording and playback (respectively). INPUT_PIN is connected to the audio in.

The problem I'm running into is that this sketch runs fine when I'm just pressing the record button (REC_PIN_0), but freezes whenever I press the play button (TRIG_PIN_0). Pressing the record button prints all the expected comments to the Arduino IDE's serial monitor, and creates the expected .raw file. Pressing the play button satisfies the condition for the if statement in updateTrigIns(), but the Teensy does not print 'Sample Triggered' to the serial monitor, and after pressing the play button nothing happens if I try pressing the record button.

After some troubleshooting, I've found out that if I comment out the line from playSample() that says 'samplePlayer.play(SAMPLE_NAME)' the sketch runs fine. Both 'Sample Triggered' and 'Playing sample' show up on the serial monitor, so that's telling me that I have the button wired up correctly and don't have any issues with the control flow of this sketch.

However, I'm not sure what I should be trying now. I'm pretty sure I remember seeing somewhere that AudioInputAnalog records 12bit data, while AudioPlaySdRaw expects 16bit data. I also seem to remember seeing a function related to AudioInputAnalog that lets you change the resolution of 16bit, but the only thing I've been able to find this time around is analogReadResolution(), which isn't specific to AudioInputAnalog.

Am I on the right track in thinking there's some incapatibility between the sort of file AudioInputAnalog creates and the sort of file AudioPlaySdRaw is meant to play? Or is there something else I should be looking into? Any thoughts you can share would be a huge help.

Thanks!
 
Have you played the recorded .raw file on a computer and verified that it's a good file, no corruption, etc?

Once you know the file is okay, can you make a standalone sketch to play the pre-recorded .raw file?

Edit... AudioInputAnalog casts the ADC samples to 16 bit, so no worries about resolution mismatch.
 
Code:
  while (recQueue.available() >= 2) {
    file.write((byte*)recQueue.readBuffer(), 256);
    recQueue.freeBuffer();
  }
This will leave one record buffer in the queue. Wouldn't it be better to use >= 1 and drain it completely?

Pete
 
Have you played the recorded .raw file on a computer and verified that it's a good file, no corruption, etc?

Once you know the file is okay, can you make a standalone sketch to play the pre-recorded .raw file?

Edit... AudioInputAnalog casts the ADC samples to 16 bit, so no worries about resolution mismatch.

I finally got some time to work on this project again, and I realized that I made a mistake on the hardware side of things (I added a resistor to the input path where there shouldn't be one, which made the Teensy's audio input pin stay at a slightly negative voltage). After shorting the resistor, everything seems to be working like it should.

Thanks to wcalvert for the troubleshooting ideas, as they're what led me to recognize the hardware problem.
 
Status
Not open for further replies.
Back
Top