Divided into strategies

This commit is contained in:
Sviatoslav Tsariov Yurievich 2024-06-11 19:41:52 +03:00
parent 05af001d8c
commit 804aa7f4f6
17 changed files with 480 additions and 176 deletions

View File

@ -0,0 +1,125 @@
#include "domain/AidStrategy.h"
#include "utils/Time.h"
#include "config/config.h"
void AidStrategy::setup() {
_task1_mutex = xSemaphoreCreateMutex();
_task2_mutex = xSemaphoreCreateMutex();
_http_mutex = xSemaphoreCreateMutex();
}
void AidStrategy::process() {
xTaskCreatePinnedToCore(processTask, "ProcessTask1", 4096, this, 1, NULL, 0);
//xTaskCreatePinnedToCore(processTask, "ProcessTask2", 4096, this, 1, NULL, 1);
}
void AidStrategy::processTask(void* parameters) {
AidStrategy* aidStrategy = static_cast<AidStrategy*>(parameters);
Audio* audioSource =
(xTaskGetAffinity(NULL) == 0) ? aidStrategy->_audio : aidStrategy->_audio1;
aidStrategy->_writeToPrecedingBuffer(audioSource);
if (aidStrategy->_isNoiseDetected(audioSource)) {
aidStrategy->_recordAudio(audioSource);
}
vTaskDelete(NULL);
}
void AidStrategy::_writeToPrecedingBuffer(Audio* audioSource) {
if (!_isWritingToPrecedingBuffer && !_recordingAudio) {
_isWritingToPrecedingBuffer = true;
audioSource->writeToPrecedingBuffer();
_isWritingToPrecedingBuffer = false;
}
}
bool AidStrategy::_isNoiseDetected(Audio* audioSource) {
return audioSource->isNoiseDetected();
}
void AidStrategy::_recordAudio(Audio* audioSource) {
if (_recordingAudio)
return;
Serial.println("!!!");
bool isReady = false;
_recordingAudio = true;
if (xSemaphoreTake(_http_mutex, portMAX_DELAY)) {
isReady = _ready();
xSemaphoreGive(_http_mutex);
}
if (isReady) {
Serial.println("========================================");
Serial.println("| RECORDING...");
audioSource->record();
Serial.println("| Recording finished");
}
if (xSemaphoreTake(_http_mutex, portMAX_DELAY)) {
if (_http->connect(RAT_IP, RAT_PORT)) {
_sendAudio(audioSource);
_http->stop();
} else {
Serial.println("| Connection failed");
}
xSemaphoreGive(_http_mutex);
}
_recordingAudio = false;
}
String AidStrategy::_ready() {
return _http->send("POST", "/aid/ready", RAT_IP, RAT_PORT, "", "");
}
void AidStrategy::_sendAudio(Audio* audioSource) {
String payloadStart = _formPayloadStart(_audio->getStartMicros());
String payloadEnd = _formPayloadEnd();
int audioLength = _audio->getSize();
int jsonLength = payloadStart.length() + audioLength + payloadEnd.length();
_http->printHeader("POST", "/aid/save", RAT_IP, "application/json");
_http->printContentLength(jsonLength);
this->_printContent(payloadStart, payloadEnd, _http->getClient());
}
void AidStrategy::_printContent(String payloadStart, String payloadEnd, Stream* stream) {
stream->print(payloadStart);
_audio->print(stream);
stream->print(payloadEnd);
_logContent(payloadStart, payloadEnd);
}
void AidStrategy::_logContent(String payloadStart, String payloadEnd) {
Serial.print("| ");
Serial.print(payloadStart);
Serial.print("...");
Serial.print(payloadEnd);
}
String AidStrategy::_formPayloadStart(unsigned long startMicros) {
String payloadStart = "";
payloadStart += "{\"audio\":{\"micros\":";
payloadStart += String(_audio->getStartMicros() - _timeModule.getInitialMicros());
payloadStart += ",\"initialTime\":";
payloadStart += String(_timeModule.getInitialTime());
payloadStart += ",\"content\":\"";
return payloadStart;
}
String AidStrategy::_formPayloadEnd() {
return "\"}}\r\n\r\n";
}

