sbc decoder: use singleton for now

This commit is contained in:
Milanka Ringwald 2016-07-01 14:56:16 +02:00
parent 48e0f8060d
commit aa6493c269
3 changed files with 50 additions and 34 deletions

View File

@ -10,16 +10,24 @@ include ${SBC_ENCODER_ROOT}/Makefile.inc
SBC_DECODER_OBJ = $(SBC_DECODER:.c=.o) SBC_DECODER_OBJ = $(SBC_DECODER:.c=.o)
SBC_ENCODER_OBJ = $(SBC_ENCODER:.c=.o) SBC_ENCODER_OBJ = $(SBC_ENCODER:.c=.o)
CFLAGS = -g -Wall -I. -I../ -I${SBC_DECODER_ROOT}/include -I${SBC_ENCODER_ROOT}/include -D PRINT_SAMPLES -D PRINT_SCALEFACTORS -D OI_DEBUG -D SBC_NO_PCM_CPY_OPTION CFLAGS = -g -Wall -I. -I../ -I${BTSTACK_ROOT}/src -I${SBC_DECODER_ROOT}/include -I${SBC_ENCODER_ROOT}/include -D PRINT_SAMPLES -D PRINT_SCALEFACTORS -D OI_DEBUG -D SBC_NO_PCM_CPY_OPTION
# -D TRACE_EXECUTION -D CODEC_DEBUG # -D TRACE_EXECUTION -D CODEC_DEBUG
LDFLAGS += -lCppUTest -lCppUTestExt LDFLAGS += -lCppUTest -lCppUTestExt
VPATH += ${SBC_DECODER_ROOT}/srce ${SBC_ENCODER_ROOT}/srce VPATH += ${SBC_DECODER_ROOT}/srce
VPATH += ${SBC_ENCODER_ROOT}/srce
VPATH += ${BTSTACK_ROOT}/src
COMMON += \
hci_dump.c \
btstack_util.c \
COMMON_OBJ = $(COMMON:.c=.o)
SBC_TESTS = sbc_decoder_test sbc_encoder_test SBC_TESTS = sbc_decoder_test sbc_encoder_test
all: ${SBC_TESTS} all: ${SBC_TESTS}
sbc_decoder_test: ${SBC_DECODER_OBJ} sbc_decoder_bludroid.o sbc_decoder_test.o sbc_decoder_test: ${SBC_DECODER_OBJ} ${COMMON_OBJ} sbc_decoder_bludroid.o sbc_decoder_test.o
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
sbc_encoder_test: ${SBC_ENCODER_OBJ} sbc_encoder_test.o sbc_encoder_test: ${SBC_ENCODER_OBJ} sbc_encoder_test.o

View File

