o.w.varley
Well-known member
Hey all,
I'm doing a project at the moment where I'm pushing out audio captured from a Teensy 4.1 + shield board over a LAN.
I've created my own Audio Player (AudioPlayMemoryRaw) that can take the raw audio blocks captured from an AudioRecordQueue and play it out via an AudioOutputI2S. My plan is to prove that I can capture and play back the audio locally (on the same Teensy) before progressing to passing the raw audio blocks over UDP to another Teensy. I'm getting some strange occurrences that make my think I don't have a correct understanding of how the Teensy/Audio Shield allocate and free memory.
With the current setup, I can happily capture and play back the first few seconds of audio, however, it then cuts out and I hear a constant tone in my headset. Doing further investigation if I remove the output and the call to playRaw.enqueue then the code runs absolutely fine. This makes me think that playRaw isn't correctly freeing the blocks or, I guess, it could be my use of std queue.
Main play:
AudioPlayMemoryRaw:
AudioPacket
Any help would be greatly appreciated.
I'm doing a project at the moment where I'm pushing out audio captured from a Teensy 4.1 + shield board over a LAN.
I've created my own Audio Player (AudioPlayMemoryRaw) that can take the raw audio blocks captured from an AudioRecordQueue and play it out via an AudioOutputI2S. My plan is to prove that I can capture and play back the audio locally (on the same Teensy) before progressing to passing the raw audio blocks over UDP to another Teensy. I'm getting some strange occurrences that make my think I don't have a correct understanding of how the Teensy/Audio Shield allocate and free memory.
With the current setup, I can happily capture and play back the first few seconds of audio, however, it then cuts out and I hear a constant tone in my headset. Doing further investigation if I remove the output and the call to playRaw.enqueue then the code runs absolutely fine. This makes me think that playRaw isn't correctly freeing the blocks or, I guess, it could be my use of std queue.
Main play:
Code:
#include "AudioPlayMemoryRaw.h"
#include "AudioPacket.h"
#include <Audio.h>
AudioInputI2S mike; //xy=105,63
AudioRecordQueue queue; //xy=281,63
AudioPlayMemoryRaw playRaw; //xy=302,157
AudioOutputI2S headphones; //xy=470,120
AudioConnection patchCord1(mike, 0, queue, 0);
AudioConnection patchCord2(mike, 0, headphones, 0);
AudioConnection patchCord3(mike, 0, headphones, 1);
AudioControlSGTL5000 sgtl5000;
int led = 13;
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
Serial.begin(115200);
AudioMemory(60);
// Enable the audio shield, select input, and enable output
sgtl5000.enable();
sgtl5000.inputSelect(AUDIO_INPUT_MIC);
sgtl5000.micGain(35);
sgtl5000.volume(0.5);
queue.begin();
playRaw.play();
Serial.println("Start Audio Up");
}
void report_memory()
{
Serial.printf("CPU: %.2f (%.2f), MEM: %i (%i)\n",
AudioProcessorUsage(), AudioProcessorUsageMax(),
AudioMemoryUsage(), AudioMemoryUsageMax());
}
void readFromQueue()
{
t_AudioPacket packet;
int16_t memoryBefore;
if (queue.available() >= 1)
{
memoryBefore = AudioMemoryUsage();
memcpy(packet.data, queue.readBuffer(), sizeof(packet.data));
queue.freeBuffer();
playRaw.enqueue(packet);
if (memoryBefore == AudioMemoryUsage())
Serial.println("No memory released by freeBuffer");
}
}
// the loop routine runs over and over again forever:
void loop()
{
readFromQueue();
}
AudioPlayMemoryRaw:
Code:
#include "AudioPlayMemoryRaw.h"
#include <Arduino.h>
#include "play_sd_raw.h"
#include "spi_interrupt.h"
#include <queue>
std::queue <t_AudioPacket> _OutputQueue;
bool AudioPlayMemoryRaw::play()
{
stop();
playing = true;
return true;
}
void AudioPlayMemoryRaw::enqueue(t_AudioPacket packet)
{
_OutputQueue.push(packet);
}
void AudioPlayMemoryRaw::stop(void)
{
if (playing)
{
playing = false;
}
}
void AudioPlayMemoryRaw::update(void)
{
unsigned int i;
audio_block_t* block;
// only update if we're playing
if (!playing) return;
// allocate the audio blocks to transmit
block = allocate();
if (block == NULL) return;
if (_OutputQueue.size() > 0)
{
t_AudioPacket packet = _OutputQueue.front();
_OutputQueue.pop();
memcpy(block->data, packet.data, sizeof(block->data));
transmit(block);
release(block);
}
}
AudioPacket
Code:
#pragma once
struct t_AudioPacket
{
int16_t data[AUDIO_BLOCK_SAMPLES];
};
Any help would be greatly appreciated.