mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-14 01:27:41 +00:00
sbc decoder: get sequence nr from H2 header
This commit is contained in:
parent
a7e6f4dda0
commit
743c1aead2
@ -71,6 +71,10 @@ int sbc_decoder_num_samples_per_frame(sbc_decoder_state_t * state);
|
||||
int sbc_decoder_num_channels(sbc_decoder_state_t * state);
|
||||
int sbc_decoder_sample_rate(sbc_decoder_state_t * state);
|
||||
|
||||
// testing only
|
||||
void sbc_decoder_test_disable_plc(void);
|
||||
void sbc_decoder_test_simulate_corrupt_frames(int period);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -61,6 +61,15 @@
|
||||
#define SBC_MAX_CHANNELS 2
|
||||
#define DECODER_DATA_SIZE (SBC_MAX_CHANNELS*SBC_MAX_BLOCKS*SBC_MAX_BANDS * 2 + SBC_CODEC_MIN_FILTER_BUFFERS*SBC_MAX_BANDS*SBC_MAX_CHANNELS * 2)
|
||||
|
||||
#define mSBC_SYNCWORD 0xad
|
||||
#define SBC_SYNCWORD 0x9c
|
||||
|
||||
|
||||
// Testing only - START
|
||||
static int plc_enabled = 1;
|
||||
static int corrupt_frame_period = -1;
|
||||
// Testing - STOP
|
||||
|
||||
typedef struct {
|
||||
OI_UINT32 bytes_in_frame_buffer;
|
||||
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
|
||||
@ -70,11 +79,51 @@ typedef struct {
|
||||
int16_t pcm_data[SBC_MAX_CHANNELS * SBC_MAX_BANDS * SBC_MAX_BLOCKS];
|
||||
uint32_t pcm_bytes;
|
||||
OI_UINT32 decoder_data[(DECODER_DATA_SIZE+3)/4];
|
||||
int corrupt_frame;
|
||||
int h2_syncword;
|
||||
int search_new_sync_word;
|
||||
int sync_word_found;
|
||||
} bludroid_decoder_state_t;
|
||||
|
||||
|
||||
static sbc_decoder_state_t * sbc_state_singelton = NULL;
|
||||
static bludroid_decoder_state_t bd_state;
|
||||
|
||||
void sbc_decoder_test_disable_plc(void){
|
||||
plc_enabled = 0;
|
||||
}
|
||||
|
||||
void sbc_decoder_test_simulate_corrupt_frames(int period){
|
||||
corrupt_frame_period = period;
|
||||
}
|
||||
|
||||
static int find_h2_syncword(const OI_BYTE *frameData, OI_UINT32 frameBytes, sbc_mode_t mode){
|
||||
if (mode != SBC_MODE_mSBC) return -1;
|
||||
int syncword = mSBC_SYNCWORD;
|
||||
uint8_t h2_first_byte = 0;
|
||||
uint8_t h2_second_byte = 0;
|
||||
|
||||
int i;
|
||||
for (i=0; i<frameBytes; i++){
|
||||
if (frameData[i] == syncword) {
|
||||
break;
|
||||
}
|
||||
h2_first_byte = h2_second_byte;
|
||||
h2_second_byte = frameData[i];
|
||||
}
|
||||
if (h2_first_byte != 1) return -1;
|
||||
|
||||
// check if upper nibble of second byte is 0x08
|
||||
uint8_t ln = h2_second_byte & 0x0F;
|
||||
if (ln != 8) return -1;
|
||||
|
||||
// check that bits 0+2 == bits 1+3
|
||||
uint8_t hn = h2_second_byte >> 4;
|
||||
if ( ((hn>>1) & 0x05) != (hn & 0x05) ) return -1;
|
||||
|
||||
return ((hn & 0x04) >> 1) | (hn & 0x01);
|
||||
}
|
||||
|
||||
int sbc_decoder_num_samples_per_frame(sbc_decoder_state_t * state){
|
||||
bludroid_decoder_state_t * decoder_state = (bludroid_decoder_state_t *) state->decoder_state;
|
||||
return decoder_state->decoder_context.common.frameInfo.nrof_blocks * decoder_state->decoder_context.common.frameInfo.nrof_subbands;
|
||||
@ -116,11 +165,18 @@ void sbc_decoder_init(sbc_decoder_state_t * state, sbc_mode_t mode, void (*callb
|
||||
sbc_state_singelton = state;
|
||||
bd_state.bytes_in_frame_buffer = 0;
|
||||
bd_state.pcm_bytes = sizeof(bd_state.pcm_data);
|
||||
bd_state.h2_syncword = -1;
|
||||
bd_state.sync_word_found = 0;
|
||||
bd_state.search_new_sync_word = 0;
|
||||
if (mode == SBC_MODE_mSBC){
|
||||
bd_state.search_new_sync_word = 1;
|
||||
}
|
||||
|
||||
state->handle_pcm_data = callback;
|
||||
state->mode = mode;
|
||||
state->context = context;
|
||||
state->decoder_state = &bd_state;
|
||||
|
||||
sbc_plc_init(&state->plc_state);
|
||||
}
|
||||
|
||||
@ -139,7 +195,7 @@ static void append_received_sbc_data(bludroid_decoder_state_t * state, uint8_t *
|
||||
void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int size){
|
||||
bludroid_decoder_state_t * bd_decoder_state = (bludroid_decoder_state_t*)state->decoder_state;
|
||||
int bytes_to_process = size;
|
||||
int msbc_frame_size = 57;
|
||||
int msbc_frame_size = 57; // 57 for mSBC frame, 2 for header H2
|
||||
|
||||
// printf("<<-- enter -->>\n");
|
||||
|
||||
@ -167,6 +223,25 @@ void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int
|
||||
uint16_t bytes_processed = 0;
|
||||
const OI_BYTE *frame_data = bd_decoder_state->frame_buffer;
|
||||
|
||||
static int frame_count = 0;
|
||||
if (corrupt_frame_period > 0){
|
||||
frame_count++;
|
||||
|
||||
if (frame_count % corrupt_frame_period == 0){
|
||||
*(uint8_t*)&frame_data[5] = 0;
|
||||
frame_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bd_decoder_state->search_new_sync_word && !bd_decoder_state->sync_word_found){
|
||||
int h2_syncword = find_h2_syncword(frame_data, bd_decoder_state->bytes_in_frame_buffer, state->mode);
|
||||
if (h2_syncword != -1){
|
||||
bd_decoder_state->sync_word_found = 1;
|
||||
bd_decoder_state->h2_syncword = h2_syncword;
|
||||
}
|
||||
}
|
||||
// printf("Sync1: %d\n", bd_decoder_state->h2_syncword);
|
||||
|
||||
OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(bd_decoder_state->decoder_context),
|
||||
&frame_data,
|
||||
&(bd_decoder_state->bytes_in_frame_buffer),
|
||||
@ -175,31 +250,49 @@ void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int
|
||||
|
||||
bytes_processed = bytes_in_buffer_before - bd_decoder_state->bytes_in_frame_buffer;
|
||||
|
||||
// printf("Decode status %u, processed %u, left %u\n", status, bytes_processed, bd_decoder_state->bytes_in_frame_buffer);
|
||||
|
||||
memmove(bd_decoder_state->frame_buffer, bd_decoder_state->frame_buffer + bytes_processed, bd_decoder_state->bytes_in_frame_buffer);
|
||||
|
||||
//printf("frame_count %d, expected frame len %d, bytes in frame %d \n", frame_count, OI_CODEC_SBC_CalculateFramelen(&bd_decoder_state->decoder_context.common.frameInfo), bytes_in_buffer_before);
|
||||
switch(status){
|
||||
case 0:
|
||||
// printf("OK: \n");
|
||||
if (state->mode == SBC_MODE_mSBC){
|
||||
printf("%d : OK\n", bd_decoder_state->h2_syncword);
|
||||
bd_decoder_state->search_new_sync_word = 1;
|
||||
bd_decoder_state->sync_word_found = 0;
|
||||
} else {
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
if (bd_decoder_state->h2_syncword == 3) printf("\n");
|
||||
sbc_plc_good_frame(&state->plc_state, bd_decoder_state->pcm_plc_data, bd_decoder_state->pcm_data);
|
||||
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);
|
||||
|
||||
|
||||
continue;
|
||||
case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
|
||||
case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
|
||||
// printf("NOT_ENOUGH_DATA: \n");
|
||||
// printf(" NOT_ENOUGH_DATA\n");
|
||||
if (bd_decoder_state->sync_word_found){
|
||||
bd_decoder_state->search_new_sync_word = 0;
|
||||
}
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
case OI_CODEC_SBC_NO_SYNCWORD:
|
||||
case OI_CODEC_SBC_CHECKSUM_MISMATCH:
|
||||
// printf("NO_SYNCWORD or CHECKSUM_MISMATCH\n");
|
||||
bd_decoder_state->bytes_in_frame_buffer = 0;
|
||||
if (state->mode == SBC_MODE_mSBC){
|
||||
bd_decoder_state->h2_syncword = (bd_decoder_state->h2_syncword +1)%4;
|
||||
printf("%d : BAD FRAME\n", bd_decoder_state->h2_syncword);
|
||||
if (bd_decoder_state->h2_syncword == 3) printf("\n");
|
||||
bd_decoder_state->search_new_sync_word = 1;
|
||||
bd_decoder_state->sync_word_found = 0;
|
||||
} else {
|
||||
printf("BAD FRAME\n");
|
||||
}
|
||||
|
||||
bd_decoder_state->bytes_in_frame_buffer = 0;
|
||||
if (!plc_enabled) break;
|
||||
|
||||
frame_data = sbc_plc_zero_signal_frame();
|
||||
OI_UINT32 bytes_in_frame_buffer = msbc_frame_size;
|
||||
|
||||
@ -216,12 +309,15 @@ void sbc_decoder_process_data(sbc_decoder_state_t * state, uint8_t * buffer, int
|
||||
sbc_decoder_num_samples_per_frame(state),
|
||||
sbc_decoder_num_channels(state),
|
||||
sbc_decoder_sample_rate(state), state->context);
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
printf("Frame decode error: %d\n", status);
|
||||
break;
|
||||
}
|
||||
|
||||
memmove(bd_decoder_state->frame_buffer, bd_decoder_state->frame_buffer + bytes_processed, bd_decoder_state->bytes_in_frame_buffer);
|
||||
}
|
||||
// printf ("<<-- exit -->>\n");
|
||||
}
|
||||
|
@ -143,16 +143,36 @@ int main (int argc, const char * argv[]){
|
||||
|
||||
sbc_mode_t mode = SBC_MODE_STANDARD;
|
||||
|
||||
const char * sbc_filename = argv[1];
|
||||
const char * wav_filename = argv[2];
|
||||
const char * filename = argv[1];
|
||||
|
||||
char sbc_filename[30];
|
||||
char wav_filename[30];
|
||||
|
||||
strcpy(sbc_filename, filename);
|
||||
strcpy(wav_filename, filename);
|
||||
|
||||
const int plc_enabled = atoi(argv[3]);
|
||||
const int corrupt_frame_period = atoi(argv[4]);
|
||||
|
||||
if (strncmp(argv[3], "msbc", 4) == 0 ){
|
||||
if (strncmp(argv[2], "msbc", 4) == 0 ){
|
||||
mode = SBC_MODE_mSBC;
|
||||
printf("Using SBC_MODE_mSBC mode\n");
|
||||
printf("Using SBC_MODE_mSBC mode, plc enabled = %d\n", plc_enabled);
|
||||
} else {
|
||||
printf("Using SBC_MODE_STANDARD mode\n");
|
||||
printf("Using SBC_MODE_STANDARD mode, plc enabled = %d\n", plc_enabled);
|
||||
}
|
||||
|
||||
if (mode == SBC_MODE_mSBC){
|
||||
strcat(sbc_filename, ".msbc");
|
||||
} else {
|
||||
strcat(sbc_filename, ".sbc");
|
||||
}
|
||||
|
||||
|
||||
if (plc_enabled){
|
||||
strcat(wav_filename, "_plc.wav");
|
||||
} else {
|
||||
strcat(wav_filename, ".wav");
|
||||
}
|
||||
|
||||
int fd = open(sbc_filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Can't open file %s", sbc_filename);
|
||||
@ -167,8 +187,15 @@ int main (int argc, const char * argv[]){
|
||||
|
||||
sbc_decoder_state_t state;
|
||||
sbc_decoder_init(&state, mode, &handle_pcm_data, (void*)&wav_writer_state);
|
||||
write_wav_header(wav_writer_state.wav_file, 0, 0, 0);
|
||||
if (!plc_enabled){
|
||||
sbc_decoder_test_disable_plc();
|
||||
}
|
||||
if (corrupt_frame_period > 0){
|
||||
sbc_decoder_test_simulate_corrupt_frames(corrupt_frame_period);
|
||||
}
|
||||
|
||||
write_wav_header(wav_writer_state.wav_file, 0, 0, 0);
|
||||
|
||||
while (1){
|
||||
// get next chunk
|
||||
int bytes_read = __read(fd, read_buffer, sizeof(read_buffer));
|
||||
|
Loading…
x
Reference in New Issue
Block a user