#include <Audio.h>
#include <QNEthernet.h>
#include <Wire.h>
using namespace qindesign::network;
// Define Teensy Audio components
AudioPlayQueue playQueue;
AudioOutputI2S i2sOutput;
AudioConnection patchCord1(playQueue, 0, i2sOutput, 0);
AudioConnection patchCord2(playQueue, 0, i2sOutput, 1);
AudioControlSGTL5000 audioControl;
// Network configuration
IPAddress staticIP(192, 168, 144, 32); // Teensy's static IP
IPAddress subnet(255, 255, 255, 0); // Subnet mask
IPAddress gateway(192, 168, 144, 12); // Gateway IP
const int localPort = 55555; // Teensy's listening port for RTP
const int rtpHeaderSize = 12; // RTP header size for PCM
EthernetUDP udp;
void setup() {
AudioMemory(12);
Serial.begin(115200);
while (!Serial); // Wait for Serial Monitor to connect
// Initialize Ethernet with a static IP
Ethernet.begin(staticIP, subnet, gateway);
udp.begin(localPort);
// Initialize audio control (SGTL5000)
audioControl.enable();
audioControl.volume(0.5);
Serial.println("Setup complete, ready to receive RTP audio");
}
void loop() {
int packetSize = udp.parsePacket();
// Process only packets with expected size
if (packetSize > rtpHeaderSize) {
// Read packet data
uint8_t packetBuffer[packetSize];
int bytesRead = udp.read(packetBuffer, packetSize);
// Debug: Print packet size, IP, Port, and bytes read
Serial.print("Received packet from IP: ");
Serial.print(udp.remoteIP());
Serial.print(" Port: ");
Serial.print(udp.remotePort());
Serial.print(" Packet Size: ");
Serial.print(packetSize);
Serial.print(" Bytes Read: ");
Serial.println(bytesRead);
// Check if bytesRead matches the packetSize
if (bytesRead != packetSize) {
Serial.println("Error: Bytes read do not match packet size.");
return; // Skip processing if read size is incorrect
}
// Check IP and Port (if needed for security)
IPAddress remoteIP = udp.remoteIP();
int remotePort = udp.remotePort();
if (remoteIP != IPAddress(192, 168, 144, 20)) {//|| remotePort != 34855) {
Serial.println("Warning: Unexpected IP or port");
return;
}
// Prepare to copy audio data, skipping RTP header
int audioDataSize = (packetSize - rtpHeaderSize) / 2; // Size in int16 samples
int16_t audioData[audioDataSize];
// Extract audio data and print first and last sample for verification
for (int i = 0; i < audioDataSize; i++) {
audioData[i] = (packetBuffer[rtpHeaderSize + i * 2] << 8) | (packetBuffer[rtpHeaderSize + i * 2 + 1]);
}
// Debug: Print entire buffer in HEX format
Serial.print("RTP Packet Data (HEX): ");
for (int i = 0; i < packetSize; i++) {
if (i % 16 == 0) Serial.println(); // New line every 16 bytes
Serial.print(packetBuffer[i], HEX);
Serial.print(" ");
}
Serial.println();
// Print first and last audio samples
Serial.print("First audio sample: ");
Serial.println(audioData[0]);
Serial.print("Last audio sample: ");
Serial.println(audioData[audioDataSize - 1]);
// Queue audio data for playback
if (playQueue.available() > 0) {
int16_t *queueBuffer = playQueue.getBuffer();
memcpy(queueBuffer, audioData, audioDataSize * sizeof(int16_t));
playQueue.playBuffer();
Serial.println("Audio data queued for playback");
} else {
Serial.println("playQueue not available");
}
} else {
Serial.print("Invalid packet size (too small or read error): ");
Serial.println(packetSize);
}
delay(10); // Allow some time for other processes
}