Writing recorded audio to SD card - prominent sound artefacts hearable

Status
Not open for further replies.

ColdFire

Member
Hi,

I'm trying to record audio using a Teensy 3.6, powered by a 1s Lipo (fully charged, 4.2V to Vin). I record mono, 10KHz, using double buffering and writing to the sd card after 16000 samples have been obtained. During write operations a prominent "queek" is recorded. I already went through some threads here discussing this topic, suggesting to implement some hardware hacks on the mic breakout.

So I eliminated the mic board by just feeding ~1.65V (absolute silence) to pin 14 by using a voltage divider between AREF and Analog Ground. Still the "queek" is there. I guess there is nothing I can do about it?

As my knowledge about electronics is very limited (setting up a voltage divider is probably the most I can do) I'm now stuck. What I will try next is to do the recording on another Tennsy (let's assume on a 3.2), sending the samples from the 3.2 to the 3.6, hoping that the serial communication will not produce any "queek"s.

Code:
#include <SD.h>
#include <SPI.h>
#include <TimerOne.h>


#define IN 14
#define OUT A21
#define BSTART 16 // Start button
#define BSTOP 17  // Stop Button
#define AMP 5 // Prop shield amplifier

const uint16_t SAMPLE_RATE = 10000;
const uint8_t SAMPLE_FORMAT = 16;
const uint16_t SAMPLE_COUNT = 32000U;
const uint32_t SAMPLE_INTERVAL = 1000000UL / SAMPLE_RATE;

volatile uint16_t samples[SAMPLE_COUNT]; //  recording goes here
                                         //  after recording 16000 samples the first half of
                                         //  this array is written to the sd card
                                         //  this is hearable as a "queek" when recording goes on then 

volatile uint32_t which;
volatile uint8_t finished;
uint8_t written;
uint32_t startMicros;

File dataFile;

auto initSamples = [&] { for(volatile uint16_t &s : samples) s = 32768; };
auto waitForever = [] { while(1) ; };

void setup() 
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(AMP, OUTPUT);
  pinMode(BSTART, INPUT_PULLUP);
  pinMode(BSTOP, INPUT_PULLUP);
  analogReadResolution(SAMPLE_FORMAT);
  analogWriteResolution(SAMPLE_FORMAT);
  Timer1.initialize(SAMPLE_INTERVAL);

  delay(2000);

  initSamples();

  if (!SD.begin(BUILTIN_SDCARD)) 
  {
    Serial.println("SD error!!!");
    waitForever();
  }
  
  Serial.println("Press Start Button for recording");
  while(digitalRead(BSTART) == HIGH)
    ;

  if (SD.exists("samples.txt"))
    SD.remove("samples.txt");

  if (dataFile = SD.open("samples.txt", FILE_WRITE)) 
  {
    which = -1;
    finished = 0;
    written = 0;
    delay(300);
    digitalWrite(13, HIGH);
    Timer1.attachInterrupt(record);
  }
  else
  {
    Serial.println("SD card open failed...");
    waitForever();
  }
}
 

void loop() 
{
  while(digitalRead(BSTOP) == HIGH)
  {
    if (finished != written)
    {
      Serial.println(finished);
      if (finished == 2)
      {
        Timer1.detachInterrupt(); // Stop recording after 32000 samples (2 junks) for test purposes
        dataFile.write((uint8_t *)samples+sizeof(samples)/2, sizeof(samples)/2);
        break;  // Leave loop after 2 chunks
      }
      else
      {
        dataFile.write((uint8_t *)samples, sizeof(samples)/2);
      }
      written = finished;
      Serial.println(".");
    }
  }

  //Timer1.detachInterrupt();
  dataFile.close();
  digitalWrite(13, LOW);

  delay(200);
    
  Serial.println("Press Button to read samples from sd card");
  while(digitalRead(BSTART) == HIGH)
    ;

  Serial.println("Open File for read....");
  
  initSamples();
  
  if (!(dataFile = SD.open("samples.txt", FILE_READ))) 
  {
    Serial.println("SD file open failed!!!");
    waitForever();
  } else
  {
    uint32_t cnt = dataFile.read((uint8_t *)samples, sizeof(samples));
    dataFile.close();
    
    if (cnt != sizeof(samples))
    {
      Serial.print("Read failed!!!!");
      waitForever();
    }
    
    for(uint16_t i=0; i<10; i++) 
      Serial.println(samples[i]);
  }

  delay(200);

  while(1)
  {
    Serial.println("Press Button for replay");
    while(digitalRead(BSTART) == HIGH)
      ;
  
    digitalWrite(AMP, HIGH);
    delay(20);
    
    for (which=0;which<SAMPLE_COUNT;which++)  // Replay just for test purposes
    {
      analogWrite(OUT, samples[which]);
      
      startMicros = micros();
      while (micros() - startMicros < SAMPLE_INTERVAL)
        ;
    }
    digitalWrite(AMP, LOW);
  }
}

void record(void)
{
  if (++which == SAMPLE_COUNT)
  {
    finished = 2;
    which = 0;
  }
  if (which == SAMPLE_COUNT/2)
  {
    finished = 1;
  }
  
  *(samples+which) = analogRead(IN);
}
 
Status
Not open for further replies.
Back
Top