Skip to content

Commit

Permalink
Merge pull request #64 from hogthrob/master
Browse files Browse the repository at this point in the history
Potential fix for #53 and support for ESP32 A1S v2.3 with ES8388
  • Loading branch information
Romkabouter authored Jun 28, 2021
2 parents 71aaccb + c0e9476 commit 7459f7d
Show file tree
Hide file tree
Showing 6 changed files with 623 additions and 135 deletions.
31 changes: 26 additions & 5 deletions PlatformIO/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,53 @@
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = esp32dev

[common]
build_flags =
'-DFIXED_POINT=1'
'-DOUTSIDE_SPEEX=1'

[env:esp32dev]
[env]
extra_scripts = pre:load_settings.py
platform = espressif32
upload_speed = 115200
upload_speed = 921000
board = esp32dev
framework = arduino
board_build.partitions = ../OTABuilder/partitions_two_ota.csv
build_flags = ${common.build_flags}
monitor_speed = 115200
monitor_speed = 921000
monitor_filters = esp32_exception_decoder

;This is where you can add dependencies of your device.
lib_deps =
https://github.com/matrix-io/matrixio_hal_esp32.git
https://github.com/Locoduino/RingBuffer.git
https://github.com/marvinroger/async-mqtt-client.git
https://github.com/me-no-dev/AsyncTCP.git
https://github.com/knolleary/pubsubclient.git
https://github.com/bblanchon/ArduinoJson.git
ESP Async WebServer
m5stack/M5Atom
fastled/FastLED
yveaux/AC101 @ ^0.0.1
yveaux/AC101 @ ^0.0.1


[env:esp32dev]

;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3, INMP441MAX98357A=4

[env:m5atomecho]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=0

[env:matrixvoice]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=1

[env:audiokit]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=2

[env:inmp441]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=3

[env:inmp441Mmax98357a]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=4
142 changes: 142 additions & 0 deletions PlatformIO/src/Esp32RingBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#pragma once
#include <Arduino.h>
#include <freertos/ringbuf.h>


/**
* @brief A ringbuffer class based on the ESP32 FreeRTOS ringbuffer implementation
*
* The main use case is to convert a stream buffer (typically bytes) to a larger fixed item
* size (such as 16bit samples).
*
* Pushing into the buffer can be done on the granularity of the IT item size,
* popping returns always a full output item.
*
* The implementation is multi-core and multi-thread safe. Use methods ...FromISR
* in an interrupt service routine.
*/
template <
typename IT,
typename OT,
size_t S>

