mirror of
https://github.com/esphome/esphome.git
synced 2025-11-03 00:21:56 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1821ddd996 | ||
|
|
aee702f84f | ||
|
|
d5fe5b0899 | ||
|
|
bd7fe1227c | ||
|
|
7dced7f55d | ||
|
|
36de644065 | ||
|
|
95292dbba1 | ||
|
|
86c9546362 | ||
|
|
f37a812e59 |
@@ -145,7 +145,7 @@ async def display_page_show_to_code(config, action_id, template_arg, args):
|
||||
DisplayPageShowNextAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(Display)),
|
||||
}
|
||||
),
|
||||
)
|
||||
@@ -159,7 +159,7 @@ async def display_page_show_next_to_code(config, action_id, template_arg, args):
|
||||
DisplayPageShowPrevAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(Display)),
|
||||
}
|
||||
),
|
||||
)
|
||||
@@ -173,7 +173,7 @@ async def display_page_show_previous_to_code(config, action_id, template_arg, ar
|
||||
DisplayIsDisplayingPageCondition,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.use_id(DisplayBuffer),
|
||||
cv.GenerateID(CONF_ID): cv.use_id(Display),
|
||||
cv.Required(CONF_PAGE_ID): cv.use_id(DisplayPage),
|
||||
},
|
||||
key=CONF_PAGE_ID,
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace esp32_rmt_led_strip {
|
||||
|
||||
static const char *const TAG = "esp32_rmt_led_strip";
|
||||
|
||||
static const uint32_t RMT_CLK_FREQ = 80000000;
|
||||
|
||||
static const uint8_t RMT_CLK_DIV = 2;
|
||||
|
||||
void ESP32RMTLEDStripLightOutput::setup() {
|
||||
@@ -65,7 +67,7 @@ void ESP32RMTLEDStripLightOutput::setup() {
|
||||
|
||||
void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high,
|
||||
uint32_t bit1_low) {
|
||||
float ratio = (float) APB_CLK_FREQ / RMT_CLK_DIV / 1e09f;
|
||||
float ratio = (float) RMT_CLK_FREQ / RMT_CLK_DIV / 1e09f;
|
||||
|
||||
// 0-bit
|
||||
this->bit0_.duration0 = (uint32_t) (ratio * bit0_high);
|
||||
|
||||
@@ -55,6 +55,9 @@ void Inkplate6::setup() {
|
||||
this->wakeup_pin_->digital_write(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate buffers. May be called after setup to re-initialise if e.g. greyscale is changed.
|
||||
*/
|
||||
void Inkplate6::initialize_() {
|
||||
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||
ExternalRAMAllocator<uint32_t> allocator32(ExternalRAMAllocator<uint32_t>::ALLOW_FAILURE);
|
||||
|
||||
@@ -68,8 +68,9 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
||||
|
||||
void set_greyscale(bool greyscale) {
|
||||
this->greyscale_ = greyscale;
|
||||
this->initialize_();
|
||||
this->block_partial_ = true;
|
||||
if (this->is_ready())
|
||||
this->initialize_();
|
||||
}
|
||||
void set_partial_updating(bool partial_updating) { this->partial_updating_ = partial_updating; }
|
||||
void set_full_update_every(uint32_t full_update_every) { this->full_update_every_ = full_update_every; }
|
||||
|
||||
@@ -17,7 +17,7 @@ static const char *const TAG = "voice_assistant";
|
||||
|
||||
static const size_t SAMPLE_RATE_HZ = 16000;
|
||||
static const size_t INPUT_BUFFER_SIZE = 32 * SAMPLE_RATE_HZ / 1000; // 32ms * 16kHz / 1000ms
|
||||
static const size_t BUFFER_SIZE = 1000 * SAMPLE_RATE_HZ / 1000; // 1s
|
||||
static const size_t BUFFER_SIZE = 1024 * SAMPLE_RATE_HZ / 1000;
|
||||
static const size_t SEND_BUFFER_SIZE = INPUT_BUFFER_SIZE * sizeof(int16_t);
|
||||
static const size_t RECEIVE_SIZE = 1024;
|
||||
static const size_t SPEAKER_BUFFER_SIZE = 16 * RECEIVE_SIZE;
|
||||
@@ -86,14 +86,14 @@ void VoiceAssistant::setup() {
|
||||
|
||||
#ifdef USE_ESP_ADF
|
||||
this->vad_instance_ = vad_create(VAD_MODE_4);
|
||||
#endif
|
||||
|
||||
this->ring_buffer_ = rb_create(BUFFER_SIZE, sizeof(int16_t));
|
||||
this->ring_buffer_ = RingBuffer::create(BUFFER_SIZE * sizeof(int16_t));
|
||||
if (this->ring_buffer_ == nullptr) {
|
||||
ESP_LOGW(TAG, "Could not allocate ring buffer");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ExternalRAMAllocator<uint8_t> send_allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||
this->send_buffer_ = send_allocator.allocate(SEND_BUFFER_SIZE);
|
||||
@@ -112,14 +112,8 @@ int VoiceAssistant::read_microphone_() {
|
||||
memset(this->input_buffer_, 0, INPUT_BUFFER_SIZE * sizeof(int16_t));
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_ESP_ADF
|
||||
// Write audio into ring buffer
|
||||
int available = rb_bytes_available(this->ring_buffer_);
|
||||
if (available < bytes_read) {
|
||||
rb_read(this->ring_buffer_, nullptr, bytes_read - available, 0);
|
||||
}
|
||||
rb_write(this->ring_buffer_, (char *) this->input_buffer_, bytes_read, 0);
|
||||
#endif
|
||||
this->ring_buffer_->write((void *) this->input_buffer_, bytes_read);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "microphone not running");
|
||||
}
|
||||
@@ -141,9 +135,9 @@ void VoiceAssistant::loop() {
|
||||
switch (this->state_) {
|
||||
case State::IDLE: {
|
||||
if (this->continuous_ && this->desired_state_ == State::IDLE) {
|
||||
this->ring_buffer_->reset();
|
||||
#ifdef USE_ESP_ADF
|
||||
if (this->use_wake_word_) {
|
||||
rb_reset(this->ring_buffer_);
|
||||
this->set_state_(State::START_MICROPHONE, State::WAIT_FOR_VAD);
|
||||
} else
|
||||
#endif
|
||||
@@ -236,19 +230,15 @@ void VoiceAssistant::loop() {
|
||||
break; // State changed when udp server port received
|
||||
}
|
||||
case State::STREAMING_MICROPHONE: {
|
||||
size_t bytes_read = this->read_microphone_();
|
||||
#ifdef USE_ESP_ADF
|
||||
if (rb_bytes_filled(this->ring_buffer_) >= SEND_BUFFER_SIZE) {
|
||||
rb_read(this->ring_buffer_, (char *) this->send_buffer_, SEND_BUFFER_SIZE, 0);
|
||||
this->socket_->sendto(this->send_buffer_, SEND_BUFFER_SIZE, 0, (struct sockaddr *) &this->dest_addr_,
|
||||
this->read_microphone_();
|
||||
size_t available = this->ring_buffer_->available();
|
||||
while (available >= SEND_BUFFER_SIZE) {
|
||||
size_t read_bytes = this->ring_buffer_->read((void *) this->send_buffer_, SEND_BUFFER_SIZE, 0);
|
||||
this->socket_->sendto(this->send_buffer_, read_bytes, 0, (struct sockaddr *) &this->dest_addr_,
|
||||
sizeof(this->dest_addr_));
|
||||
available = this->ring_buffer_->available();
|
||||
}
|
||||
#else
|
||||
if (bytes_read > 0) {
|
||||
this->socket_->sendto(this->input_buffer_, bytes_read, 0, (struct sockaddr *) &this->dest_addr_,
|
||||
sizeof(this->dest_addr_));
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
case State::STOP_MICROPHONE: {
|
||||
@@ -473,9 +463,9 @@ void VoiceAssistant::request_start(bool continuous, bool silence_detection) {
|
||||
if (this->state_ == State::IDLE) {
|
||||
this->continuous_ = continuous;
|
||||
this->silence_detection_ = silence_detection;
|
||||
this->ring_buffer_->reset();
|
||||
#ifdef USE_ESP_ADF
|
||||
if (this->use_wake_word_) {
|
||||
rb_reset(this->ring_buffer_);
|
||||
this->set_state_(State::START_MICROPHONE, State::WAIT_FOR_VAD);
|
||||
} else
|
||||
#endif
|
||||
@@ -618,9 +608,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||
case api::enums::VOICE_ASSISTANT_RUN_END: {
|
||||
ESP_LOGD(TAG, "Assist Pipeline ended");
|
||||
if (this->state_ == State::STREAMING_MICROPHONE) {
|
||||
this->ring_buffer_->reset();
|
||||
#ifdef USE_ESP_ADF
|
||||
if (this->use_wake_word_) {
|
||||
rb_reset(this->ring_buffer_);
|
||||
// No need to stop the microphone since we didn't use the speaker
|
||||
this->set_state_(State::WAIT_FOR_VAD, State::WAITING_FOR_VAD);
|
||||
} else
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/ring_buffer.h"
|
||||
|
||||
#include "esphome/components/api/api_connection.h"
|
||||
#include "esphome/components/api/api_pb2.h"
|
||||
@@ -21,7 +22,6 @@
|
||||
|
||||
#ifdef USE_ESP_ADF
|
||||
#include <esp_vad.h>
|
||||
#include <ringbuf.h>
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
@@ -177,10 +177,10 @@ class VoiceAssistant : public Component {
|
||||
|
||||
#ifdef USE_ESP_ADF
|
||||
vad_handle_t vad_instance_;
|
||||
ringbuf_handle_t ring_buffer_;
|
||||
uint8_t vad_threshold_{5};
|
||||
uint8_t vad_counter_{0};
|
||||
#endif
|
||||
std::unique_ptr<RingBuffer> ring_buffer_;
|
||||
|
||||
bool use_wake_word_;
|
||||
uint8_t noise_suppression_level_;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Constants used by esphome."""
|
||||
|
||||
__version__ = "2023.12.6"
|
||||
__version__ = "2023.12.8"
|
||||
|
||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||
|
||||
50
esphome/core/ring_buffer.cpp
Normal file
50
esphome/core/ring_buffer.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "ring_buffer.h"
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
|
||||
static const char *const TAG = "ring_buffer";
|
||||
|
||||
std::unique_ptr<RingBuffer> RingBuffer::create(size_t len) {
|
||||
std::unique_ptr<RingBuffer> rb = make_unique<RingBuffer>();
|
||||
|
||||
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||
rb->storage_ = allocator.allocate(len + 1);
|
||||
if (rb->storage_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rb->handle_ = xStreamBufferCreateStatic(len + 1, 0, rb->storage_, &rb->structure_);
|
||||
ESP_LOGD(TAG, "Created ring buffer with size %u", len);
|
||||
return rb;
|
||||
}
|
||||
|
||||
size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
|
||||
return xStreamBufferReceive(this->handle_, data, len, ticks_to_wait);
|
||||
}
|
||||
|
||||
size_t RingBuffer::write(void *data, size_t len) {
|
||||
size_t free = this->free();
|
||||
if (free < len) {
|
||||
size_t needed = len - free;
|
||||
uint8_t discard[needed];
|
||||
xStreamBufferReceive(this->handle_, discard, needed, 0);
|
||||
}
|
||||
return xStreamBufferSend(this->handle_, data, len, 0);
|
||||
}
|
||||
|
||||
size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); }
|
||||
|
||||
size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); }
|
||||
|
||||
BaseType_t RingBuffer::reset() { return xStreamBufferReset(this->handle_); }
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
||||
34
esphome/core/ring_buffer.h
Normal file
34
esphome/core/ring_buffer.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/stream_buffer.h>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
class RingBuffer {
|
||||
public:
|
||||
size_t read(void *data, size_t len, TickType_t ticks_to_wait = 0);
|
||||
|
||||
size_t write(void *data, size_t len);
|
||||
|
||||
size_t available() const;
|
||||
size_t free() const;
|
||||
|
||||
BaseType_t reset();
|
||||
|
||||
static std::unique_ptr<RingBuffer> create(size_t len);
|
||||
|
||||
protected:
|
||||
StreamBufferHandle_t handle_;
|
||||
StaticStreamBuffer_t structure_;
|
||||
uint8_t *storage_;
|
||||
};
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user