Hardware: Teensy 3.5 with Audio Shield SGTL5000
OS: Windows 10
Problem: Heteroskedastic divergence between implied audio input buffer time and system time. I'm trying to figure out how to keep exact time from the buffers that the Audio library is reading from the ADC. However, adding up the total number of read buffers produces an increasing discrepancy over time with the system time obtained by turning off interrupts and calling micros(). The picture below is the 1s rolling mean of the difference between the implied buffer time and the system time since the beginning of the program. I subtracted the first value of the difference from all subsequent differences--the system time includes all of the setup time and comes out to ~700,000 microseconds on the hardware that I'm using.
There is also a small drift that happens every 64 buffers collected that I've added a correcting factor for, but that's not nearly as big a problem as the increasing variance between micros() and the sum of the buffer lengths as time goes on. It looks like a kind of accumulating error to me, but I have't been able to find an accumulating error in my code. I was wondering if anyone else has encountered a similar problem?
Code:
Duty Cycle .wav:
OS: Windows 10
Problem: Heteroskedastic divergence between implied audio input buffer time and system time. I'm trying to figure out how to keep exact time from the buffers that the Audio library is reading from the ADC. However, adding up the total number of read buffers produces an increasing discrepancy over time with the system time obtained by turning off interrupts and calling micros(). The picture below is the 1s rolling mean of the difference between the implied buffer time and the system time since the beginning of the program. I subtracted the first value of the difference from all subsequent differences--the system time includes all of the setup time and comes out to ~700,000 microseconds on the hardware that I'm using.
There is also a small drift that happens every 64 buffers collected that I've added a correcting factor for, but that's not nearly as big a problem as the increasing variance between micros() and the sum of the buffer lengths as time goes on. It looks like a kind of accumulating error to me, but I have't been able to find an accumulating error in my code. I was wondering if anyone else has encountered a similar problem?
Code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <math.h>
#include "AudioSampleDutycycle.h"
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
#define AUDIO_BUFF_LN 128
// GUI Code Begins Here
AudioInputI2S i2s1;
AudioPlayMemory playMem1;
AudioAmplifier amp1;
AudioRecordQueue queue1;
AudioOutputI2S i2s2;
AudioConnection patchCord1(i2s1, 0, queue1, 0);
AudioConnection patchCord2(playMem1, amp1);
AudioConnection patchCord3(amp1, 0, i2s2, 0);
AudioControlSGTL5000 sgtl5000_1;
IntervalTimer playDutyCycle;
short availableBuffs;
short firstBuff = 1;
short audioBuff[AUDIO_BUFF_LN];
volatile long mu;
volatile long realTime;
long buffsRcvd = -1;
long bufferTime;
long sixtyFourBuffCnt;
float diffRealTimeAndBuffTime;
void playMemTimer() {
if (!playMem1.isPlaying()) {
playMem1.play(AudioSampleDutycycle);
}
}
void processMicInput() {
availableBuffs = queue1.available();
if (availableBuffs < 1) {
return;
}
buffsRcvd++;
if ((buffsRcvd % 64) == 0) {
sixtyFourBuffCnt++;
}
memcpy(audioBuff,
queue1.readBuffer(),
256);
queue1.freeBuffer();
availableBuffs--;
bufferTime = (buffsRcvd + availableBuffs) * (2901.37588685);
noInterrupts();
realTime = micros();
interrupts();
// sixtyFourBuffCnt is a correction factor for a timing discrepancy I noticed happening every 64 buffers of 128 samples in the output. The 2.7195 number is an eyeballed estimate from watching
// the data scroll by on the serial monitor, but as you can see from the picture, it's a slight overestimate, amounting to ~20 microseconds of difference after 10000 samples.
diffRealTimeAndBuffTime = (realTime + 2.7195 * sixtyFourBuffCnt) - bufferTime;
Serial.println(diffRealTimeAndBuffTime);
}
void setup() {
// put your setup code here, to run once:
amp1.gain(1);
Serial.begin(9600);
AudioMemory(52);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
queue1.begin();
playDutyCycle.priority(128);
playDutyCycle.begin(playMemTimer,
23235);
}
void loop() {
// put your main code here, to run repeatedly:
if (!playMem1.isPlaying()) {
playMem1.play(AudioSampleDutycycle);
}
processMicInput();
}
Duty Cycle .wav:
Code:
// Audio data converted from WAV file by wav2sketch
#include "AudioSampleDutycycle.h"
// Converted from dutyCycle.wav, using 44100 Hz, 16 bit PCM encoding
const unsigned int AudioSampleDutycycle[512] = {
0x81000400,0xFCB9004E,0xE7E70CC8,0x1D790FBB,0x71C8A6A1,0x1E6FAD10,0xF8420215,0xFF74035D,
0x00000007,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};
Code:
// Audio data converted from WAV file by wav2sketch
extern const unsigned int AudioSampleDutycycle[512];