wav_amr.mm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #import "wav_amr.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdint.h>
  6. #include "interf_enc.h"
  7. #include "interf_dec.h"
  8. #include "wavreader.h"
  9. #include "wavwriter.h"
  10. const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };
  11. int decode_amr(const char* infile, NSMutableData *outData) {
  12. FILE* in = fopen(infile, "rb");
  13. if (!in) {
  14. return 1;
  15. }
  16. char header[6];
  17. ssize_t n = fread(header, 1, 6, in);
  18. if (n != 6 || memcmp(header, "#!AMR\n", 6)) {
  19. fprintf(stderr, "Bad header\n");
  20. return 1;
  21. }
  22. NSMutableData *body = [[NSMutableData alloc] init];
  23. void* wav = wav_write_open(outData, body, 8000, 16, 1);
  24. void* amr = Decoder_Interface_init();
  25. while (1) {
  26. uint8_t buffer[500];
  27. /* Read the mode byte */
  28. n = fread(buffer, 1, 1, in);
  29. if (n <= 0)
  30. break;
  31. /* Find the packet size */
  32. int size = sizes[(buffer[0] >> 3) & 0x0f];
  33. if (size <= 0)
  34. continue;
  35. n = fread(buffer + 1, 1, size, in);
  36. if (n != size)
  37. break;
  38. /* Decode the packet */
  39. int16_t outbuffer[160];
  40. Decoder_Interface_Decode(amr, buffer, outbuffer, 0);
  41. /* Convert to little endian and write to wav */
  42. uint8_t littleendian[320];
  43. uint8_t* ptr = littleendian;
  44. for (int i = 0; i < 160; i++) {
  45. *ptr++ = (outbuffer[i] >> 0) & 0xff;
  46. *ptr++ = (outbuffer[i] >> 8) & 0xff;
  47. }
  48. wav_write_data(wav, littleendian, 320);
  49. }
  50. fclose(in);
  51. Decoder_Interface_exit(amr);
  52. wav_write_close(wav);
  53. [outData appendData:body];
  54. return 0;
  55. }
  56. int encode_amr(const char* infile, const char* outfile) {
  57. enum Mode mode = MR122;
  58. FILE *out;
  59. void *wav, *amr;
  60. int format, sampleRate, channels, bitsPerSample;
  61. int inputSize;
  62. uint8_t* inputBuf;
  63. wav = wav_read_open(infile);
  64. if (!wav) {
  65. fprintf(stderr, "Unable to open wav file %s\n", infile);
  66. return 1;
  67. }
  68. if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
  69. fprintf(stderr, "Bad wav file %s\n", infile);
  70. return 1;
  71. }
  72. if (format != 1) {
  73. fprintf(stderr, "Unsupported WAV format %d\n", format);
  74. return 1;
  75. }
  76. if (bitsPerSample != 16) {
  77. fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample);
  78. return 1;
  79. }
  80. if (channels != 1)
  81. fprintf(stderr, "Warning, only compressing one audio channel\n");
  82. if (sampleRate != 8000)
  83. fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate);
  84. inputSize = channels*2*160;
  85. inputBuf = (uint8_t*) malloc(inputSize);
  86. amr = Encoder_Interface_init(0);
  87. out = fopen(outfile, "wb");
  88. if (!out) {
  89. perror(outfile);
  90. return 1;
  91. }
  92. fwrite("#!AMR\n", 1, 6, out);
  93. while (1) {
  94. short buf[160];
  95. uint8_t outbuf[500];
  96. int read, i, n;
  97. read = wav_read_data(wav, inputBuf, inputSize);
  98. read /= channels;
  99. read /= 2;
  100. if (read < 160)
  101. break;
  102. for (i = 0; i < 160; i++) {
  103. const uint8_t* in = &inputBuf[2*channels*i];
  104. buf[i] = in[0] | (in[1] << 8);
  105. }
  106. n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0);
  107. fwrite(outbuf, 1, n, out);
  108. }
  109. free(inputBuf);
  110. fclose(out);
  111. Encoder_Interface_exit(amr);
  112. wav_read_close(wav);
  113. return 0;
  114. }