coder.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. *****************************************************************************
  3. *
  4. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  5. * R99 Version 3.3.0
  6. * REL-4 Version 4.1.0
  7. *
  8. *****************************************************************************
  9. *
  10. * File : coder.c
  11. * Purpose : Speech encoder main program.
  12. *
  13. *****************************************************************************
  14. *
  15. * Usage : coder speech_file bitstream_file
  16. *
  17. * Format for speech_file:
  18. * Speech is read from a binary file of 16 bits data.
  19. *
  20. * Format for bitstream_file:
  21. * 1 word (2-byte) for the TX frame type
  22. * (see frame.h for possible values)
  23. * 244 words (2-byte) containing 244 bits.
  24. * Bit 0 = 0x0000 and Bit 1 = 0x0001
  25. * 1 word (2-byte) for the mode indication
  26. * (see mode.h for possible values)
  27. * 4 words for future use, currently written as zero
  28. *
  29. *****************************************************************************
  30. */
  31. /*
  32. *****************************************************************************
  33. * INCLUDE FILES
  34. *****************************************************************************
  35. */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <errno.h>
  40. #include "typedef.h"
  41. #include "cnst.h"
  42. #include "n_proc.h"
  43. #include "mode.h"
  44. #include "frame.h"
  45. #include "strfunc.h"
  46. #include "sp_enc.h"
  47. #include "pre_proc.h"
  48. #include "sid_sync.h"
  49. #include "vadname.h"
  50. #include "e_homing.h"
  51. #ifdef MMS_IO
  52. #define AMR_MAGIC_NUMBER "#!AMR\n"
  53. #define MAX_PACKED_SIZE (MAX_SERIAL_SIZE / 8 + 2)
  54. #endif
  55. const char coder_id[] = "@(#)$Id $";
  56. /* frame size in serial bitstream file (frame type + serial stream + flags) */
  57. #define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5)
  58. /*
  59. *****************************************************************************
  60. * LOCAL PROGRAM CODE
  61. *****************************************************************************
  62. */
  63. /*
  64. * read_mode read next mode from mode file
  65. *
  66. * return 0 on success, EOF on end of file, 1 on other error
  67. */
  68. int read_mode(FILE *file_modes, enum Mode *mode)
  69. {
  70. char buf[10];
  71. if (fscanf(file_modes, "%9s\n", buf) != 1) {
  72. if (feof(file_modes))
  73. return EOF;
  74. wfprintf(stderr, "\nerror reading mode control file: %s\n",
  75. strerror(errno));
  76. return 1;
  77. }
  78. if (str2mode(buf, mode) != 0 || *mode == MRDTX) {
  79. wfprintf(stderr, "\ninvalid amr_mode found in mode control file: '%s'\n",
  80. buf);
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. /*
  86. *****************************************************************************
  87. * MAIN PROGRAM
  88. *****************************************************************************
  89. */
  90. int main (int argc, char *argv[])
  91. {
  92. char *progname = argv[0];
  93. char *modeStr = NULL;
  94. char *usedModeStr = NULL;
  95. char *fileName = NULL;
  96. char *modefileName = NULL;
  97. char *serialFileName = NULL;
  98. FILE *file_speech = NULL; /* File of speech data */
  99. FILE *file_serial = NULL; /* File of coded bits */
  100. FILE *file_modes = NULL; /* File with mode information */
  101. Word16 new_speech[L_FRAME]; /* Pointer to new speech data */
  102. Word16 serial[SERIAL_FRAMESIZE]; /* Output bitstream buffer */
  103. #ifdef MMS_IO
  104. UWord8 packed_bits[MAX_PACKED_SIZE];
  105. Word16 packed_size;
  106. #endif
  107. Word32 frame;
  108. Word16 dtx = 0; /* enable encoder DTX */
  109. /* changed eedodr */
  110. Word16 reset_flag;
  111. int i;
  112. enum Mode mode;
  113. enum Mode used_mode;
  114. enum TXFrameType tx_type;
  115. int useModeFile = 0;
  116. Speech_Encode_FrameState *speech_encoder_state = NULL;
  117. sid_syncState *sid_state = NULL;
  118. proc_head ("Encoder");
  119. wfprintf(stderr, "Code compiled with VAD option: %s\n\n", get_vadname());
  120. /*----------------------------------------------------------------------*
  121. * Process command line options *
  122. *----------------------------------------------------------------------*/
  123. while (argc > 1) {
  124. if (strcmp(argv[1], "-dtx") == 0) {
  125. dtx = 1;
  126. } else if (strncmp(argv[1], "-modefile=", 10) == 0) {
  127. useModeFile = 1;
  128. modefileName = argv[1]+10;
  129. } else
  130. break;
  131. argc--;
  132. argv++;
  133. }
  134. /*----------------------------------------------------------------------*
  135. * Check number of arguments *
  136. *----------------------------------------------------------------------*/
  137. if ( (argc != 4 && !useModeFile)
  138. || (argc != 3 && useModeFile))
  139. {
  140. wfprintf (stderr,
  141. " Usage:\n\n"
  142. " %s [-dtx] amr_mode speech_file bitstream_file\n\n"
  143. " or \n\n"
  144. " %s [-dtx] -modefile=mode_file speech_file bitstream_file\n\n"
  145. " -dtx enables DTX mode\n"
  146. " -modefile=mode_file reads AMR modes from text file (one line per frame)\n\n",
  147. progname, progname);
  148. exit (1);
  149. }
  150. /*----------------------------------------------------------------------*
  151. * Open mode file or convert mode string *
  152. *----------------------------------------------------------------------*/
  153. if (useModeFile) {
  154. fileName = argv[1];
  155. serialFileName = argv[2];
  156. /* Open mode control file */
  157. if (strcmp(modefileName, "-") == 0) {
  158. file_modes = stdin;
  159. }
  160. else if ((file_modes = fopen (modefileName, "rt")) == NULL)
  161. {
  162. wfprintf (stderr, "Error opening mode control file %s !!\n",
  163. modefileName);
  164. exit (1);
  165. }
  166. wfprintf (stderr, " Mode control file: %s\n", modefileName);
  167. } else {
  168. modeStr = argv[1];
  169. fileName = argv[2];
  170. serialFileName = argv[3];
  171. /* check and convert mode string */
  172. if (str2mode(modeStr, &mode) != 0 && mode != MRDTX) {
  173. wfprintf(stderr, "Invalid amr_mode specified: '%s'\n",
  174. modeStr);
  175. exit(1);
  176. }
  177. }
  178. /*----------------------------------------------------------------------*
  179. * Open speech file and result file (output serial bit stream) *
  180. *----------------------------------------------------------------------*/
  181. if (strcmp(fileName, "-") == 0) {
  182. file_speech = stdin;
  183. }
  184. else if ((file_speech = fopen (fileName, "rb")) == NULL)
  185. {
  186. wfprintf (stderr, "Error opening input file %s !!\n", fileName);
  187. exit (1);
  188. }
  189. wfprintf (stderr, " Input speech file: %s\n", fileName);
  190. if (strcmp(serialFileName, "-") == 0) {
  191. file_serial = stdout;
  192. }
  193. else if ((file_serial = fopen (serialFileName, "wb")) == NULL)
  194. {
  195. wfprintf (stderr,"Error opening output bitstream file %s !!\n",serialFileName);
  196. exit (1);
  197. }
  198. wfprintf (stderr, " Output bitstream file: %s\n", serialFileName);
  199. /*-----------------------------------------------------------------------*
  200. * Initialisation of the coder. *
  201. *-----------------------------------------------------------------------*/
  202. if ( Speech_Encode_Frame_init(&speech_encoder_state, dtx, "encoder")
  203. || sid_sync_init (&sid_state))
  204. exit(-1);
  205. #ifdef MMS_IO
  206. /* write magic number to indicate single channel AMR file storage format */
  207. fwrite(AMR_MAGIC_NUMBER, sizeof(UWord8), strlen(AMR_MAGIC_NUMBER), file_serial);
  208. #endif
  209. /*-----------------------------------------------------------------------*
  210. * Process speech frame by frame *
  211. *-----------------------------------------------------------------------*/
  212. frame = 0;
  213. while (fread (new_speech, sizeof (Word16), L_FRAME, file_speech) == L_FRAME)
  214. {
  215. /* read new mode string from file if required */
  216. if (useModeFile) {
  217. int res;
  218. if ((res = read_mode(file_modes, &mode)) == EOF) {
  219. wfprintf(stderr, "\nend of mode control file reached");
  220. break;
  221. } else if (res == 1)
  222. exit(-1);
  223. }
  224. frame++;
  225. /* zero flags and parameter bits */
  226. for (i = 0; i < SERIAL_FRAMESIZE; i++)
  227. serial[i] = 0;
  228. /* check for homing frame */
  229. reset_flag = encoder_homing_frame_test(new_speech);
  230. /* encode speech */
  231. Speech_Encode_Frame(speech_encoder_state, mode,
  232. new_speech, &serial[1], &used_mode);
  233. /* print frame number and mode information */
  234. mode2str(mode, &modeStr);
  235. mode2str(used_mode, &usedModeStr);
  236. if ( (frame%50) == 0) {
  237. wfprintf (stderr, "\rframe=%-8d mode=%-5s used_mode=%-5s",
  238. frame, modeStr, usedModeStr);
  239. }
  240. /* include frame type and mode information in serial bitstream */
  241. sid_sync (sid_state, used_mode, &tx_type);
  242. #ifndef MMS_IO
  243. serial[0] = tx_type;
  244. if (tx_type != TX_NO_DATA) {
  245. serial[1+MAX_SERIAL_SIZE] = mode;
  246. }
  247. else {
  248. serial[1+MAX_SERIAL_SIZE] = -1;
  249. }
  250. /* write bitstream to output file */
  251. if (fwrite (serial, sizeof (Word16), SERIAL_FRAMESIZE, file_serial)
  252. != SERIAL_FRAMESIZE) {
  253. wfprintf(stderr, "\nerror writing output file: %s\n",
  254. strerror(errno));
  255. exit(-1);
  256. }
  257. #else
  258. packed_size = PackBits(used_mode, mode, tx_type, &serial[1], packed_bits);
  259. /* write file storage format bitstream to output file */
  260. if (fwrite (packed_bits, sizeof (UWord8), packed_size, file_serial)
  261. != packed_size) {
  262. wfprintf(stderr, "\nerror writing output file: %s\n",
  263. strerror(errno));
  264. exit(-1);
  265. }
  266. #endif
  267. fflush(file_serial);
  268. /* perform homing if homing frame was detected at encoder input */
  269. if (reset_flag != 0)
  270. {
  271. Speech_Encode_Frame_reset(speech_encoder_state);
  272. sid_sync_reset(sid_state);
  273. }
  274. }
  275. wfprintf (stderr, "\n%d frame(s) processed\n", frame);
  276. /*-----------------------------------------------------------------------*
  277. * Close down speech coder *
  278. *-----------------------------------------------------------------------*/
  279. Speech_Encode_Frame_exit(&speech_encoder_state);
  280. sid_sync_exit (&sid_state);
  281. return (0);
  282. }