104
src/domain/AidStrategy.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "domain/AidStrategy.h"
#include "utils/Time.h"
#include "config/config.h"
void AidStrategy::setup() {}
void AidStrategy::process() {
_writeToPrecedingBuffer(_audio);
if (_isNoiseDetected(_audio)) {
_recordAudio(_audio);
}
}
void AidStrategy::_writeToPrecedingBuffer(Audio* audioSource) {
if (!_isWritingToPrecedingBuffer && !_recordingAudio) {
_isWritingToPrecedingBuffer = true;
audioSource->writeToPrecedingBuffer();
_isWritingToPrecedingBuffer = false;
}
}
bool AidStrategy::_isNoiseDetected(Audio* audioSource) {
return audioSource->isNoiseDetected();
}
void AidStrategy::_recordAudio(Audio* audioSource) {
if (_recordingAudio)
return;
Serial.println("!!!");
bool isReady = false;
_recordingAudio = true;
isReady = _ready();
if (!isReady)
return;
if (_http->connect(RAT_IP, RAT_PORT)) {
Serial.println("========================================");
Serial.println("| RECORDING...");
audioSource->record();
Serial.println("| Recording finished");
_sendAudio(audioSource);
_http->stop();
} else {
Serial.println("| Connection failed");
}
_recordingAudio = false;
}
String AidStrategy::_ready() {
return _http->send("POST", "/aid/ready", RAT_IP, RAT_PORT, "", "");
}
void AidStrategy::_sendAudio(Audio* audioSource) {
String payloadStart = _formPayloadStart(_audio->getStartMicros());
String payloadEnd = _formPayloadEnd();
int audioLength = _audio->getSize();
int jsonLength = payloadStart.length() + audioLength + payloadEnd.length();
_http->printHeader("POST", "/aid/save", RAT_IP, "application/json");
_http->printContentLength(jsonLength);
this->_printContent(payloadStart, payloadEnd, _http->getClient());
}
void AidStrategy::_printContent(String payloadStart, String payloadEnd, Stream* stream) {
stream->print(payloadStart);
_audio->print(stream);
stream->print(payloadEnd);
_logContent(payloadStart, payloadEnd);
}
void AidStrategy::_logContent(String payloadStart, String payloadEnd) {
Serial.print("| ");
Serial.print(payloadStart);
Serial.print("...");
Serial.print(payloadEnd);
}
String AidStrategy::_formPayloadStart(unsigned long startMicros) {
String payloadStart = "";
payloadStart += "{\"audio\":{\"micros\":";
payloadStart += String(_audio->getStartMicros() - _timeModule.getInitialMicros());
payloadStart += ",\"initialTime\":";
payloadStart += String(_timeModule.getInitialTime());
payloadStart += ",\"content\":\"";
return payloadStart;
}
String AidStrategy::_formPayloadEnd() {
return "\"}}\r\n\r\n";
}

37
src/domain/AidStrategy.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include "domain/BaseStrategy.h"
#include "utils/Time.h"
class AidStrategy : public BaseStrategy {
private:
Time& _timeModule = Time::getInstance();
SemaphoreHandle_t _task1_mutex;
SemaphoreHandle_t _task2_mutex;
SemaphoreHandle_t _http_mutex;
bool _isWritingToPrecedingBuffer = false;
bool _recordingAudio = false;
void _recordAudio(Audio* audioSource);
void _writeToPrecedingBuffer(Audio* audioSource);
bool _isNoiseDetected(Audio* audioSource);
String _ready();
void _sendAudio(Audio* audioSource);
void _printContent(String payloadStart, String payloadEnd, Stream* stream);
void _logContent(String payloadStart, String payloadEnd);
String _formPayloadStart(unsigned long startMicros);
String _formPayloadEnd();
static void processTask(void* parameters);
public:
AidStrategy(MicType micType, Http* http) : BaseStrategy(micType, http) {}
~AidStrategy() {}
void setup();
void process();
};