@ -53,19 +53,21 @@
#include "oi_codec_sbc.h" #include "oi_codec_sbc.h"
#include "oi_assert.h" #include "oi_assert.h"
static uint8_t frame_buffer[5000]; #include "btstack.h"
static int16_t pcm_data[1000];
static uint32_t pcm_bytes = sizeof(pcm_data);
static OI_UINT32 decoder_data[10000];
typedef struct { typedef struct {
OI_UINT32 bytes_read; OI_UINT32 bytes_read;
OI_UINT32 bytes_in_frame; OI_UINT32 bytes_in_frame;
const OI_BYTE *frame_data;
OI_CODEC_SBC_DECODER_CONTEXT decoder_context; OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
const OI_BYTE *frame_data;
uint8_t frame_buffer[5000];
int16_t pcm_data[1000];
uint32_t pcm_bytes;
OI_UINT32 decoder_data[10000];
} bludroid_decoder_state_t; } bludroid_decoder_state_t;
static sbc_decoder_state_t * sbc_state_singelton = NULL;
static bludroid_decoder_state_t bd_state; static bludroid_decoder_state_t bd_state;
int sbc_decoder_num_samples_per_frame(sbc_decoder_state_t * state){ int sbc_decoder_num_samples_per_frame(sbc_decoder_state_t * state){
@ -89,14 +91,22 @@ void OI_AssertFail(char* file, int line, char* reason){
} }
void sbc_decoder_init(sbc_decoder_state_t * state, void (*callback)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context), void * context){ void sbc_decoder_init(sbc_decoder_state_t * state, void (*callback)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context), void * context){
OI_STATUS status = OI_CODEC_mSBC_DecoderReset(&(bd_state.decoder_context), decoder_data, sizeof(decoder_data)); if (sbc_state_singelton && sbc_state_singelton != state ){
log_error("SBC decoder: different sbc decoder state is allready registered");
}
OI_STATUS status = OI_CODEC_mSBC_DecoderReset(&(bd_state.decoder_context),
bd_state.decoder_data, sizeof(bd_state.decoder_data));
if (status != 0){ if (status != 0){
printf("Reset decoder error %d\n", status); log_error("SBC decoder: error during reset %d\n", status);
} }
sbc_state_singelton = state;
bd_state.bytes_in_frame = 0; bd_state.bytes_in_frame = 0;
bd_state.bytes_read = 0; bd_state.bytes_read = 0;
bd_state.frame_data = NULL; bd_state.frame_data = NULL;
bd_state.pcm_bytes = sizeof(bd_state.pcm_data);
state->handle_pcm_data = callback; state->handle_pcm_data = callback;
state->context = context; state->context = context;
state->decoder_state = &bd_state; state->decoder_state = &bd_state;
@ -104,29 +114,32 @@ void sbc_decoder_init(sbc_decoder_state_t * state, void (*callback)(int16_t * da
} }
static void append_received_sbc_data(bludroid_decoder_state_t * state, uint8_t * buffer, int size){ static void append_received_sbc_data(bludroid_decoder_state_t * state, uint8_t * buffer, int size){
int numFreeBytes = sizeof(frame_buffer) - state->bytes_in_frame; int numFreeBytes = sizeof(state->frame_buffer) - state->bytes_in_frame;
if (size > numFreeBytes){ if (size > numFreeBytes){
printf("sbc data: more bytes read %u than free bytes in buffer %u", size, numFreeBytes); log_error("SBC data: more bytes read %u than free bytes in buffer %u", size, numFreeBytes);
exit(10);
} }
memcpy(frame_buffer + state->bytes_in_frame, buffer, size); memcpy(state->frame_buffer + state->bytes_in_frame, buffer, size);
state->bytes_in_frame += size; state->bytes_in_frame += size;
state->bytes_read = state->bytes_in_frame; state->bytes_read = state->bytes_in_frame;
state->frame_data = frame_buffer; state->frame_data = state->frame_buffer;
} }
void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int size){ void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int size){
int bytes_read = size; int bytes_read = size;
while (bytes_read > 0){ while (bytes_read > 0){
bludroid_decoder_state_t * bd_decoder_state = (bludroid_decoder_state_t*)state->decoder_state; bludroid_decoder_state_t * bd_decoder_state = (bludroid_decoder_state_t*)state->decoder_state;
int space_in_frame_buffer = sizeof(frame_buffer) - bd_decoder_state->bytes_in_frame; int space_in_frame_buffer = sizeof(bd_decoder_state->frame_buffer) - bd_decoder_state->bytes_in_frame;
int bytes_to_append = space_in_frame_buffer > bytes_read ? bytes_read : space_in_frame_buffer; int bytes_to_append = space_in_frame_buffer > bytes_read ? bytes_read : space_in_frame_buffer;
append_received_sbc_data(bd_decoder_state, buffer, bytes_to_append); append_received_sbc_data(bd_decoder_state, buffer, bytes_to_append);
while (1){ while (1){
OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(bd_decoder_state->decoder_context), &(bd_decoder_state->frame_data), &(bd_decoder_state->bytes_in_frame), pcm_data, &pcm_bytes); OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(bd_decoder_state->decoder_context),
&(bd_decoder_state->frame_data),
&(bd_decoder_state->bytes_in_frame),
bd_decoder_state->pcm_data,
&(bd_decoder_state->pcm_bytes));
if (status != 0){ if (status != 0){
if (status != OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA && status != OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA){ if (status != OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA && status != OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA){
@ -135,10 +148,15 @@ void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int
break; break;
} }
// printf("Not enough data, read next %u bytes, move %d bytes\n", state->bytes_read-state->bytes_in_frame, state->bytes_in_frame); // printf("Not enough data, read next %u bytes, move %d bytes\n", state->bytes_read-state->bytes_in_frame, state->bytes_in_frame);
memmove(frame_buffer, frame_buffer + bd_decoder_state->bytes_read - bd_decoder_state->bytes_in_frame, bd_decoder_state->bytes_in_frame); memmove(bd_decoder_state->frame_buffer,
bd_decoder_state->frame_buffer + bd_decoder_state->bytes_read - bd_decoder_state->bytes_in_frame,
bd_decoder_state->bytes_in_frame);
break; break;
} }
state->handle_pcm_data(pcm_data, sbc_decoder_num_samples_per_frame(state), sbc_decoder_num_channels(state), sbc_decoder_sample_rate(state), state->context); state->handle_pcm_data(bd_decoder_state->pcm_data,
sbc_decoder_num_samples_per_frame(state),
sbc_decoder_num_channels(state),
sbc_decoder_sample_rate(state), state->context);
} }
memmove(buffer, buffer + bytes_to_append, size - bytes_to_append); memmove(buffer, buffer + bytes_to_append, size - bytes_to_append);

View File

@ -52,6 +52,8 @@
#include "sbc_decoder.h" #include "sbc_decoder.h"
#include "oi_assert.h" #include "oi_assert.h"
#include "btstack.h"
static uint8_t read_buffer[6000]; static uint8_t read_buffer[6000];
static uint8_t buf[4]; static uint8_t buf[4];
@ -79,18 +81,6 @@ static ssize_t __read(int fd, void *buf, size_t count){
return pos; return pos;
} }
void little_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){
buffer[pos++] = value;
buffer[pos++] = value >> 8;
}
void little_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){
buffer[pos++] = value;
buffer[pos++] = value >> 8;
buffer[pos++] = value >> 16;
buffer[pos++] = value >> 24;
}
void little_endian_fstore_16(FILE *wav_file, uint16_t value){ void little_endian_fstore_16(FILE *wav_file, uint16_t value){
little_endian_store_32(buf, 0, value); little_endian_store_32(buf, 0, value);
fwrite(&buf, 1, 2, wav_file); fwrite(&buf, 1, 2, wav_file);