class Esp32RingBuffer
{
RingbufHandle_t rbh;

public:
Esp32RingBuffer()
{
static_assert((sizeof(OT) % sizeof(IT)) == 0, "sizeof(OT) must be a multiple of sizeof(IT)");
rbh = xRingbufferCreate(S * sizeof(OT), RINGBUF_TYPE_BYTEBUF);
}


/* Push an input item to the end of the buffer */
bool push(const IT inElement)
{
return pdTRUE == xRingbufferSend(rbh, &inElement, sizeof(IT), pdMS_TO_TICKS(10));
}

/* Push an item array to the end of the buffer */
bool push(const IT *const inElement_p, size_t len = 1)
{
return pdTRUE == xRingbufferSend(rbh, inElement_p, sizeof(IT)*len, pdMS_TO_TICKS(10));
}

/* Pop the data at the beginning of the buffer */
bool pop(OT &outElement)
{
bool retval = false;
size_t item_size;
if (size() >= sizeof(OT))
{
OT *item_p = static_cast<OT *>(xRingbufferReceiveUpTo(rbh, &item_size, pdMS_TO_TICKS(100), sizeof(OT)));
if (item_p != NULL)
{
if (item_size != sizeof(OT))
{
Serial.println("Did not receive enough data, this should not happen");
}
else
{
outElement = *item_p;
retval = true;
}
vRingbufferReturnItem(rbh, item_p);
}
}
return retval;
}

/* Push an input item to the end of the buffer from within an interrupt service routine */
bool pushFromISR(const IT inElement)
{
return pdTRUE == xRingbufferSendFromISR(rbh, &inElement, sizeof(IT), pdMS_TO_TICKS(10));
}

/* Push an input item array to the end of the buffer from within an interrupt service routine */
bool pushFromISR(const IT *const inElement_p, size_t len = 1)
{
return pdTRUE == xRingbufferSendFromISR(rbh, inElement_p, sizeof(IT)*len, pdMS_TO_TICKS(10));
}

/* Pop the data from the beginning of the buffer from within an interrupt service routine */
bool popFromISR(OT &outElement)
{
bool retval = false;
size_t item_size;
if (size() >= sizeof(OT))
{
OT *item_p = static_cast<OT *>(xRingbufferReceiveUpToFromISR(rbh, &item_size, sizeof(OT)));
if (item_p != NULL)
{
if (item_size != sizeof(OT))
{
Serial.println("Did not receive enough data, this should not happen");
}
else
{
outElement = *item_p;
retval = true;
}
vRingbufferReturnItemFromISR(rbh, item_p);
}
}
return retval;
}

/* Return true if the buffer is full */
bool isFull() { return xRingbufferGetCurFreeSize(rbh) == 0; }

/* Return true if the buffer is empty */
bool isEmpty() { return xRingbufferGetCurFreeSize(rbh) == xRingbufferGetMaxItemSize(rbh); }

/* Reset the buffer to an empty state */
void clear()
{
// we try to get to a state where we are not getting any more memory back
// this requires at least 2 calls to xRingbufferReceiveUpTo
void* item_p;

do
{
size_t freed_bytes;

item_p = xRingbufferReceiveUpTo(rbh, &freed_bytes, 0, size());
if (item_p != NULL)
{
vRingbufferReturnItem(rbh, item_p);
}
}
while (item_p != NULL);
}
/* return the used size of the buffer in bytes */
size_t size() { return xRingbufferGetMaxItemSize(rbh) - xRingbufferGetCurFreeSize(rbh); }

/* return the maximum size of the buffer in bytes*/
size_t maxSize() { return xRingbufferGetMaxItemSize(rbh); }

/* return the free size of the buffer in bytes*/
size_t freeSize() { return xRingbufferGetMaxItemSize(rbh); }
};
6 changes: 2 additions & 4 deletions PlatformIO/src/General.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#include <WiFi.h>
#include <AsyncMqttClient.h>
#include <PubSubClient.h>
#include "RingBuf.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
#include <ArduinoJson.h>
#include "index_html.h"
#include "Esp32RingBuffer.h"

const int PLAY = BIT0;
const int STREAM = BIT1;
Expand Down Expand Up @@ -70,7 +70,7 @@ std::string restartTopic = config.siteid + std::string("/restart");
AsyncMqttClient asyncClient;
WiFiClient net;
PubSubClient audioServer(net);
RingBuf<uint8_t, 60000> audioData;
Esp32RingBuffer<uint8_t, uint16_t, (1U << 15)> audioData;
long message_size = 0;
int queueDelay = 10;
int sampleRate = 16000;
Expand Down Expand Up @@ -146,8 +146,6 @@ XT_Wav_Class::XT_Wav_Class(const unsigned char *WavData) {
}
}

uint8_t WaveData[44];

// this function supplies template variables to the template engine
String processor(const String& var){
if(var == "MQTT_HOST"){
Expand Down
9 changes: 8 additions & 1 deletion PlatformIO/src/Satellite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@
#define INMP441 3
#define INMP441MAX98357A 4

#ifdef PI_DEVICE_TYPE
#undef DEVICE_TYPE
#define DEVICE_TYPE PI_DEVICE_TYPE
#endif


// This is where you can include your device, make sure to create a *device
// The *device is used to call methods
Expand All @@ -122,13 +127,15 @@
#elif DEVICE_TYPE == INMP441MAX98357A
#include "devices/Inmp441Max98357a.hpp"
Inmp441Max98357a *device = new Inmp441Max98357a();
#else
#error DEVICE_TYPE is out of range
#endif

#include <General.hpp>
#include <StateMachine.hpp>

void setup() {
Serial.begin(115200);
Serial.begin(921000);
Serial.println("Booting");

if (wbSemaphore == NULL) // Not yet been created?
Expand Down
Loading

0 comments on commit 7459f7d

Please sign in to comment.