37
src/domain/BaseStrategy.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include "infra/Audio.h"
#include "infra/Http.h"
class BaseStrategy {
protected:
Audio* _audio;
Audio* _audio1;
Http* _http;
public:
BaseStrategy(MicType micType, Http* http) {
Serial.print("Free heap: ");
Serial.println(esp_get_minimum_free_heap_size());
_audio = new Audio(micType, I2S_NUM_0);
Serial.print("Free heap: ");
Serial.println(esp_get_minimum_free_heap_size());
_audio1 = new Audio(micType, I2S_NUM_1);
Serial.print("Free heap: ");
Serial.println(esp_get_minimum_free_heap_size());
_http = http;
}
~BaseStrategy() {
delete _audio;
delete _audio1;
}
virtual void setup() = 0;
virtual void process() = 0;
};

30
src/domain/Controller.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "domain/Controller.h"
Controller Controller::_instance;
Controller::Controller() : _strategy(nullptr) {}
void Controller::setStrategy(BaseStrategy* newStrategy) {
if (_strategy) {
delete _strategy;
}
_strategy = newStrategy;
if (_strategy) {
_strategy->setup();
}
}
Controller::~Controller() {
if (_strategy) {
delete _strategy;
}
}
Controller& Controller::getInstance() {
return _instance;
}
void Controller::process() {
_strategy->process();
}

17
src/domain/Controller.h Normal file
View File

@ -0,0 +1,17 @@
#include "domain/BaseStrategy.h"
class Controller {
private:
static Controller _instance;
BaseStrategy* _strategy;
Controller();
Controller(Controller const&) = delete;
void operator=(Controller const&) = delete;
~Controller();
public:
static Controller& getInstance();
void setStrategy(BaseStrategy* strategy);
void process();
};

View File

@ -1,93 +0,0 @@
#include "domain/Recorder.h"
#include "config/config.h"
#include "utils/Time.h"
Time& timeModule = Time::getInstance();
Recorder::Recorder(MicType micType, Http* http) {
_audio = new Audio(micType);
_http = http;
}
Recorder::~Recorder() {
delete _audio;
}
void Recorder::recordAudio() {
_recordingAudio = true;
_ready();
if (_http->connect(RAT_IP, RAT_PORT)) {
Serial.println("========================================");
Serial.println("| RECORDING...");
_audio->record();
Serial.println("| Recording finished");
_transcribe();
} else {
Serial.println("| Connection failed");
}
_recordingAudio = false;
}
void Recorder::_ready() {
_http->send("POST", "/ready", RAT_IP, RAT_PORT, "", "");
}
void Recorder::_transcribe() {
String payloadStart = _formPayloadStart();
String payloadEnd = _formPayloadEnd();
int audioLength = _audio->getSize();
int jsonLength = payloadStart.length() + audioLength + payloadEnd.length();
_http->printHeader("POST", "/save_to_file", RAT_IP, "application/json");
_http->printContentLength(jsonLength);
this->_printContent(payloadStart, payloadEnd, _http->getClient());
}
void Recorder::_printContent(String payloadStart, String payloadEnd, Stream* stream) {
stream->print(payloadStart);
_audio->print(stream);
stream->print(payloadEnd);
_logContent(payloadStart, payloadEnd);
}
void Recorder::_logContent(String payloadStart, String payloadEnd) {
Serial.print("| ");
Serial.print(payloadStart);
Serial.print("...");
Serial.print(payloadEnd);
}
String Recorder::_formPayloadStart() {
String payloadStart = "";
payloadStart += "{\"audio\":{\"micros\":";
payloadStart += String(_audio->getStartMicros() - timeModule.getInitialMicros());
payloadStart += ",\"initialTime\":";
payloadStart += String(timeModule.getInitialTime());
payloadStart += ",\"content\":\"";
return payloadStart;
}
String Recorder::_formPayloadEnd() {
return "\"}}\r\n\r\n";
}
void Recorder::writeToPrecedingBuffer() {
if (!_isWritingToPrecedingBuffer && !_recordingAudio) {
_isWritingToPrecedingBuffer = true;
_audio->writeToPrecedingBuffer();
_isWritingToPrecedingBuffer = false;
}
}
bool Recorder::isNoiseDetected() {
return _audio->isNoiseDetected();
}

View File

