#include <Arduino.h>
#include "AudioOut.h"
#include "driver/i2s.h"
void AudioOut::addSingleData(int16_t singleData) {
this->receiveAudioBuffer[this->bufferPointer++] = singleData;
if (this->bufferPointer == this->receivePackageSize) {
std::swap(this->receiveAudioBuffer, this->playAudioBuffer);
this->bufferPointer = 0;
//通知播放
xTaskNotify(this->playHandle, 1, eIncrement);
}
}
void AudioOut::processData(uint8_t *bufferData) {
int16_t *rawDatas = (int16_t *)bufferData;
for (int i = 0; i < this->receivePackageSize; i++) {
if (this->db == 0) {
addSingleData(rawDatas[i] );
} else {
addSingleData(rawDatas[i] * 1.259 * this->db);
}
}
}
void AudioOut::startProcessData(uint8_t *bufferData) {
this->processData(bufferData);
}
void playTask(void *param) {
AudioOut *audioOut = (AudioOut *)param;
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(100);
while (true) {
uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, xMaxBlockTime);
if (ulNotificationValue > 0) {
//开始播放
audioOut->doPlay();
}
}
}
void AudioOut::start(i2s_config_t i2SConfig, i2s_pin_config_t i2SPinConfig,
int32_t receivePackageSize, int db) {
this->i2SConfig = i2SConfig;
this->i2SPinConfig = i2SPinConfig;
this->db = db;
this->receivePackageSize = receivePackageSize / sizeof(int16_t);
//分配buffer大小
this->receiveAudioBuffer = (int16_t *)malloc(receivePackageSize);
this->playAudioBuffer = (int16_t *)malloc(receivePackageSize);
//安装i2s驱动
i2s_driver_install(this->i2sPort, &i2SConfig, 0, NULL);
//设置i2spin
i2s_set_pin(this->i2sPort, &i2SPinConfig);
//在0核心中读取数据
xTaskCreatePinnedToCore(playTask, "playTask", 102400, this, 1,
&playHandle, 0);
}
void AudioOut::doPlay() {
size_t bytesWritten = 0;
i2s_write(this->i2sPort, this->playAudioBuffer, this->receivePackageSize * sizeof(int16_t),
&bytesWritten, 10);
}
#ifndef WIFIAUDIORX_AUDIOOUT_H
#define WIFIAUDIORX_AUDIOOUT_H
#include "driver/i2s.h"
class AudioOut {
private:
// i2s序列
i2s_port_t i2sPort = I2S_NUM_0;
// i2s配置
i2s_config_t i2SConfig;
// i2s pin设置
i2s_pin_config_t i2SPinConfig;
//播放句柄
TaskHandle_t playHandle;
//两个缓冲buffer
int16_t *receiveAudioBuffer;
//发送缓存
int16_t *playAudioBuffer;
//接收缓冲区大小
int32_t receivePackageSize;
int bytesRead = 0;
int32_t bufferPointer = 0;
int db;
void processData(uint8_t *bufferData);
void addSingleData(int16_t singleData);
void doPlay();
public:
void start(i2s_config_t i2SConfig, i2s_pin_config_t i2SPinConfig,
int32_t receivePackageSize, int db);
void startProcessData(uint8_t *bufferData);
friend void playTask(void *param);
};
#endif // WIFIAUDIORX_AUDIOOUT_H
#include "AudioOut.h"
#include <WiFi.h>
const char *ssid = "BLabAudio";
const char *password = "dengyi1991";
IPAddress localIp(192, 168, 101, 2);
IPAddress gateWay(192, 168, 101, 1);
IPAddress subNet(255, 255, 255, 0);
//----------定义常量------------
#define OPEN_DEBUG true
#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 600 //睡眠时间10分钟
#define MUTE_OUT_PIN 32
#define TOUCH_THRESHOLD 40 //触摸灵敏度阈值,越大越灵敏
#define STATUS_PIN 12
#define MUTE_STATUS_PIN 14
#define ADC_PIN 34
// i2s配置
i2s_config_t i2sConfig = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format =
i2s_comm_format_t(I2S_COMM_FORMAT_I2S),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 512,
.use_apll = true,
.tx_desc_auto_clear = true,
.fixed_mclk = I2S_PIN_NO_CHANGE
};
// i2s pin配置
i2s_pin_config_t i2SPinConfig = { .bck_io_num = GPIO_NUM_27,
.ws_io_num = GPIO_NUM_26,
.data_out_num = GPIO_NUM_25,
.data_in_num = I2S_PIN_NO_CHANGE
};
AudioOut *audioOut = NULL;
int connectedClientNum = 0;
WiFiServer server(8888);
void wifiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_AP_START:
Serial.println("ESP32 soft AP started");
break;
case SYSTEM_EVENT_AP_STACONNECTED:
connectedClientNum++;
Serial.println("Station connected to ESP32 soft AP");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
connectedClientNum--;
Serial.println("Station disconnected from ESP32 soft AP");
break;
default:
break;
}
}
void setup() {
// esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
// //读取电压,电池电压低于3.7v就直接睡眠,ADC值大概算了一下在2300未精确测量,睡10分钟然后醒来检测一次
// if (analogRead(ADC_PIN) <= 2300) {
// esp_deep_sleep_start();
// }
//是否开启debug
if (OPEN_DEBUG) {
Serial.begin(115200);
}
//状态led初始化
pinMode(MUTE_OUT_PIN, OUTPUT);
pinMode(STATUS_PIN, OUTPUT);
pinMode(MUTE_STATUS_PIN, OUTPUT);
digitalWrite(MUTE_OUT_PIN, HIGH);
digitalWrite(STATUS_PIN, LOW);
digitalWrite(MUTE_STATUS_PIN, LOW);
//设置WiFi事件
WiFi.onEvent(wifiEvent);
WiFi.mode(WIFI_MODE_AP);
WiFi.softAP(ssid, password);
//延迟等待ap设置成功
delay(200);
WiFi.softAPConfig(localIp, gateWay, subNet);
IPAddress IP = WiFi.softAPIP();
server.begin();
//初始化输出
audioOut = new AudioOut();
//1db大概是1.259倍,放大2个db
audioOut->start(i2sConfig, i2SPinConfig, 1024, 1);
//延迟等待ap设置成功
delay(500);
digitalWrite(STATUS_PIN, HIGH);
}
void loop() {
WiFiClient client = server.available();
if (client) {
while (client.connected()) {
while (client.available() > 0) {
uint8_t readData[1024];
client.read(readData, 1024);
audioOut->startProcessData(readData);
}
}
}
}
#include <Arduino.h>
#include "driver/i2s.h"
#include "AudioSampler.h"
void AudioSampler::processData(int16_t *i2sData, size_t bytesRead) {
for (int i = 0; i < bytesRead / 2; i++) {
addSingleData(i2sData[i]);
}
}
void AudioSampler::addSingleData(int16_t singleData) {
this->currentAudioBuffer[this->bufferPointer++] = singleData;
if (this->bufferPointer == this->transmitPackageSize) {
//过滤器处理
//如果采样缓冲池满了就交换
std::swap(this->currentAudioBuffer, this->transmitAudioBuffer);
this->bufferPointer = 0;
xTaskNotify(this->transmitHandle, 1, eIncrement);
}
}
void i2sSamplerTask(void *param) {
AudioSampler *audioSampler = (AudioSampler *)param;
while (true) {
// 等待队列中有数据再处理
i2s_event_t event;
if (xQueueReceive(audioSampler->i2sQueue, &event, portMAX_DELAY) == pdPASS) {
if (event.type == I2S_EVENT_RX_DONE) {
size_t bytesRead = 0;
do {
// 从i2s中读取数据
int16_t readData[1024];
i2s_read(audioSampler->i2sPort, readData, 1024, &bytesRead, 10);
// 处理原始数据
audioSampler->processData(readData, bytesRead);
} while (bytesRead > 0);
}
}
}
}
void AudioSampler::start(i2s_config_t i2SConfig, i2s_pin_config_t i2SPinConfig,
int32_t transmitPackageSize, TaskHandle_t transmitHandle) {
this->i2SConfig = i2SConfig;
this->i2SPinConfig = i2SPinConfig;
this->transmitPackageSize = transmitPackageSize / sizeof(int16_t);
//保存通知句柄
this->transmitHandle = transmitHandle;
//分配buffer大小
this->currentAudioBuffer = (int16_t *)malloc(transmitPackageSize);
this->transmitAudioBuffer = (int16_t *)malloc(transmitPackageSize);
//安装i2s驱动
i2s_driver_install(this->i2sPort, &i2SConfig, 4, &i2sQueue);
//设置i2spin
i2s_set_pin(this->i2sPort, &i2SPinConfig);
//在0核心中读取数据
xTaskCreatePinnedToCore(i2sSamplerTask, "AudioSampler", 10240, this, 1, NULL,
0);
}
#ifndef WIFIAUDIOTX_AUDIOSAMPLER_H
#define WIFIAUDIOTX_AUDIOSAMPLER_H
#include "driver/i2s.h"
#include <WiFi.h>
class AudioSampler {
private:
// i2s序列
i2s_port_t i2sPort = I2S_NUM_1;
// i2s配置
i2s_config_t i2SConfig;
// i2s pin设置
i2s_pin_config_t i2SPinConfig;
//发送句柄
TaskHandle_t transmitHandle;
//两个缓冲buffer8个,2的3次方
int16_t *currentAudioBuffer;
//发送缓存
int16_t *transmitAudioBuffer;
// i2s队列
QueueHandle_t i2sQueue;
//数据指针
int32_t bufferPointer = 0;
//缓冲数据大小
int32_t bufferArraySize;
//发送数据包大小
int32_t transmitPackageSize;
/**
处理数据方法,用于对剩余进行增益控制
@param i2sData 原始数据
@param bytesRead 读取到的数据数
*/
void processData(int16_t *i2sData, size_t bytesRead);
//添加单个数据到缓冲中
void addSingleData(int16_t singleData);
public:
void start(i2s_config_t i2SConfig, i2s_pin_config_t i2SPinConfig,
int32_t transmitPackageSize, TaskHandle_t transmitHandle);
int16_t *getTransmitBuffer() {
return transmitAudioBuffer;
};
int32_t getTransmitPackageSize() {
return transmitPackageSize * sizeof(int16_t);
};
friend void i2sSamplerTask(void *param);
};
#endif
#include <Arduino.h>
#include <WiFi.h>
#include "AudioSampler.h"
//--------定义常量---------
#define OPEN_DEBUG true //正式运行的时候请设置为false
#define SSID "BLabAudio"
#define PASSWORD "dengyi1991"
#define SERVER_IP "192.168.101.2"
#define SERVER_PORT 8888
#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 600 //睡眠时间10分钟,到时会醒来检查一次,还是没电会继续睡
#define MUTEPIN 12
#define TOUCH_THRESHOLD 40 //触摸灵敏度阈值,越大越灵敏
#define STATUSPIN 14
#define ADCPIN 34
//-------定义变量----------
volatile bool wifiConnected = false;
volatile bool mute = false;
volatile int statusLedState = LOW;
volatile unsigned long sinceLastTouch = 0;
volatile bool inited = false;
// i2s配置
i2s_config_t i2sConfig = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format =
i2s_comm_format_t(I2S_COMM_FORMAT_I2S),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
// i2s pin配置
i2s_pin_config_t i2SPinConfig = { .bck_io_num = GPIO_NUM_5,
.ws_io_num = GPIO_NUM_19,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = GPIO_NUM_18
};
AudioSampler *audioSampler = NULL;
/**
静音中断函数
*/
void muteTouch() {
if (millis() - sinceLastTouch < 1000) return;
sinceLastTouch = millis();
mute = !mute;
if (mute) {
digitalWrite(MUTEPIN, HIGH);
} else {
digitalWrite(MUTEPIN, LOW);
}
}
/**
发送缓冲数组到服务器方法
@param param
*/
void transmitTask(void *param) {
AudioSampler *audioSampler = (AudioSampler *)param;
//socket连接服务器
WiFiClient *wifiClient = new WiFiClient();
// while (!wifiClient->connect("192.168.43.121", 8888)) {
while (!wifiClient->connect(SERVER_IP, SERVER_PORT)) {
delay(100);
}
wifiClient->setNoDelay(true);
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(100);
unsigned long startTime;
unsigned long endTime;
while (true) {
// 等待队列通知
uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, xMaxBlockTime);
if (ulNotificationValue > 0) {
//wifi连接上同时未静音才发送数据
if (wifiConnected && !mute) {
// Serial.print("start-->");
// startTime = millis();
// Serial.print(startTime);
// Serial.print("---->");
int sendNum = wifiClient->write((uint8_t *)audioSampler->getTransmitBuffer(), audioSampler->getTransmitPackageSize());
// Serial.print("end-->");
// endTime = millis();
// Serial.print(endTime);
// Serial.print("---->");
// Serial.print("total--->");
// Serial.println(endTime - startTime);
} else {
//未连接时情况tcp缓存
wifiClient->flush();
}
}
}
}
void wifiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_STA_CONNECTED:
wifiConnected = true;
//led亮起
digitalWrite(STATUSPIN, HIGH);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
//回调会多次执行,所以要判断一下
if (inited) {
wifiConnected = false;
digitalWrite(STATUSPIN, LOW);
ESP.restart();
}
break;
default: break;
}
}
void setup() {
//状态led初始化
pinMode(MUTEPIN, OUTPUT);
pinMode(STATUSPIN, OUTPUT);
digitalWrite(STATUSPIN, LOW);
digitalWrite(MUTEPIN, LOW);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
//读取电压,电池电压低于3.7v就直接睡眠,ADC值大概算了一下在2300未精确测量,睡10分钟然后醒来检测一次
if (analogRead(ADCPIN) <= 2300) {
esp_deep_sleep_start();
}
//是否开启debug
if (OPEN_DEBUG) {
Serial.begin(115200);
}
//初始化并连接WiFi
WiFi.mode(WIFI_STA);
WiFi.onEvent(wifiEvent);
WiFi.begin(SSID, PASSWORD);
//循环等待连接上WiFi
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
delay(500);
if (statusLedState == LOW) {
statusLedState = HIGH;
} else {
statusLedState = LOW;
}
digitalWrite(STATUSPIN, statusLedState);
Serial.println(statusLedState);
}
//创建取样器对象
audioSampler = new AudioSampler();
//创建发送句柄
TaskHandle_t transmitHandle;
xTaskCreate(transmitTask, "transmitTask", 10240, audioSampler, 1,
&transmitHandle);
//启动采样
audioSampler->start(i2sConfig, i2SPinConfig, 2048, transmitHandle);
//触摸T0对应的是gpio4
touchAttachInterrupt(T0, muteTouch, TOUCH_THRESHOLD);
//初始化完将初始化状态置为true
inited = true;
}
void loop() {}
疫情下的wifi医疗传呼系统代码
于 2023-04-25 22:39:12 首次发布