Recently I am working on audio processing. To put it simply, I want to codec the data of one frame and one frame. Some audio formats have an uncertain data size, such as AAC, it is often necessary to process a piece of data of unknown size.
If static arrays are used, the size is not determined, and it is not conducive to expansion according to the demand changes. Currently, the memory of the machine is relatively large, but the memory should be used properly to avoid waste. Dynamic Allocation, frequent memory allocation/release may easily generate memory fragments, affecting program efficiency.
In the above case, I wrote a dynamic buffer. Currently, the interface is not very complete and can be added if necessary.
/**
*
* filename: Buffer.h
* summary: dynamic buffer
* author: caosiyang
* email: csy3228@gmail.com
*
*/
#ifndef __BUFFER_H__
#define __BUFFER_H__
#include <iostream>
#include <assert.h>
using namespace std;
class Buffer {
public:
Buffer() : _buffer(NULL), _index(0), _length(0), _left(0), _initlen(102400), _incrlen(20480) {
assert(0 == _init());
}
//recommended
Buffer(const int32_t initlen, const int32_t incrlen) : _buffer(NULL), _index(0), _length(0), _left(0), _initlen(initlen), _incrlen(incrlen) {
assert(0 == _init());
}
~Buffer() {
if (_buffer) {
_free();
}
}
//reinitialize
int32_t Reinit(const int32_t initlen, const int32_t incrlen) {
_initlen = initlen;
_incrlen = incrlen;
return _init();
}
//copy data to buffer
int32_t Fill(const char *buf, const int32_t buflen) {
if (!_buffer) { //NULL pointer
return -1;
}
while (_left < buflen) {
char *p = (char *)realloc(_buffer, (_length + _incrlen) * sizeof(char));
if (p) {
_buffer = p;
_length += _incrlen;
_left += _incrlen;
//cout << "realloc() done" << endl;
} else {
//cerr << "realloc() failed" << endl;
}
}
memcpy(_buffer + _index, buf, buflen);
_index += buflen;
_left -= buflen;
return 0;
}
//get pointer of buffer
const char* Data() const {
return _buffer;
}
//get length of data in buffer
const int32_t Length() const {
return _index;
}
//print buffer status
void Status() const {
cout << "buffer status:" << endl;
cout << "_initlen = " << _initlen << endl;
cout << "_incrlen = " << _incrlen << endl;
cout << "_index = " << _index << endl;
cout << "_left = " << _left << endl;
cout << "_length = " << _length << endl;
cout << endl;
}
//set buffer's bytes to 0
void Clean() {
if (_buffer) {
memset(_buffer, 0, _length);
_index = 0;
_left = _length;
}
}
private:
Buffer(const Buffer &buffer);
Buffer& operator=(const Buffer &rhs);
char *_buffer;
int32_t _index; //current position
int32_t _length; //total length
int32_t _left; //length of available buffer
int32_t _initlen; //initial length
int32_t _incrlen; //increment length
//init buffer
int32_t _init() {
//avoid memory leak
if (_buffer) {
_free();
}
if (_initlen <= 0 || _incrlen <= 0) {
return -1;
}
_buffer = (char *)malloc(_initlen * sizeof(char));
if (!_buffer) {
cerr << "malloc() failed" << endl;
return -1;
}
_length = _initlen;
_index = 0;
_left = _initlen;
return 0;
}
//free buffer
void _free() {
free(_buffer);
_buffer = NULL;
_length = 0;
_index = 0;
_left = 0;
}
};
#endif /*__BUFFER_H__*/