#include <Arduino.h>
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"
#include "configuration.h"
#include "I2SMEMSSampler.h"
#include "AsyncUDP.h"
const char * ssid = "MERCURY_213";
const char * password = "213213213";
IPAddress serverip = IPAddress(192,168,1,108); //服务端的静态IP地址
uint16_t toport_sound = 8085; //服务端的开放端口
const int SAMPLE_SIZE = 700;//越大延迟越高,但效果越好
AsyncUDP SoundUDP;
I2SSampler *i2sSampler = NULL;
void InitUDP(IPAddress ip, uint16_t toport_sound){
if(SoundUDP.connect(ip, toport_sound)) {
Serial.println("UDP connected");
SoundUDP.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("S2 Got %u bytes of data", packet.length());
});
//Send unicast
//SoundUDP.print("This is S2 Server");
}
}
// i2s config for reading from left channel of I2S
i2s_config_t i2sMemsConfigLeftChannel = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_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 pins
i2s_pin_config_t i2sPins = {
.bck_io_num = GPIO_NUM_15,
.ws_io_num = GPIO_NUM_16,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = GPIO_NUM_21};
// 发送音频数据
void sendSoundData(uint8_t *bytes, size_t count, AsyncUDP* UDPClient = &SoundUDP, uint16_t the_port = toport_sound)
{
// send them off to the server
digitalWrite(2, HIGH);
/*
httpClient->begin(*wifiClient, url);
httpClient->addHeader("content-type", "application/octet-stream");
httpClient->POST(bytes, count);
httpClient->end();
*/
//这是向局域网内所有用户广播,若只发给连接的用户,要用UDPClient.write()
UDPClient->broadcastTo(bytes, count,the_port);
digitalWrite(2, LOW);
}
// Task to write samples to our server
void i2sMemsWriterTask(void *param)
{
I2SSampler *sampler = (I2SSampler *)param;
int16_t *samples = (int16_t *)malloc(sizeof(uint16_t) * SAMPLE_SIZE);
if (!samples)
{
Serial.println("Failed to allocate memory for samples");
return;
}
while (true)
{
int samples_read = sampler->read(samples, SAMPLE_SIZE);
//sendSoundData((uint8_t *)samples, samples_read * sizeof(uint16_t));
SoundUDP.write((uint8_t *)samples, samples_read * sizeof(uint16_t));
//SoundUDP.broadcastTo((uint8_t *)samples, samples_read * sizeof(uint16_t),toport_sound);
}
}
void setup()
{
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
//Serial.setDebugOutput(false);
// launch WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
// indicator LED
pinMode(2, OUTPUT);
InitUDP(serverip,toport_sound);
// Direct i2s input from INMP441 or the SPH0645
i2sSampler = new I2SMEMSSampler(I2S_NUM_1, i2sPins, i2sMemsConfigLeftChannel, false);
i2sSampler->start();
// set up the i2s sample writer task
TaskHandle_t i2sMemsWriterTaskHandle;
xTaskCreatePinnedToCore(i2sMemsWriterTask, "I2S Writer Task", 4096, i2sSampler, 1, &i2sMemsWriterTaskHandle, 1);
// // start sampling from i2s device
}
void loop()
{
// nothing to do here - everything is taken care of by tasks
}