Bell catchup

This commit is contained in:
philippe44
2023-07-26 13:19:20 -07:00
parent 859efdb954
commit 232afb948b
467 changed files with 77538 additions and 37137 deletions

View File

@@ -1,8 +1,10 @@
#include "AACDecoder.h"
#include <stdlib.h> // for free, malloc
#include "CodecType.h" // for bell
#include <string.h>
#include <assert.h>
#include "e_tmp4audioobjecttype.h"
#include "pvmp4audiodecoder_api.h"
namespace bell {
class AudioContainer;
@@ -11,47 +13,100 @@ class AudioContainer;
using namespace bell;
AACDecoder::AACDecoder() {
aac = AACInitDecoder();
pcmData = (int16_t*)malloc(AAC_MAX_NSAMPS * AAC_MAX_NCHANS * sizeof(int16_t));
aacDecoder =
(tPVMP4AudioDecoderExternal*)malloc(sizeof(tPVMP4AudioDecoderExternal));
int32_t pMemRequirement = PVMP4AudioDecoderGetMemRequirements();
pMem = malloc(pMemRequirement);
memset(aacDecoder, 0, sizeof(tPVMP4AudioDecoderExternal));
memset(pMem, 0, pMemRequirement);
// Initialize the decoder buffers
outputBuffer.resize(4096);
aacDecoder->pOutputBuffer_plus = &outputBuffer[2048];
aacDecoder->pOutputBuffer = &outputBuffer[0];
aacDecoder->inputBufferMaxLength = PVMP4AUDIODECODER_INBUFSIZE;
// Settings
aacDecoder->desiredChannels = 2;
aacDecoder->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
aacDecoder->aacPlusEnabled = TRUE;
// State
aacDecoder->inputBufferCurrentLength = 0;
aacDecoder->inputBufferUsedLength = 0;
aacDecoder->remainderBits = 0;
firstFrame = true;
assert(PVMP4AudioDecoderInitLibrary(aacDecoder, pMem) == MP4AUDEC_SUCCESS);
}
AACDecoder::~AACDecoder() {
AACFreeDecoder(aac);
free(pcmData);
free(pMem);
free(aacDecoder);
}
int AACDecoder::getDecodedStreamType() {
switch (aacDecoder->extendedAudioObjectType) {
case MP4AUDIO_AAC_LC:
case MP4AUDIO_LTP:
return AAC;
case MP4AUDIO_SBR:
return AACPLUS;
case MP4AUDIO_PS:
return ENH_AACPLUS;
default:
return -1;
}
}
bool AACDecoder::setup(uint32_t sampleRate, uint8_t channelCount,
uint8_t bitDepth) {
PVMP4AudioDecoderResetBuffer(pMem);
assert(PVMP4AudioDecoderInitLibrary(aacDecoder, pMem) == MP4AUDEC_SUCCESS);
firstFrame = true;
return true;
}
bool AACDecoder::setup(AudioContainer* container) {
PVMP4AudioDecoderResetBuffer(pMem);
assert(PVMP4AudioDecoderInitLibrary(aacDecoder, pMem) == MP4AUDEC_SUCCESS);
firstFrame = true;
return true;
}
uint8_t* AACDecoder::decode(uint8_t* inData, uint32_t& inLen,
uint32_t& outLen) {
if (!inData)
if (!inData || inLen == 0)
return nullptr;
int status = AACDecode(aac, static_cast<unsigned char**>(&inData),
reinterpret_cast<int*>(&inLen),
static_cast<short*>(this->pcmData));
aacDecoder->inputBufferCurrentLength = inLen;
aacDecoder->inputBufferUsedLength = 0;
aacDecoder->inputBufferMaxLength = inLen;
aacDecoder->pInputBuffer = inData;
aacDecoder->remainderBits = 0;
aacDecoder->repositionFlag = true;
AACGetLastFrameInfo(aac, &frame);
if (status != ERR_AAC_NONE) {
lastErrno = status;
int32_t status;
status = PVMP4AudioDecodeFrame(aacDecoder, pMem);
if (status != MP4AUDEC_SUCCESS) {
outLen = 0;
inLen = 0;
return nullptr;
} else {
inLen -= aacDecoder->inputBufferUsedLength;
}
if (sampleRate != frame.sampRateOut) {
this->sampleRate = frame.sampRateOut;
outLen = aacDecoder->frameLength * sizeof(int16_t);
// Handle AAC+
if (aacDecoder->aacPlusUpsamplingFactor == 2) {
outLen *= 2;
}
if (channelCount != frame.nChans) {
this->channelCount = frame.nChans;
}
outLen = frame.outputSamps * sizeof(int16_t);
return (uint8_t*)pcmData;
outLen *= aacDecoder->desiredChannels;
return (uint8_t*)&outputBuffer[0];
}

View File

@@ -1,7 +1,6 @@
#include "BaseCodec.h"
#include "AudioContainer.h" // for AudioContainer
#include "CodecType.h" // for bell
using namespace bell;
@@ -23,10 +22,7 @@ uint8_t* BaseCodec::decode(AudioContainer* container, uint32_t& outLen) {
availableBytes = lastSampleLen;
auto* result = decode((uint8_t*)data, availableBytes, outLen);
if (result == nullptr) {
container->consumeBytes(1);
} else {
container->consumeBytes(lastSampleLen - availableBytes);
}
container->consumeBytes(lastSampleLen - availableBytes);
return result;
}

View File

@@ -1,8 +1,7 @@
#include "MP3Decoder.h"
#include <stdlib.h> // for free, malloc
#include "CodecType.h" // for bell
#include <cstdio>
namespace bell {
class AudioContainer;
@@ -41,6 +40,8 @@ uint8_t* MP3Decoder::decode(uint8_t* inData, uint32_t& inLen,
MP3GetLastFrameInfo(mp3, &frame);
if (status != ERR_MP3_NONE) {
lastErrno = status;
inLen -= 2;
outLen = 0;
return nullptr;
}
if (sampleRate != frame.samprate) {

View File

@@ -1,18 +1,23 @@
#pragma once
#include <stdint.h> // for uint8_t, uint32_t, int16_t
#include <vector>
#include "BaseCodec.h" // for BaseCodec
#include "aacdec.h" // for AACFrameInfo, HAACDecoder
#include "BaseCodec.h" // for BaseCodec
#include "pvmp4audiodecoder_api.h" // for tPVMP4AudioDecoderExternal
namespace bell {
class AudioContainer;
class AACDecoder : public BaseCodec {
private:
HAACDecoder aac;
int16_t* pcmData;
AACFrameInfo frame = {};
tPVMP4AudioDecoderExternal* aacDecoder;
std::vector<uint8_t> inputBuffer;
std::vector<int16_t> outputBuffer;
void* pMem;
bool firstFrame = true;
int getDecodedStreamType();
public:
AACDecoder();

View File

@@ -7,7 +7,7 @@
#include <stdio.h> // for NULL
#include "aacdec.h" // for AACFreeDecoder, AACInitDecoder, HAACDecoder
// #include "aacdec.h" // for AACFreeDecoder, AACInitDecoder, HAACDecoder
#include "mp3dec.h" // for MP3FreeDecoder, MP3InitDecoder, HMP3Decoder
namespace bell {
@@ -16,16 +16,16 @@ class DecodersInstance {
DecodersInstance(){};
~DecodersInstance() {
MP3FreeDecoder(mp3Decoder);
AACFreeDecoder(aacDecoder);
// AACFreeDecoder(aacDecoder);
};
HAACDecoder aacDecoder = NULL;
// HAACDecoder aacDecoder = NULL;
HMP3Decoder mp3Decoder = NULL;
void ensureAAC() {
if (aacDecoder == NULL) {
aacDecoder = AACInitDecoder();
}
// if (aacDecoder == NULL) {
// aacDecoder = AACInitDecoder();
// }
}
void ensureMP3() {

View File

@@ -1,55 +0,0 @@
#include "AACContainer.h"
#include <cstring> // for memmove
#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16, SampleRate, Sampl...
#include "aacdec.h" // for AACFindSyncWord
using namespace bell;
#define SYNC_WORLD_LEN 4
AACContainer::AACContainer(std::istream& istr) : bell::AudioContainer(istr) {}
bool AACContainer::fillBuffer() {
if (this->bytesInBuffer < AAC_MAX_FRAME_SIZE * 2) {
this->istr.read((char*)buffer.data() + bytesInBuffer,
buffer.size() - bytesInBuffer);
this->bytesInBuffer += istr.gcount();
}
return this->bytesInBuffer >= AAC_MAX_FRAME_SIZE * 2;
}
std::byte* AACContainer::readSample(uint32_t& len) {
if (!this->fillBuffer()) {
len = 0;
return nullptr;
}
// Align the data if previous read was offseted
if (toConsume > 0 && toConsume <= bytesInBuffer) {
memmove(buffer.data(), buffer.data() + toConsume,
buffer.size() - toConsume);
bytesInBuffer = bytesInBuffer - toConsume;
toConsume = 0;
}
int startOffset =
AACFindSyncWord((uint8_t*)this->buffer.data(), bytesInBuffer);
if (startOffset < 0) {
// Discard word
toConsume = AAC_MAX_FRAME_SIZE;
return nullptr;
}
len = bytesInBuffer - startOffset;
return this->buffer.data() + startOffset;
}
void AACContainer::parseSetupData() {
channels = 2;
sampleRate = bell::SampleRate::SR_44100;
bitWidth = bell::BitWidth::BW_16;
}

View File

@@ -0,0 +1,129 @@
#include "ADTSContainer.h"
#include <cstring> // for memmove
#include <iostream>
#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16, SampleRate, Sampl...
// #include "aacdec.h" // for AACFindSyncWord
using namespace bell;
#define SYNC_WORLD_LEN 4
#define SYNCWORDH 0xff
#define SYNCWORDL 0xf0
// AAC ADTS frame header len
#define AAC_ADTS_FRAME_HEADER_LEN 9
// AAC ADTS frame sync verify
#define AAC_ADTS_SYNC_VERIFY(buf) \
((buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0))
// AAC ADTS Frame size value stores in 13 bits started at the 31th bit from header
#define AAC_ADTS_FRAME_GETSIZE(buf) \
((buf[3] & 0x03) << 11 | buf[4] << 3 | buf[5] >> 5)
ADTSContainer::ADTSContainer(std::istream& istr, const std::byte* headingBytes)
: bell::AudioContainer(istr) {
if (headingBytes != nullptr) {
memcpy(buffer.data(), headingBytes, 7);
bytesInBuffer = 7;
}
}
bool ADTSContainer::fillBuffer() {
if (this->bytesInBuffer < AAC_MAX_FRAME_SIZE * 2) {
this->istr.read((char*)buffer.data() + bytesInBuffer,
buffer.size() - bytesInBuffer);
this->bytesInBuffer += istr.gcount();
}
return this->bytesInBuffer >= AAC_MAX_FRAME_SIZE;
}
bool ADTSContainer::resyncADTS() {
int resyncOffset = 0;
bool resyncValid = false;
size_t validBytes = bytesInBuffer - dataOffset;
while (!resyncValid && resyncOffset < validBytes) {
uint8_t* buf = (uint8_t*)this->buffer.data() + dataOffset + resyncOffset;
if (AAC_ADTS_SYNC_VERIFY(buf)) {
// Read frame size, and check if a consecutive frame is available
uint32_t frameSize = AAC_ADTS_FRAME_GETSIZE(buf);
if (frameSize + resyncOffset > validBytes) {
// Not enough data, discard this frame
resyncOffset++;
continue;
}
buf =
(uint8_t*)this->buffer.data() + dataOffset + resyncOffset + frameSize;
if (AAC_ADTS_SYNC_VERIFY(buf)) {
buf += AAC_ADTS_FRAME_GETSIZE(buf);
if (AAC_ADTS_SYNC_VERIFY(buf)) {
protectionAbsent = (buf[1] & 1);
// Found 3 consecutive frames, resynced
resyncValid = true;
}
}
} else {
resyncOffset++;
}
}
dataOffset += resyncOffset;
return resyncValid;
}
void ADTSContainer::consumeBytes(uint32_t len) {
dataOffset += len;
}
std::byte* ADTSContainer::readSample(uint32_t& len) {
// Align data if previous read was offseted
if (dataOffset > 0 && bytesInBuffer > 0) {
size_t toConsume = std::min(dataOffset, bytesInBuffer);
memmove(buffer.data(), buffer.data() + toConsume,
buffer.size() - toConsume);
dataOffset -= toConsume;
bytesInBuffer -= toConsume;
}
if (!this->fillBuffer()) {
len = 0;
return nullptr;
}
uint8_t* buf = (uint8_t*)buffer.data() + dataOffset;
if (!AAC_ADTS_SYNC_VERIFY(buf)) {
if (!resyncADTS()) {
len = 0;
return nullptr;
}
} else {
protectionAbsent = (buf[1] & 1);
}
len = AAC_ADTS_FRAME_GETSIZE(buf);
if (len > bytesInBuffer - dataOffset) {
if (!resyncADTS()) {
len = 0;
return nullptr;
}
}
return buffer.data() + dataOffset;
}
void ADTSContainer::parseSetupData() {
channels = 2;
sampleRate = bell::SampleRate::SR_44100;
bitWidth = bell::BitWidth::BW_16;
}

View File

@@ -1,11 +1,12 @@
#include "AudioContainers.h"
#include <string.h> // for memcmp
#include <cstddef> // for byte
#include <string.h> // for memcmp
#include <cstddef> // for byte
#include "BellLogger.h" // for BellLogger
#include "AACContainer.h" // for AACContainer
#include "CodecType.h" // for bell
#include "MP3Container.h" // for MP3Container
#include "ADTSContainer.h" // for AACContainer
#include "CodecType.h" // for bell
#include "MP3Container.h" // for MP3Container
namespace bell {
class AudioContainer;
@@ -20,15 +21,19 @@ std::unique_ptr<bell::AudioContainer> AudioContainers::guessAudioContainer(
if (memcmp(tmp, "\xFF\xF1", 2) == 0 || memcmp(tmp, "\xFF\xF9", 2) == 0) {
// AAC found
std::cout << "AAC" << std::endl;
return std::make_unique<bell::AACContainer>(istr);
BELL_LOG(info, "AudioContainers",
"Mime guesser found AAC in ADTS format, creating ADTSContainer");
return std::make_unique<bell::ADTSContainer>(istr, tmp);
} else if (memcmp(tmp, "\xFF\xFB", 2) == 0 ||
memcmp(tmp, "\x49\x44\x33", 3) == 0) {
// MP3 Found
std::cout << "MP3" << std::endl;
BELL_LOG(info, "AudioContainers",
"Mime guesser found MP3 format, creating MP3Container");
return std::make_unique<bell::MP3Container>(istr);
return std::make_unique<bell::MP3Container>(istr, tmp);
}
BELL_LOG(error, "AudioContainers",
"Mime guesser found no supported format [%X, %X]", tmp[0], tmp[1]);
return nullptr;
}

View File

@@ -7,7 +7,12 @@
using namespace bell;
MP3Container::MP3Container(std::istream& istr) : bell::AudioContainer(istr) {}
MP3Container::MP3Container(std::istream& istr, const std::byte* headingBytes) : bell::AudioContainer(istr) {
if (headingBytes != nullptr) {
memcpy(buffer.data(), headingBytes, 7);
bytesInBuffer = 7;
}
}
bool MP3Container::fillBuffer() {
if (this->bytesInBuffer < MP3_MAX_FRAME_SIZE * 2) {
@@ -18,32 +23,41 @@ bool MP3Container::fillBuffer() {
return this->bytesInBuffer >= MP3_MAX_FRAME_SIZE * 2;
}
void MP3Container::consumeBytes(uint32_t len) {
dataOffset += len;
}
std::byte* MP3Container::readSample(uint32_t& len) {
// Align data if previous read was offseted
if (dataOffset > 0 && bytesInBuffer > 0) {
size_t toConsume = std::min(dataOffset, bytesInBuffer);
memmove(buffer.data(), buffer.data() + toConsume,
buffer.size() - toConsume);
dataOffset -= toConsume;
bytesInBuffer -= toConsume;
}
if (!this->fillBuffer()) {
len = 0;
return nullptr;
}
// Align the data if previous read was offseted
if (toConsume > 0 && toConsume <= bytesInBuffer) {
memmove(buffer.data(), buffer.data() + toConsume,
buffer.size() - toConsume);
bytesInBuffer = bytesInBuffer - toConsume;
toConsume = 0;
}
int startOffset =
MP3FindSyncWord((uint8_t*)this->buffer.data(), bytesInBuffer);
if (startOffset < 0) {
// Discard word
toConsume = MP3_MAX_FRAME_SIZE;
dataOffset = MP3_MAX_FRAME_SIZE;
return nullptr;
}
len = bytesInBuffer - startOffset;
dataOffset += startOffset;
return this->buffer.data() + startOffset;
len = bytesInBuffer - dataOffset;
return this->buffer.data() + dataOffset;
}
void MP3Container::parseSetupData() {

View File

@@ -9,13 +9,15 @@
#include "CodecType.h" // for AudioCodec, AudioCodec::AAC
namespace bell {
class AACContainer : public AudioContainer {
class ADTSContainer : public AudioContainer {
public:
~AACContainer(){};
AACContainer(std::istream& istr);
~ADTSContainer(){};
ADTSContainer(std::istream& istr, const std::byte* headingBytes = nullptr);
std::byte* readSample(uint32_t& len) override;
bool resyncADTS();
void parseSetupData() override;
void consumeBytes(uint32_t len) override;
bell::AudioCodec getCodec() override { return bell::AudioCodec::AAC; }
@@ -27,6 +29,7 @@ class AACContainer : public AudioContainer {
size_t bytesInBuffer = 0;
size_t dataOffset = 0;
bool protectionAbsent = false;
bool fillBuffer();
};

View File

@@ -10,7 +10,6 @@ namespace bell {
class AudioContainer {
protected:
std::istream& istr;
uint32_t toConsume = 0;
public:
bell::SampleRate sampleRate;
@@ -20,7 +19,7 @@ class AudioContainer {
AudioContainer(std::istream& istr) : istr(istr) {}
virtual std::byte* readSample(uint32_t& len) = 0;
void consumeBytes(uint32_t bytes) { this->toConsume = bytes; }
virtual void consumeBytes(uint32_t len) = 0;
virtual void parseSetupData() = 0;
virtual bell::AudioCodec getCodec() = 0;
};

View File

@@ -12,10 +12,12 @@ namespace bell {
class MP3Container : public AudioContainer {
public:
~MP3Container(){};
MP3Container(std::istream& istr);
MP3Container(std::istream& istr, const std::byte* headingBytes = nullptr);
std::byte* readSample(uint32_t& len) override;
void parseSetupData() override;
void consumeBytes(uint32_t len) override;
bell::AudioCodec getCodec() override { return bell::AudioCodec::MP3; }
private:
@@ -26,6 +28,7 @@ class MP3Container : public AudioContainer {
size_t bytesInBuffer = 0;
size_t dataOffset = 0;
size_t toConsume = 0;
bool fillBuffer();
};

View File

@@ -100,7 +100,6 @@ size_t BellDSP::process(uint8_t* data, size_t bytes, int channels,
// Data has been downmixed to mono
if (streamInfo->numChannels == 1) {
data16Bit[i] = dataLeft[i] * MAX_INT16; // Denormalize left
} else {
data16Bit[i * 2] = dataLeft[i] * MAX_INT16; // Denormalize left

View File

@@ -49,12 +49,12 @@ ES8388AudioSink::ES8388AudioSink() {
ESP_LOGE("OI", "i2s set pin error: %d", err);
}
err = i2c_param_config(0, &i2c_config);
err = i2c_param_config(I2C_NUM_0, &i2c_config);
if (err != ESP_OK) {
ESP_LOGE("OI", "i2c param config error: %d", err);
}
err = i2c_driver_install(0, I2C_MODE_MASTER, 0, 0, 0);
err = i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
if (err != ESP_OK) {
ESP_LOGE("OI", "i2c driver installation error: %d", err);
}
@@ -132,7 +132,7 @@ void ES8388AudioSink::writeReg(uint8_t reg_add, uint8_t data) {
res |= i2c_master_write_byte(cmd, reg_add, ACK_CHECK_EN);
res |= i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
res |= i2c_master_stop(cmd);
res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_PERIOD_MS);
res |= i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (res != ESP_OK) {

View File

@@ -97,7 +97,7 @@ class ES8388AudioSink : public BufferedAudioSink {
private:
i2c_config_t i2c_config;
i2c_port_t i2c_port = 0;
i2c_port_t i2c_port = I2C_NUM_0;
};
#endif
#endif

View File

@@ -22,7 +22,7 @@ class TAS5711AudioSink : public BufferedAudioSink {
private:
i2c_config_t i2c_config;
i2c_port_t i2c_port = 0;
i2c_port_t i2c_port = I2C_NUM_0;
};
#endif
#endif

View File

@@ -35,7 +35,14 @@ class WebSocketHandler : public CivetWebSocketHandler {
}
virtual bool handleData(CivetServer* server, struct mg_connection* conn,
int bits, char* data, size_t data_len) {
int flags, char* data, size_t data_len) {
if ((flags & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
// Received close message from client. Close the connection.
this->stateHandler(conn, BellHTTPServer::WSState::CLOSED);
return false;
}
this->dataHandler(conn, data, data_len);
return true;
}

View File

@@ -14,8 +14,8 @@ using namespace bell;
EncodedAudioStream::EncodedAudioStream() {
bell::decodersInstance->ensureAAC();
bell::decodersInstance->ensureMP3();
inputBuffer = std::vector<uint8_t>(AAC_READBUF_SIZE * 4);
outputBuffer = std::vector<short>(AAC_MAX_NCHANS * AAC_MAX_NSAMPS * 4 * 4);
inputBuffer = std::vector<uint8_t>(1024 * 4);
outputBuffer = std::vector<short>(2 * 2 * 4 * 4);
decodePtr = inputBuffer.data();
}
@@ -115,46 +115,47 @@ bool EncodedAudioStream::isReadable() {
}
size_t EncodedAudioStream::decodeFrameAAC(uint8_t* dst) {
size_t writtenBytes = 0;
auto bufSize = AAC_READBUF_SIZE;
return 0;
// size_t writtenBytes = 0;
// auto bufSize = AAC_READBUF_SIZE;
int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
bufSize - bytesInBuffer);
if (readBytes > 0) {
bytesInBuffer += readBytes;
decodePtr = inputBuffer.data();
offset = AACFindSyncWord(inputBuffer.data(), bytesInBuffer);
// int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
// bufSize - bytesInBuffer);
// if (readBytes > 0) {
// bytesInBuffer += readBytes;
// decodePtr = inputBuffer.data();
// offset = AACFindSyncWord(inputBuffer.data(), bytesInBuffer);
if (offset != -1) {
bytesInBuffer -= offset;
decodePtr += offset;
// if (offset != -1) {
// bytesInBuffer -= offset;
// decodePtr += offset;
int decodeStatus =
AACDecode(bell::decodersInstance->aacDecoder, &decodePtr,
&bytesInBuffer, outputBuffer.data());
AACGetLastFrameInfo(bell::decodersInstance->aacDecoder, &aacFrameInfo);
if (decodeStatus == ERR_AAC_NONE) {
decodedSampleRate = aacFrameInfo.sampRateOut;
writtenBytes =
(aacFrameInfo.bitsPerSample / 8) * aacFrameInfo.outputSamps;
// int decodeStatus =
// AACDecode(bell::decodersInstance->aacDecoder, &decodePtr,
// &bytesInBuffer, outputBuffer.data());
// AACGetLastFrameInfo(bell::decodersInstance->aacDecoder, &aacFrameInfo);
// if (decodeStatus == ERR_AAC_NONE) {
// decodedSampleRate = aacFrameInfo.sampRateOut;
// writtenBytes =
// (aacFrameInfo.bitsPerSample / 8) * aacFrameInfo.outputSamps;
memcpy(dst, outputBuffer.data(), writtenBytes);
// memcpy(dst, outputBuffer.data(), writtenBytes);
} else {
BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
decodeStatus);
decodePtr += 1;
bytesInBuffer -= 1;
}
} else {
BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
decodePtr += 3800;
bytesInBuffer -= 3800;
}
// } else {
// BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
// decodeStatus);
// decodePtr += 1;
// bytesInBuffer -= 1;
// }
// } else {
// BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
// decodePtr += 3800;
// bytesInBuffer -= 3800;
// }
memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
}
return writtenBytes;
// memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
// }
// return writtenBytes;
}
void EncodedAudioStream::guessDataFormat() {

View File

@@ -0,0 +1,77 @@
// MGStreamAdapter.cpp
#include "MGStreamAdapter.h"
mg_buf::mg_buf(struct mg_connection* _conn) : conn(_conn) {
setp(buffer, buffer + BUF_SIZE - 1); // -1 to leave space for overflow '\0'
}
mg_buf::int_type mg_buf::overflow(int_type c) {
if (c != EOF) {
*pptr() = c;
pbump(1);
}
if (flush_buffer() == EOF) {
return EOF;
}
return c;
}
int mg_buf::flush_buffer() {
int len = int(pptr() - pbase());
if (mg_write(conn, buffer, len) != len) {
return EOF;
}
pbump(-len); // reset put pointer accordingly
return len;
}
int mg_buf::sync() {
if (flush_buffer() == EOF) {
return -1; // return -1 on error
}
return 0;
}
MGStreamAdapter::MGStreamAdapter(struct mg_connection* _conn) : std::ostream(&buf), buf(_conn) {
rdbuf(&buf); // set the custom streambuf
}
mg_read_buf::mg_read_buf(struct mg_connection* _conn) : conn(_conn) {
setg(buffer + BUF_SIZE, // beginning of putback area
buffer + BUF_SIZE, // read position
buffer + BUF_SIZE); // end position
}
mg_read_buf::int_type mg_read_buf::underflow() {
if (gptr() < egptr()) { // buffer not exhausted
return traits_type::to_int_type(*gptr());
}
char* base = buffer;
char* start = base;
if (eback() == base) { // true when this isn't the first fill
// Make arrangements for putback characters
std::memmove(base, egptr() - 2, 2);
start += 2;
}
// Read new characters
int n = mg_read(conn, start, buffer + BUF_SIZE - start);
if (n == 0) {
return traits_type::eof();
}
// Set buffer pointers
setg(base, start, start + n);
// Return next character
return traits_type::to_int_type(*gptr());
}
MGInputStreamAdapter::MGInputStreamAdapter(struct mg_connection* _conn) : std::istream(&buf), buf(_conn) {
rdbuf(&buf); // set the custom streambuf
}

View File

@@ -51,7 +51,7 @@ class reader {
reader(std::istream& inp)
: _inp(inp), _cached_header_data_valid(false), _number_of_files(-1) {}
// Returns true iff another file can be read from |inp|.
// Returns true if another file can be read from |inp|.
bool contains_another_file();
// Returns file name of next file in |inp|.
@@ -72,4 +72,4 @@ class reader {
// Returns number of files in tar at |inp|.
int number_of_files();
};
} // namespace bell::BellTar
} // namespace bell::BellTar

View File

@@ -1,8 +1,9 @@
#pragma once
#ifndef ESP_PLATFORM
#if __has_include(<bit>)
#include <bit> // for endian
#endif
#include <stdint.h> // for int16_t, int32_t, int64_t, uint16_t, uint32_t
#include <cstddef> // for byte
#include <iostream> // for istream, ostream

View File

@@ -6,7 +6,6 @@
#include <string> // for basic_string, string
#include <vector> // for vector
#include "aacdec.h" // for AACFrameInfo
#include "mp3dec.h" // for MP3FrameInfo
namespace bell {
@@ -48,7 +47,7 @@ class EncodedAudioStream {
std::vector<uint8_t> mp3MagicBytesUntagged = {0xFF, 0xFB};
std::vector<uint8_t> mp3MagicBytesIdc = {0x49, 0x44, 0x33};
AACFrameInfo aacFrameInfo;
// AACFrameInfo aacFrameInfo;
MP3FrameInfo mp3FrameInfo;
size_t decodeFrameMp3(uint8_t* dst);

View File

@@ -0,0 +1,60 @@
#pragma once
#include <iostream>
#include <ostream>
#include <cstring>
#include "civetweb.h"
const size_t BUF_SIZE = 1024;
// Custom streambuf
class mg_buf : public std::streambuf {
private:
struct mg_connection* conn;
char buffer[BUF_SIZE];
public:
mg_buf(struct mg_connection* _conn);
protected:
virtual int_type overflow(int_type c);
int flush_buffer();
virtual int sync();
};
/**
* @brief Adapts ostream to mg_write
*
*/
class MGStreamAdapter : public std::ostream {
private:
mg_buf buf;
public:
MGStreamAdapter(struct mg_connection* _conn);
};
// Custom streambuf
class mg_read_buf : public std::streambuf {
private:
struct mg_connection* conn;
char buffer[BUF_SIZE];
public:
mg_read_buf(struct mg_connection* _conn);
protected:
virtual int_type underflow();
};
/**
* @brief Adapts istream to mg_read
*/
class MGInputStreamAdapter : public std::istream {
private:
mg_read_buf buf;
public:
MGInputStreamAdapter(struct mg_connection* _conn);
};

View File

@@ -4,6 +4,9 @@
#include <random> // for mt19937, uniform_int_distribution, random_device
#ifdef ESP_PLATFORM
#include "esp_system.h"
#if __has_include("esp_mac.h")
#include "esp_mac.h"
#endif
#endif
std::string bell::generateRandomUUID() {
@@ -27,6 +30,7 @@ std::string bell::generateRandomUUID() {
std::string bell::getMacAddress() {
#ifdef ESP_PLATFORM
uint8_t mac[6];
esp_read_mac(mac, ESP_MAC_WIFI_STA);
char macStr[18];

View File

@@ -135,14 +135,20 @@ std::vector<uint8_t> CryptoMbedTLS::pbkdf2HmacSha1(
int iterations, int digestSize) {
auto digest = std::vector<uint8_t>(digestSize);
#if MBEDTLS_VERSION_NUMBER < 0x03030000
// Init sha context
sha1Init();
mbedtls_pkcs5_pbkdf2_hmac(&sha1Context, password.data(), password.size(),
salt.data(), salt.size(), iterations, digestSize,
digest.data());
// Free sha context
mbedtls_md_free(&sha1Context);
#else
mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, password.data(), password.size(),
salt.data(), salt.size(), iterations, digestSize,
digest.data());
#endif
return digest;
}
@@ -230,4 +236,4 @@ std::vector<uint8_t> CryptoMbedTLS::generateVectorWithRandomData(
mbedtls_ctr_drbg_free(&ctrDrbg);
return randomVector;
}
}