mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-14 23:47:02 +03:00
Bell catchup
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
77
components/spotify/cspot/bell/main/io/MGStreamAdapter.cpp
Normal file
77
components/spotify/cspot/bell/main/io/MGStreamAdapter.cpp
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user