FreeCalypso > hg > efr-experiments
view src/decoder.c @ 2:c511bfb36c2a
beginning of EFR2 decoder, using AMR version of AGC module
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 03 Apr 2024 05:47:51 +0000 |
parents | 56410792419a |
children | 799b56cbccb6 |
line wrap: on
line source
/*************************************************************************** * * FILE NAME: decoder.c * * Usage : decoder bitstream_file synth_file * * Format for bitstream_file: * One word (2-byte) for bad frame indication (BFI) flag bit * 0x0000 -> good frame; 0x0001 -> bad frame * 244 words (2-byte) containing 244 bits. * Bit 0 = 0x0000 and Bit 1 = 0x0001 * One word (2-byte) for ternary Silence Descriptor (SID) flag * 0x0000 -> inactive (no detected speech activity); * 0x0001 -> active * One word (2-byte) for Time Alignment Flag (TAF) bit * 0x0000 -> inactive (no transmission of speech frames); * 0x0001 -> active * * Format for synth_file: * Synthesis is written to a binary file of 16 bits data. * ***************************************************************************/ #include <stdio.h> #include <stdlib.h> #include "typedef.h" #include "n_stack.h" #include "basic_op.h" #include "sig_proc.h" #include "count.h" #include "codec.h" #include "cnst.h" #include "d_homing.h" /* These constants define the number of consecutive parameters that function decoder_homing_frame_test() checks */ #define WHOLE_FRAME 57 #define TO_FIRST_SUBFRAME 18 Word16 synth_buf[L_FRAME + M]; /* L_FRAME, M, PRM_SIZE, AZ_SIZE, SERIAL_SIZE: defined in "cnst.h" */ /*-----------------------------------------------------------------* * Global variables * *-----------------------------------------------------------------*/ #if (WMOPS) Word16 dtx_mode = 0; #endif /*-----------------------------------------------------------------* * Main decoder routine * *-----------------------------------------------------------------*/ int main (int argc, char *argv[]) { Word16 *synth; /* Synthesis */ Word16 parm[PRM_SIZE + 1]; /* Synthesis parameters */ Word16 serial[SERIAL_SIZE+2];/* Serial stream */ Word16 Az_dec[AZ_SIZE]; /* Decoded Az for post-filter */ /* in 4 subframes, length= 44 */ Word16 i, frame, temp; FILE *f_syn, *f_serial; Word16 TAF, SID_flag; Word16 reset_flag; static Word16 reset_flag_old = 1; proc_head ("Decoder"); /*-----------------------------------------------------------------* * Read passed arguments and open in/out files * *-----------------------------------------------------------------*/ if (argc != 3) { fprintf (stderr, " Usage:\n\n decoder bitstream_file synth_file\n"); fprintf (stderr, "\n"); exit (1); } /* Open file for synthesis and packed serial stream */ if ((f_serial = fopen (argv[1], "rb")) == NULL) { fprintf (stderr, "Input file '%s' does not exist !!\n", argv[1]); exit (0); } else fprintf (stderr, "Input bitstream file: %s\n", argv[1]); if ((f_syn = fopen (argv[2], "wb")) == NULL) { fprintf (stderr, "Cannot open file '%s' !!\n", argv[2]); exit (0); } else fprintf (stderr, "Synthesis speech file: %s\n", argv[2]); /*-----------------------------------------------------------------* * Initialization of decoder * *-----------------------------------------------------------------*/ synth = synth_buf + M; reset_dec (); /* Bring the decoder and receive DTX to the initial state */ #if (WMOPS) Init_WMOPS_counter (); #endif /*-----------------------------------------------------------------* * Loop for each "L_FRAME" speech data * *-----------------------------------------------------------------*/ frame = 0; while (fread (serial, sizeof (Word16), 247, f_serial) == 247) { #if (WMOPS) fprintf (stderr, "frame=%d ", ++frame); #else fprintf (stderr, "\nframe=%d ", ++frame); #endif #if (WMOPS) Reset_WMOPS_counter (); /* reset WMOPS counter for the new frame */ #endif SID_flag = serial[245]; /* Receive SID flag */ TAF = serial[246]; /* Receive TAF flag */ Bits2prm_12k2 (serial, parm); /* serial to parameters */ #if (WMOPS) fwc (); /* function worst case */ #endif if (parm[0] == 0) /* BFI == 0, perform DHF check */ { if (reset_flag_old == 1) /* Check for second and further successive DHF (to first subfr.) */ { reset_flag = decoder_homing_frame_test (&parm[1], TO_FIRST_SUBFRAME); } else { reset_flag = 0; } } else /* BFI==1, bypass DHF check (frame is taken as not being a DHF) */ { reset_flag = 0; } if ((reset_flag != 0) && (reset_flag_old != 0)) { /* Force the output to be the encoder homing frame pattern */ for (i = 0; i < L_FRAME; i++) { synth[i] = EHF_MASK; } } else { Decoder_12k2 (parm, synth, Az_dec, TAF, SID_flag);/* Synthesis */ Post_Filter (synth, Az_dec); /* Post-filter */ #if (WMOPS) fwc (); /* function worst case */ #endif for (i = 0; i < L_FRAME; i++) /* Upscale the 15 bit linear PCM to 16 bits, then truncate to 13 bits */ { temp = shl (synth[i], 1); synth[i] = temp & 0xfff8; logic16 (); move16 (); } #if (WMOPS) fwc (); /* function worst case */ #endif #if (WMOPS) WMOPS_output (dtx_mode);/* output WMOPS values for current frame */ #endif } /* else */ fwrite (synth, sizeof (Word16), L_FRAME, f_syn); /* BFI == 0, perform check for first DHF (whole frame) */ if ((parm[0] == 0) && (reset_flag_old == 0)) { reset_flag = decoder_homing_frame_test (&parm[1], WHOLE_FRAME); } if (reset_flag != 0) { /* Bring the decoder and receive DTX to the home state */ reset_dec (); } reset_flag_old = reset_flag; } /* while */ return 0; }