Skip to content

Commit

Permalink
Correct allocation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Jan 27, 2022
1 parent b142ff4 commit b1646a9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 66 deletions.
51 changes: 27 additions & 24 deletions src/AACDecoderHelix.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include "CommonHelix.h"
#include "libhelix-aac/aacdec.h"

#define AAC_MAX_OUTPUT_SIZE 2048
#define AAC_MAX_FRAME_SIZE 1600
#define AAC_MAX_OUTPUT_SIZE 1024 * 3
#define AAC_MAX_FRAME_SIZE 2100

namespace libhelix {

Expand All @@ -19,24 +19,20 @@ typedef void (*AACDataCallback)(_AACFrameInfo &info,short *pwm_buffer, size_t le
*/
class AACDecoderHelix : public CommonHelix {
public:
AACDecoderHelix() {
decoder = AACInitDecoder();
}
AACDecoderHelix() = default;

#ifdef ARDUINO
AACDecoderHelix(Print &output, AACInfoCallback infoCallback=nullptr){
decoder = AACInitDecoder();
this->out = &output;
this->infoCallback = infoCallback;
}
#endif
AACDecoderHelix(AACDataCallback dataCallback){
decoder = AACInitDecoder();
this->pwmCallback = dataCallback;
}

~AACDecoderHelix(){
AACFreeDecoder(decoder);
virtual ~AACDecoderHelix(){
end();
}


Expand All @@ -50,10 +46,11 @@ class AACDecoderHelix : public CommonHelix {


/// Releases the reserved memory
void end(){
LOG(Debug, "end");
if (CommonHelix::active){
virtual void end() override {
LOG_HELIX(Debug, "end");
if (decoder!=nullptr){
AACFreeDecoder(decoder);
decoder = nullptr;
}
CommonHelix::end();
}
Expand All @@ -69,22 +66,29 @@ class AACDecoderHelix : public CommonHelix {
AACInfoCallback infoCallback = nullptr;
_AACFrameInfo aacFrameInfo;

size_t maxFrameSize(){
/// Allocate the decoder
virtual void allocateDecoder() override {
if (decoder==nullptr){
decoder = AACInitDecoder();
}
}

size_t maxFrameSize() override {
return max_frame_size == 0 ? AAC_MAX_FRAME_SIZE : max_frame_size;
}

size_t maxPWMSize() {
size_t maxPWMSize() override {
return max_pwm_size == 0 ? AAC_MAX_OUTPUT_SIZE : max_pwm_size;
}

int findSynchWord(int offset=0) {
int findSynchWord(int offset=0) override {
int result = AACFindSyncWord(frame_buffer+offset, buffer_size)+offset;
return result < 0 ? result : result + offset;
}

/// decods the data and removes the decoded frame from the buffer
void decode(Range r) {
LOG(Debug, "decode %d", r.end);
void decode(Range r) override {
LOG_HELIX(Debug, "decode %d", r.end);
int len = buffer_size - r.start;
int bytesLeft = len;
uint8_t* ptr = frame_buffer + r.start;
Expand All @@ -93,8 +97,8 @@ class AACDecoderHelix : public CommonHelix {
int decoded = len - bytesLeft;
assert(decoded == ptr-(frame_buffer + r.start));
if (result==0){
LOG(Debug, "-> bytesLeft %d -> %d = %d ", buffer_size, bytesLeft, decoded);
LOG(Debug, "-> End of frame (%d) vs end of decoding (%d)", r.end, decoded)
LOG_HELIX(Debug, "-> bytesLeft %d -> %d = %d ", buffer_size, bytesLeft, decoded);
LOG_HELIX(Debug, "-> End of frame (%d) vs end of decoding (%d)", r.end, decoded)

// return the decoded result
_AACFrameInfo info;
Expand All @@ -106,14 +110,14 @@ class AACDecoderHelix : public CommonHelix {
buffer_size -= decoded;
//assert(buffer_size<=maxFrameSize());
memmove(frame_buffer, frame_buffer+r.start+decoded, buffer_size);
LOG(Debug, " -> decoded %d bytes - remaining buffer_size: %d", decoded, buffer_size);
LOG_HELIX(Debug, " -> decoded %d bytes - remaining buffer_size: %d", decoded, buffer_size);
} else {
LOG(Warning, " -> decoded %d > buffersize %d", decoded, buffer_size);
LOG_HELIX(Warning, " -> decoded %d > buffersize %d", decoded, buffer_size);
buffer_size = 0;
}
} else {
// decoding error
LOG(Debug, " -> decode error: %d - removing frame!", result);
LOG_HELIX(Debug, " -> decode error: %d - removing frame!", result);
int ignore = decoded;
if (ignore == 0) ignore = r.end;
// We advance to the next synch world
Expand All @@ -123,13 +127,12 @@ class AACDecoderHelix : public CommonHelix {
} else {
buffer_size = 0;
}

}
}

// return the result PWM data
void provideResult(_AACFrameInfo &info){
LOG(Debug, "provideResult: %d samples",info.outputSamps);
LOG_HELIX(Debug, "provideResult: %d samples",info.outputSamps);
if (info.outputSamps>0){
// provide result
if(pwmCallback!=nullptr){
Expand Down
43 changes: 24 additions & 19 deletions src/CommonHelix.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,19 @@ class CommonHelix {
if (active){
end();
}

allocateDecoder();

if (frame_buffer == nullptr) {
LOG(Info,"allocating frame_buffer with %zu bytes", maxFrameSize());
LOG_HELIX(Info,"allocating frame_buffer with %zu bytes", maxFrameSize());
frame_buffer = new uint8_t[maxFrameSize()];
}
if (pwm_buffer == nullptr) {
LOG(Info,"allocating pwm_buffer with %zu bytes", maxPWMSize());
LOG_HELIX(Info,"allocating pwm_buffer with %zu bytes", maxPWMSize());
pwm_buffer = new short[maxPWMSize()];
}
if (pwm_buffer==nullptr || frame_buffer==nullptr){
LOG(Error, "Not enough memory for buffers");
LOG_HELIX(Error, "Not enough memory for buffers");
active = false;
return;
}
Expand All @@ -108,7 +111,7 @@ class CommonHelix {
*/

virtual size_t write(const void *in_ptr, size_t in_size) {
LOG(Debug, "write %zu", in_size);
LOG_HELIX(Debug, "write %zu", in_size);
size_t start = 0;
if (active){
uint8_t* ptr8 = (uint8_t* )in_ptr;
Expand All @@ -118,15 +121,15 @@ class CommonHelix {
// we have some space left in the buffer
int written_len = writeFrame(ptr8+start, write_len);
start += written_len;
LOG(Info,"-> Written %zu of %zu - Counter %zu", start, in_size, frame_counter);
LOG_HELIX(Info,"-> Written %zu of %zu - Counter %zu", start, in_size, frame_counter);
write_len = min(in_size - start, static_cast<size_t>(maxFrameSize()-buffer_size));
// add delay - e.g. needed by esp32 and esp8266
if (delay_ms>0){
delay(delay_ms);
}
}
} else {
LOG(Warning, "CommonHelix not active");
LOG_HELIX(Warning, "CommonHelix not active");
}

return start;
Expand Down Expand Up @@ -156,6 +159,8 @@ class CommonHelix {
Print *out = nullptr;
#endif

virtual void allocateDecoder() = 0;

/// Provides the maximum frame size - this is allocated on the heap and you can reduce the heap size my minimizing this value
virtual size_t maxFrameSize() = 0;

Expand All @@ -180,23 +185,23 @@ class CommonHelix {

/// we add the data to the buffer until it is full
size_t appendToBuffer(const void *in_ptr, int in_size){
LOG(Info, "appendToBuffer: %d (at %p)", in_size, frame_buffer);
LOG_HELIX(Info, "appendToBuffer: %d (at %p)", in_size, frame_buffer);
int buffer_size_old = buffer_size;
int process_size = min((int)(maxFrameSize() - buffer_size), in_size);
memmove(frame_buffer+buffer_size, in_ptr, process_size);
buffer_size += process_size;
if (buffer_size>maxFrameSize()){
LOG(Error, "Increase MAX_FRAME_SIZE > %zu", buffer_size);
LOG_HELIX(Error, "Increase MAX_FRAME_SIZE > %zu", buffer_size);
}
assert(buffer_size<=maxFrameSize());

LOG(Debug, "appendToBuffer %d + %d -> %u", buffer_size_old, process_size, buffer_size );
LOG_HELIX(Debug, "appendToBuffer %d + %d -> %u", buffer_size_old, process_size, buffer_size );
return process_size;
}

/// appends the data to the frame buffer and decodes
size_t writeFrame(const void *in_ptr, size_t in_size){
LOG(Debug, "writeFrame %zu", in_size);
LOG_HELIX(Debug, "writeFrame %zu", in_size);
size_t result = 0;
// in the beginning we ingnore all data until we found the first synch word
result = appendToBuffer(in_ptr, in_size);
Expand All @@ -205,39 +210,39 @@ class CommonHelix {
if(r.isValid(maxFrameSize())){
decode(r);
} else {
LOG(Warning, " -> invalid frame size: %d / max: %d", (int) r.end-r.start, (int) maxFrameSize());
LOG_HELIX(Warning, " -> invalid frame size: %d / max: %d", (int) r.end-r.start, (int) maxFrameSize());
}
frame_counter++;
return result;
}

/// returns valid start and end synch word.
Range synchronizeFrame() {
LOG(Debug, "synchronizeFrame");
LOG_HELIX(Debug, "synchronizeFrame");
Range range = frameRange();
if (range.start<0){
// there is no Synch in the buffer at all -> we can ignore all data
range.end = -1;
LOG(Debug, "-> no synch")
LOG_HELIX(Debug, "-> no synch")
if (buffer_size==maxFrameSize()) {
buffer_size = 0;
LOG(Debug, "-> buffer cleared");
LOG_HELIX(Debug, "-> buffer cleared");
}
} else if (range.start>0) {
// make sure that buffer starts with a synch word
LOG(Debug, "-> moving to new start %d",range.start);
LOG_HELIX(Debug, "-> moving to new start %d",range.start);
buffer_size -= range.start;
assert(buffer_size<=maxFrameSize());

memmove(frame_buffer, frame_buffer + range.start, buffer_size);
range.end -= range.start;
range.start = 0;
LOG(Debug, "-> we are at beginning of synch word");
LOG_HELIX(Debug, "-> we are at beginning of synch word");
} else if (range.start==0) {
LOG(Debug, "-> we are at beginning of synch word");
LOG_HELIX(Debug, "-> we are at beginning of synch word");
if (range.end<0 && buffer_size == maxFrameSize()){
buffer_size = 0;
LOG(Debug, "-> buffer cleared");
LOG_HELIX(Debug, "-> buffer cleared");
}
}
return range;
Expand All @@ -248,7 +253,7 @@ class CommonHelix {
Range result;
result.start = findSynchWord(0);
result.end = findSynchWord(result.start+SYNCH_WORD_LEN);
LOG(Debug, "-> frameRange -> %d - %d", result.start, result.end);
LOG_HELIX(Debug, "-> frameRange -> %d - %d", result.start, result.end);
return result;
}

Expand Down
Loading

0 comments on commit b1646a9

Please sign in to comment.