ref: b03e0534d7d2ab306b584296bf0af011db85bf55
dir: /amr-wb/bits.c/
/*------------------------------------------------------------------------* * BITS.C * *------------------------------------------------------------------------* * Performs bit stream manipulation * *------------------------------------------------------------------------*/ #include <stdlib.h> #include <stdio.h> #include "typedef.h" #include "basic_op.h" #include "cnst.h" #include "bits.h" #include "acelp.h" #include "count.h" #include "dtx.h" #include "mime_io.tab" /*-----------------------------------------------------* * Write_serial -> write serial stream into a file * *-----------------------------------------------------*/ Word16 Init_write_serial(TX_State ** st) { TX_State *s; /* allocate memory */ test(); if ((s = (TX_State *) malloc(sizeof(TX_State))) == NULL) { fprintf(stderr, "write_serial_init: can not malloc state structure\n"); return -1; } Reset_write_serial(s); *st = s; return 0; } Word16 Close_write_serial(TX_State *st) { /* allocate memory */ test(); if (st != NULL) { free(st); st = NULL; return 0; } return 1; } void Reset_write_serial(TX_State * st) { st->sid_update_counter = 3; st->sid_handover_debt = 0; st->prev_ft = TX_SPEECH; } void Write_serial(FILE * fp, Word16 prms[], int coding_mode, int mode, TX_State *st, int bitstreamformat) { Word16 i, frame_type; Word16 stream[AMR_WB_SIZE_MAX]; UWord8 temp; UWord8 *stream_ptr; if (coding_mode == MRDTX) { st->sid_update_counter--; if (st->prev_ft == TX_SPEECH) { frame_type = TX_SID_FIRST; st->sid_update_counter = 3; } else { if ((st->sid_handover_debt > 0) && (st->sid_update_counter > 2)) { /* ensure extra updates are properly delayed after a possible SID_FIRST */ frame_type = TX_SID_UPDATE; st->sid_handover_debt--; } else { if (st->sid_update_counter == 0) { frame_type = TX_SID_UPDATE; st->sid_update_counter = 8; } else { frame_type = TX_NO_DATA; } } } } else { st->sid_update_counter = 8; frame_type = TX_SPEECH; } st->prev_ft = frame_type; if(bitstreamformat == 0) /* default file format */ { stream[0] = TX_FRAME_TYPE; stream[1] = frame_type; stream[2] = mode; for (i = 0; i < nb_of_bits[coding_mode]; i++) { stream[3 + i] = prms[i]; } fwrite(stream, sizeof(Word16), 3 + nb_of_bits[coding_mode], fp); } else { if (bitstreamformat == 1) /* ITU file format */ { stream[0] = 0x6b21; if(frame_type != TX_NO_DATA && frame_type != TX_SID_FIRST) { stream[1]=nb_of_bits[coding_mode]; for (i = 0; i < nb_of_bits[coding_mode]; i++) { if(prms[i] == BIT_0){ stream[2 + i] = BIT_0_ITU; } else{ stream[2 + i] = BIT_1_ITU; } } fwrite(stream, sizeof(Word16), 2 + nb_of_bits[coding_mode], fp); } else { stream[1] = 0; fwrite(stream, sizeof(Word16), 2, fp); } } else /* MIME/storage file format */ { #define MRSID 9 /* change mode index in case of SID frame */ if (coding_mode == MRDTX) { coding_mode = MRSID; if (frame_type == TX_SID_FIRST) { for (i = 0; i < NBBITS_SID; i++) prms[i] = BIT_0; } } /* we cannot handle unspecified frame types (modes 10 - 13) */ /* -> force NO_DATA frame */ if (coding_mode < 0 || coding_mode > 15 || (coding_mode > MRSID && coding_mode < 14)) { coding_mode = 15; } /* mark empty frames between SID updates as NO_DATA frames */ if (coding_mode == MRSID && frame_type == TX_NO_DATA) { coding_mode = 15; } /* set pointer for packed frame, note that we handle data as bytes */ stream_ptr = (UWord8*)stream; /* insert table of contents (ToC) byte at the beginning of the packet */ *stream_ptr = toc_byte[coding_mode]; stream_ptr++; temp = 0; /* sort and pack AMR-WB speech or SID bits */ for (i = 1; i < unpacked_size[coding_mode] + 1; i++) { if (prms[sort_ptr[coding_mode][i-1]] == BIT_1) { temp++; } if (i % 8) { temp <<= 1; } else { *stream_ptr = temp; stream_ptr++; temp = 0; } } /* insert SID type indication and speech mode in case of SID frame */ if (coding_mode == MRSID) { if (frame_type == TX_SID_UPDATE) { temp++; } temp <<= 4; temp += mode & 0x000F; } /* insert unused bits (zeros) at the tail of the last byte */ if (unused_size[coding_mode]) { temp <<= (unused_size[coding_mode] - 1); } *stream_ptr = temp; /* write packed frame into file (1 byte added to cover ToC entry) */ fwrite(stream, sizeof(UWord8), 1 + packed_size[coding_mode], fp); } } return; } /*-----------------------------------------------------* * Read_serial -> read serial stream into a file * *-----------------------------------------------------*/ Word16 Init_read_serial(RX_State ** st) { RX_State *s; /* allocate memory */ test(); if ((s = (RX_State *) malloc(sizeof(RX_State))) == NULL) { fprintf(stderr, "read_serial_init: can not malloc state structure\n"); return -1; } Reset_read_serial(s); *st = s; return 0; } Word16 Close_read_serial(RX_State *st) { /* allocate memory */ test(); if (st != NULL) { free(st); st = NULL; return 0; } return 1; } void Reset_read_serial(RX_State * st) { st->prev_ft = RX_SPEECH_GOOD; st->prev_mode = 0; } Word16 Read_serial(FILE * fp, Word16 prms[], Word16 * frame_type, Word16 * mode, RX_State *st, int bitstreamformat) { Word16 n, n1, type_of_frame_type, coding_mode, datalen, i; UWord8 toc, q, temp, *packet_ptr, packet[64]; if(bitstreamformat == 0) /* default file format */ { n = (Word16) fread(&type_of_frame_type, sizeof(Word16), 1, fp); n = (Word16) (n + fread(frame_type, sizeof(Word16), 1, fp)); n = (Word16) (n + fread(mode, sizeof(Word16), 1, fp)); coding_mode = *mode; if(*mode < 0 || *mode > NUM_OF_MODES-1) { fprintf(stderr, "Invalid mode received: %d (check file format).\n", *mode); exit(-1); } if (n == 3) { if (type_of_frame_type == TX_FRAME_TYPE) { switch (*frame_type) { case TX_SPEECH: *frame_type = RX_SPEECH_GOOD; break; case TX_SID_FIRST: *frame_type = RX_SID_FIRST; break; case TX_SID_UPDATE: *frame_type = RX_SID_UPDATE; break; case TX_NO_DATA: *frame_type = RX_NO_DATA; break; } } else if (type_of_frame_type != RX_FRAME_TYPE) { fprintf(stderr, "Wrong type of frame type:%d.\n", type_of_frame_type); } if ((*frame_type == RX_SID_FIRST) | (*frame_type == RX_SID_UPDATE) | (*frame_type == RX_NO_DATA) | (*frame_type == RX_SID_BAD)) { coding_mode = MRDTX; } n = (Word16) fread(prms, sizeof(Word16), nb_of_bits[coding_mode], fp); if (n != nb_of_bits[coding_mode]) n = 0; } return (n); } else { if (bitstreamformat == 1) /* ITU file format */ { n = (Word16) fread(&type_of_frame_type, sizeof(Word16), 1, fp); n = (Word16)(n+fread(&datalen, sizeof(Word16), 1, fp)); if(n == 2) { if(type_of_frame_type == 0x6b20) /* bad frame */ { *frame_type = RX_SPEECH_LOST; *mode = st->prev_mode; } else if(type_of_frame_type == 0x6b21) /* good frame */ { if(datalen == 0) /* RX_NO_DATA frame type */ { if(st->prev_ft == RX_SPEECH_GOOD) { *frame_type = RX_SID_FIRST; } else { *frame_type = RX_NO_DATA; } *mode = st->prev_mode; } else { coding_mode = -1; for(i=NUM_OF_MODES-1; i>=0; i--) { if(datalen == nb_of_bits[i]) { coding_mode = i; } } if(coding_mode == -1) { fprintf(stderr, "\n\n ERROR: Invalid number of data bits received [%d]\n\n", datalen); exit(-1); } if(coding_mode == NUM_OF_MODES-1) /* DTX frame type */ { *frame_type = RX_SID_UPDATE; *mode = st->prev_mode; } else { *frame_type = RX_SPEECH_GOOD; *mode = coding_mode; } } st->prev_mode = *mode; st->prev_ft = *frame_type; } else { fprintf(stderr, "\n\n ERROR: Invalid ITU file format \n\n"); exit(-1); } } n1 = fread(prms, sizeof(Word16), datalen, fp); n += n1; for(i=0; i<n1; i++) { if(prms[i] <= BIT_0_ITU) prms[i] = BIT_0; else prms[i] = BIT_1; } return(n); } else /* MIME/storage file format */ { /* read ToC byte, return immediately if no more data available */ if (fread(&toc, sizeof(UWord8), 1, fp) == 0) { return 0; } /* extract q and mode from ToC */ q = (toc >> 2) & 0x01; *mode = (toc >> 3) & 0x0F; /* read speech bits, return with empty frame if mismatch between mode info and available data */ if ((Word16)fread(packet, sizeof(UWord8), packed_size[*mode], fp) != packed_size[*mode]) { return 0; } packet_ptr = (UWord8*)packet; temp = *packet_ptr; packet_ptr++; /* unpack and unsort speech or SID bits */ for (i = 1; i < unpacked_size[*mode] + 1; i++) { if (temp & 0x80) prms[sort_ptr[*mode][i-1]] = BIT_1; else prms[sort_ptr[*mode][i-1]] = BIT_0; if (i % 8) { temp <<= 1; } else { temp = *packet_ptr; packet_ptr++; } } /* set frame type */ switch (*mode) { case MODE_7k: case MODE_9k: case MODE_12k: case MODE_14k: case MODE_16k: case MODE_18k: case MODE_20k: case MODE_23k: case MODE_24k: if (q) *frame_type = RX_SPEECH_GOOD; else *frame_type = RX_SPEECH_BAD; break; case MRSID: if (q) { if (temp & 0x80) *frame_type = RX_SID_UPDATE; else *frame_type = RX_SID_FIRST; } else { *frame_type = RX_SID_BAD; } /* read speech mode indication */ coding_mode = (temp >> 3) & 0x0F; /* set mode index */ *mode = st->prev_mode; break; case 14: /* SPEECH_LOST */ *frame_type = RX_SPEECH_LOST; *mode = st->prev_mode; break; case 15: /* NO_DATA */ *frame_type = RX_NO_DATA; *mode = st->prev_mode; break; default: /* replace frame with unused mode index by NO_DATA frame */ *frame_type = RX_NO_DATA; *mode = st->prev_mode; break; } st->prev_mode = *mode; /* return 1 to indicate succesfully parsed frame */ return 1; } #undef MRSID } } /*-----------------------------------------------------* * Parm_serial -> convert parameters to serial stream * *-----------------------------------------------------*/ void Parm_serial( Word16 value, /* input : parameter value */ Word16 no_of_bits, /* input : number of bits */ Word16 ** prms ) { Word16 i, bit; *prms += no_of_bits; move16(); for (i = 0; i < no_of_bits; i++) { bit = (Word16) (value & 0x0001); logic16(); /* get lsb */ test();move16(); if (bit == 0) *--(*prms) = BIT_0; else *--(*prms) = BIT_1; value = shr(value, 1); move16(); } *prms += no_of_bits; move16(); return; } /*----------------------------------------------------* * Serial_parm -> convert serial stream to parameters * *----------------------------------------------------*/ Word16 Serial_parm( /* Return the parameter */ Word16 no_of_bits, /* input : number of bits */ Word16 ** prms ) { Word16 value, i; Word16 bit; value = 0; move16(); for (i = 0; i < no_of_bits; i++) { value = shl(value, 1); bit = *((*prms)++); move16(); test();move16(); if (bit == BIT_1) value = add(value, 1); } return (value); }