@ -1,29 +0,0 @@
#pragma once
#include "infra/Audio.h"
#include "infra/Http.h"
class Recorder {
private:
Audio* _audio;
Http* _http;
bool _isWritingToPrecedingBuffer = false;
bool _recordingAudio = false;
void _ready();
void _transcribe();
void _printContent(String payloadStart, String payloadEnd, Stream* stream);
void _logContent(String payloadStart, String payloadEnd);
void _printAudio();
String _formPayloadStart();
String _formPayloadEnd();
public:
Recorder(MicType micType, Http* http);
~Recorder();
void recordAudio();
void writeToPrecedingBuffer();
bool isNoiseDetected();
};

View File

@ -0,0 +1,13 @@
#include "domain/RecorderStrategy.h"
#include "config/config.h"
void RecorderStrategy::setup() {}
void RecorderStrategy::process() {
}
void RecorderStrategy::_check() {
_http->send("POST", "/recorder/check", RAT_IP, RAT_PORT, "", "");
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "domain/BaseStrategy.h"
#include "utils/Time.h"
class RecorderStrategy : public BaseStrategy {
private:
Time& _timeModule = Time::getInstance();
void _check();
public:
void setup();
void process();
};

View File

@ -5,14 +5,14 @@
#define PRECEDING_BUFFER_SIZE 4 #define PRECEDING_BUFFER_SIZE 4
Audio::Audio(MicType micType) { Audio::Audio(MicType micType, i2s_port_t i2sNum) {
_wavData = new char*[_wavDataSize/_dividedWavDataSize]; _wavData = new char*[_wavDataSize/_dividedWavDataSize];
for (int i = 0; i < _wavDataSize/_dividedWavDataSize; ++i) for (int i = 0; i < _wavDataSize/_dividedWavDataSize; ++i)
_wavData[i] = new char[_dividedWavDataSize]; _wavData[i] = new char[_dividedWavDataSize];
_precedingWavBuffer = new CircularBuffer<char*>(_precedingWavPartsAmount); _precedingWavBuffer = new CircularBuffer<char*>(_precedingWavPartsAmount);
i2s = new I2S(micType); i2s = new I2S(micType, i2sNum);
} }
Audio::~Audio() { Audio::~Audio() {
@ -47,7 +47,7 @@ void Audio::_createWavHeader(byte* header, int waveDataSize){
header[19] = 0x00; header[19] = 0x00;
header[20] = 0x01; // linear PCM header[20] = 0x01; // linear PCM
header[21] = 0x00; header[21] = 0x00;
header[22] = 0x01; // monoral header[22] = 0x02; // stereo
header[23] = 0x00; header[23] = 0x00;
header[24] = 0x80; // sampling rate 16000 header[24] = 0x80; // sampling rate 16000
header[25] = 0x3E; header[25] = 0x3E;
@ -141,9 +141,8 @@ void Audio::writeToPrecedingBuffer() {
} }
void Audio::_convertBufferToWav(char* partialWavBuffer) { void Audio::_convertBufferToWav(char* partialWavBuffer) {
for (int i = 0; i < _i2sBufferSize/8; ++i) { for (int i = 0; i < _i2sBufferSize/2; ++i) {
partialWavBuffer[2*i] = _i2sBuffer[4*i + 2]; partialWavBuffer[i] = _i2sBuffer[i];
partialWavBuffer[2*i + 1] = _i2sBuffer[4*i + 3];
} }
} }
@ -152,12 +151,30 @@ int Audio::getSize() {
} }
String Audio::print(Stream* stream) { String Audio::print(Stream* stream) {
return printHeader(stream) + printContent(stream);
}
String Audio::printHeader(Stream* stream) {
String enc = base64::encode(_paddedHeader, sizeof(_paddedHeader)); String enc = base64::encode(_paddedHeader, sizeof(_paddedHeader));
enc.replace("\n", ""); enc.replace("\n", "");
stream->print(enc); stream->print(enc);
return enc;
}
String Audio::printContent(Stream* stream) {
String enc;
Serial.print("Free heap: ");
Serial.println(esp_get_minimum_free_heap_size());
for (int j = 0; j < _wavDataSize / _dividedWavDataSize; ++j) { for (int j = 0; j < _wavDataSize / _dividedWavDataSize; ++j) {
enc = base64::encode((byte*)_wavData[j], _dividedWavDataSize); enc = base64::encode((byte*)_wavData[j], _dividedWavDataSize/2);
enc.replace("\n", "");
stream->print(enc);
enc = base64::encode((byte*)_wavData[j] + _dividedWavDataSize/2,
_dividedWavDataSize/2);
enc.replace("\n", ""); enc.replace("\n", "");
stream->print(enc); stream->print(enc);
} }

View File

@ -10,17 +10,18 @@
class Audio { class Audio {
private: private:
I2S* i2s; I2S* i2s;
static const int _headerSize = 44;
static const int _i2sBufferSize = 6000;
char _i2sBuffer[_i2sBufferSize];
char _i2sBuffer2[_i2sBufferSize];
static const int _wavDataSize = 90000; // It must be multiple of _dividedWavDataSize. Recording time is about 1.9 second. static const int _headerSize = 44;
static const int _dividedWavDataSize = _i2sBufferSize/4; static const int _i2sBufferSize = 6048/2;
char _i2sBuffer[_i2sBufferSize/2];
static const int _wavDataSize = 90720/2; // It must be multiple of _dividedWavDataSize. Recording time is about 1.9 second.
static const int _dividedWavDataSize = _i2sBufferSize/2;
char** _wavData; // It's divided. Because large continuous memory area can't be allocated in esp32. char** _wavData; // It's divided. Because large continuous memory area can't be allocated in esp32.
static const int _precedingWavPartsAmount = 12; static const int _precedingWavPartsAmount = (_wavDataSize/_dividedWavDataSize)/5;
static const int _precedingWavDataSize = _precedingWavPartsAmount*_dividedWavDataSize; static const int _precedingWavDataSize =
_precedingWavPartsAmount*_dividedWavDataSize;
char** _precedingWavData; char** _precedingWavData;
CircularBuffer<char*>* _precedingWavBuffer; CircularBuffer<char*>* _precedingWavBuffer;
bool _precedingBufferFull = false; bool _precedingBufferFull = false;
@ -37,11 +38,13 @@ private:
bool _isNoiseDetectedInPrecedingBuffer(); bool _isNoiseDetectedInPrecedingBuffer();
public: public:
Audio(MicType micType); Audio(MicType micType, i2s_port_t i2sNum=I2S_NUM_0);
~Audio(); ~Audio();
char** record(); char** record();
int getSize(); int getSize();
String print(Stream* stream); String print(Stream* stream);
String printHeader(Stream* stream);
String printContent(Stream* stream);
unsigned long getStartMicros(); unsigned long getStartMicros();
void emptyPrecedingBuffer(); void emptyPrecedingBuffer();
void writeToPrecedingBuffer(); void writeToPrecedingBuffer();

View File

@ -62,6 +62,8 @@ void Http::printContentLength(int contentLength) {
_client->print("Content-Length: "); _client->print("Content-Length: ");
_client->println(contentLength); _client->println(contentLength);
_client->println(); _client->println();
_logContentLength(contentLength);
} }
String Http::readResponse() { String Http::readResponse() {
@ -133,3 +135,8 @@ void Http::_logPayload(String payload) {
Serial.println(payload); Serial.println(payload);
} }
} }
void Http::_logContentLength(int contentLength) {
Serial.print("| Content-Length: ");
Serial.println(contentLength);
}

View File

@ -11,6 +11,7 @@ private:
void _logHeader(String method, String endpoint, String host, String contentType); void _logHeader(String method, String endpoint, String host, String contentType);
void _logPayload(String payload); void _logPayload(String payload);
void _logConnected(String host, int port); void _logConnected(String host, int port);
void _logContentLength(int contentLength);
public: public:
Http(Eth* eth); Http(Eth* eth);

View File

@ -2,11 +2,20 @@
#include "config/config.h" #include "config/config.h"
#define SAMPLE_RATE (16000) #define SAMPLE_RATE (16000)
#define PIN_I2S_BCLK (GPIO_NUM_26)
#define PIN_I2S_LRC (GPIO_NUM_25) // Define pins for I2S_NUM_0
#define PIN_I2S_DIN (GPIO_NUM_3) #define PIN_I2S_0_BCLK (GPIO_NUM_26)
#define PIN_I2S_DOUT (GPIO_NUM_22) #define PIN_I2S_0_LRC (GPIO_NUM_25)
#define PIN_I2S_MCK (GPIO_NUM_0) #define PIN_I2S_0_DIN (GPIO_NUM_3)
#define PIN_I2S_0_DOUT (GPIO_NUM_22)
#define PIN_I2S_0_MCK (GPIO_NUM_0)
// Define pins for I2S_NUM_1
#define PIN_I2S_1_BCLK (GPIO_NUM_32)
#define PIN_I2S_1_LRC (GPIO_NUM_33)
#define PIN_I2S_1_DIN (GPIO_NUM_35)
#define PIN_I2S_1_DOUT (GPIO_NUM_0)
#define PIN_I2S_1_MCK (GPIO_NUM_0)
SemaphoreHandle_t dmaInterruptSemaphore; SemaphoreHandle_t dmaInterruptSemaphore;
static intr_handle_t dmaInterruptRetHandle; static intr_handle_t dmaInterruptRetHandle;
@ -18,7 +27,7 @@ static intr_handle_t dmaInterruptRetHandle;
// - Data bits are MSB first. // - Data bits are MSB first.
// - DATA bits are left-aligned with respect to LRC edge. // - DATA bits are left-aligned with respect to LRC edge.
// - DATA bits are right-shifted by one with respect to LRC edges. // - DATA bits are right-shifted by one with respect to LRC edges.
I2S::I2S(MicType micType) { I2S::I2S(MicType micType, i2s_port_t i2sNum) : _i2sNum(i2sNum) {
if (micType == M5GO || micType == M5STACKFIRE ) { if (micType == M5GO || micType == M5STACKFIRE ) {
BITS_PER_SAMPLE = I2S_BITS_PER_SAMPLE_16BIT; BITS_PER_SAMPLE = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config_t i2s_config = { i2s_config_t i2s_config = {
@ -31,10 +40,10 @@ I2S::I2S(MicType micType) {
.dma_buf_count = 2, .dma_buf_count = 2,
.dma_buf_len = 1024 .dma_buf_len = 1024
}; };
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_driver_install(_i2sNum, &i2s_config, 0, NULL);
i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_6); i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_6);
i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO); i2s_set_clk(_i2sNum, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
i2s_adc_enable(I2S_NUM_0); i2s_adc_enable(_i2sNum);
} }
else if (micType == ADMP441 || micType == ICS43434 ) { else if (micType == ADMP441 || micType == ICS43434 ) {
BITS_PER_SAMPLE = I2S_BITS_PER_SAMPLE_16BIT;// I2S_BITS_PER_SAMPLE_32BIT; BITS_PER_SAMPLE = I2S_BITS_PER_SAMPLE_16BIT;// I2S_BITS_PER_SAMPLE_32BIT;
@ -49,27 +58,39 @@ I2S::I2S(MicType micType) {
.dma_buf_len = 60, .dma_buf_len = 60,
}; };
i2s_pin_config_t pin_config; i2s_driver_install(_i2sNum, &i2s_config, 0, NULL);
_setPins();
pin_config.bck_io_num = PIN_I2S_BCLK; i2s_set_clk(_i2sNum, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
pin_config.ws_io_num = PIN_I2S_LRC; i2s_zero_dma_buffer(_i2sNum);
pin_config.data_out_num = I2S_PIN_NO_CHANGE;
pin_config.data_in_num = PIN_I2S_DIN;
pin_config.mck_io_num = PIN_I2S_MCK;
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
i2s_zero_dma_buffer(I2S_NUM_0);
} }
dmaInterruptSemaphore = xSemaphoreCreateBinary(); dmaInterruptSemaphore = xSemaphoreCreateBinary();
} }
void I2S::_setPins() {
i2s_pin_config_t pin_config;
if (_i2sNum == I2S_NUM_0) {
pin_config.bck_io_num = PIN_I2S_0_BCLK;
pin_config.ws_io_num = PIN_I2S_0_LRC;
pin_config.data_out_num = I2S_PIN_NO_CHANGE;
pin_config.data_in_num = PIN_I2S_0_DIN;
pin_config.mck_io_num = PIN_I2S_0_MCK;
} else if (_i2sNum == I2S_NUM_1) {
pin_config.bck_io_num = PIN_I2S_1_BCLK;
pin_config.ws_io_num = PIN_I2S_1_LRC;
pin_config.data_out_num = I2S_PIN_NO_CHANGE;
pin_config.data_in_num = PIN_I2S_1_DIN;
pin_config.mck_io_num = PIN_I2S_1_MCK;
}
i2s_set_pin(_i2sNum, &pin_config);
}
int I2S::Read(char* data, int numData) { int I2S::Read(char* data, int numData) {
size_t bytes_read; size_t bytes_read;
if (i2s_read(I2S_NUM_0, (char *)data, numData, &bytes_read, portMAX_DELAY)) { if (i2s_read(_i2sNum, (char *)data, numData, &bytes_read, portMAX_DELAY)) {
return (int)bytes_read; return (int)bytes_read;
} }

View File

@ -14,11 +14,15 @@ enum MicType {
}; };
class I2S { class I2S {
i2s_bits_per_sample_t BITS_PER_SAMPLE;
public: public:
I2S(MicType micType); I2S(MicType micType, i2s_port_t i2sNum=I2S_NUM_0);
int Read(char* data, int numData); int Read(char* data, int numData);
int GetBitPerSample(); int GetBitPerSample();
private:
i2s_port_t _i2sNum;
i2s_bits_per_sample_t BITS_PER_SAMPLE;
void _setPins();
}; };
#endif // _I2S_H #endif // _I2S_H

View File

@ -10,7 +10,8 @@
#include "infra/Http.h" #include "infra/Http.h"
#include "infra/Eth.h" #include "infra/Eth.h"
#include "domain/Recorder.h" #include "domain/Controller.h"
#include "domain/AidStrategy.h"
volatile bool loudnessFlag = false; volatile bool loudnessFlag = false;
@ -20,7 +21,7 @@ Eth eth;
EthernetClient* client = eth.getEthClient(); EthernetClient* client = eth.getEthClient();
Http http(&eth); Http http(&eth);
Recorder* recorder; Controller& controller = Controller::getInstance();
Time timeService = Time::getInstance(); Time timeService = Time::getInstance();
@ -39,11 +40,6 @@ void setInitialTime() {
void writeToPrecedingBufferTask(void* parameter) { void writeToPrecedingBufferTask(void* parameter) {
while (true) { while (true) {
recorder->writeToPrecedingBuffer();
if (recorder->isNoiseDetected()) {
recorder->recordAudio();
}
vTaskDelay(500 / portTICK_PERIOD_MS); vTaskDelay(500 / portTICK_PERIOD_MS);
} }
@ -52,7 +48,8 @@ void writeToPrecedingBufferTask(void* parameter) {
void createWriteToPrecedingBufferTask() { void createWriteToPrecedingBufferTask() {
TaskHandle_t xHandle = NULL; TaskHandle_t xHandle = NULL;
xTaskCreatePinnedToCore(writeToPrecedingBufferTask, "writeToPrecedingBufferTask", 4096, NULL, 1, &xHandle, 0); xTaskCreatePinnedToCore(writeToPrecedingBufferTask,
"writeToPrecedingBufferTask", 4096, NULL, 1, &xHandle, 0);
if (xHandle == NULL) { if (xHandle == NULL) {
ESP_LOGE("TASK1", "Failed to task create"); ESP_LOGE("TASK1", "Failed to task create");
@ -66,7 +63,8 @@ void setup() {
eth.initEthernet(); eth.initEthernet();
setInitialTime(); setInitialTime();
recorder = new Recorder(ADMP441, &http); Serial.println(1);
controller.setStrategy(new AidStrategy(ADMP441, &http));
//createWriteToPrecedingBufferTask(); //createWriteToPrecedingBufferTask();
@ -76,9 +74,5 @@ void setup() {
void loop() { void loop() {
eth.readAndPrintData(true); // set to false for better speed measurement eth.readAndPrintData(true); // set to false for better speed measurement
recorder->writeToPrecedingBuffer(); controller.process();
if (recorder->isNoiseDetected()) {
recorder->recordAudio();
}
} }