0

I'm trying to stream voice to the MQTT broker. I'm using esp8266(NodeMCU1.0) and it's ADC to sampling the audio signal at 4KHz and 8-bit PCM audio format. I used Pubsubclient.h library to publish audio packets to the broker but on the other side when I receive packets and play them I have the interrupted voice and I have a delay between playing packets as long as my buffer size. please help me to have continues voice.

I have 2 main problems: 1) delay between playing packets as long as my buffer size

example of what i received: ;D ;D ;D .....|||||..........|||||||...........|||||||||............||||||||

2) Quality of voice: I receive a noisy voice.

Please help me! Thanks.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "Knight";
const char* password = "****";
const char* mqtt_server = "104.21.218.224";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (4096)
int i;
byte voice[MSG_BUFFER_SIZE];

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}



void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ashkan";
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      if (!client.publish("doorphone/connected", "true")) {
        Serial.println("publish failed, either connection lost, or message too large");
      }
      else {
        Serial.println("publish succeeded");

      }
      // ... and resubscribe
      //      client.subscribe("doorphone/open");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  for (i = 0; i < MSG_BUFFER_SIZE; i++) {
    voice[i] = analogRead(A0);
    //        client.write(voice[i]);
            delayMicroseconds(125);
  }
  client.publish("doorphone/connected", voice, MSG_BUFFER_SIZE);
}
  • I will happily be corrected, but I don’t believe MQTT has the bandwidth to start approaching any sort of quality playback. So **2** I would say is unachievable – fdcpp Mar 18 '20 at 20:25
  • With problem **1** you will need to have ideally a couple of buffers of audio ready to play. So _buffer one_ is being filled while _buffer two_ is the source of audio. When _buffer two_ has finished playing, switch buffers so that _buffer one_ is now the source and _buffer two_ is being filled – fdcpp Mar 18 '20 at 20:30
  • 1
    I disagree; MQTT certainly could have the bandwidth; it really depends on the broker and what it's running on. Latency is also an issue. – romkey Mar 18 '20 at 22:09
  • First thing - have you confirmed that the data you're transmitting is good? If you're recording noisy voice, that has nothing to do with the MQTT broker. Analog to digital on the ESP8266 is not particularly good; you may need to use an external ADC to get better quality. – romkey Mar 18 '20 at 22:11
  • Second thing, you're going to miss voice samples while you publish the data, which will take some time. A better way to write the code would be to take analog samples from an interrupt handler that runs once every 125 microseconds. Fill a ring buffer twice the size of the message you're sending. Once one buffer fills, transmit it. You'll still be collecting audio samples in the other buffer while the transmit happens. – romkey Mar 18 '20 at 22:13
  • Third thing, a lot depends on how your receiver is handling the data it gets, too. If it's written to just get a buffer of data, play it and then wait for another one, you're never going to get good quality out of it. – romkey Mar 18 '20 at 22:13
  • I have to agree with others here: MQTT was never designed for real-time audio streaming...that is what RTSP is for! It can handle the packet size, but it has no guarantees about performance or packet order! If you plan to use it to "broadcast" an audio stream to multiple receivers, I suspect you will be greatly disappointed. – JD Allen Mar 21 '20 at 00:41

0 Answers0