123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #import "wav_amr.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #include "interf_enc.h"
- #include "interf_dec.h"
- #include "wavreader.h"
- #include "wavwriter.h"
- const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };
- int decode_amr(const char* infile, NSMutableData *outData) {
- FILE* in = fopen(infile, "rb");
- if (!in) {
- return 1;
- }
- char header[6];
- ssize_t n = fread(header, 1, 6, in);
- if (n != 6 || memcmp(header, "#!AMR\n", 6)) {
- fprintf(stderr, "Bad header\n");
- return 1;
- }
- NSMutableData *body = [[NSMutableData alloc] init];
- void* wav = wav_write_open(outData, body, 8000, 16, 1);
- void* amr = Decoder_Interface_init();
- while (1) {
- uint8_t buffer[500];
- /* Read the mode byte */
- n = fread(buffer, 1, 1, in);
- if (n <= 0)
- break;
- /* Find the packet size */
- int size = sizes[(buffer[0] >> 3) & 0x0f];
- if (size <= 0)
- continue;
- n = fread(buffer + 1, 1, size, in);
- if (n != size)
- break;
- /* Decode the packet */
- int16_t outbuffer[160];
- Decoder_Interface_Decode(amr, buffer, outbuffer, 0);
- /* Convert to little endian and write to wav */
- uint8_t littleendian[320];
- uint8_t* ptr = littleendian;
- for (int i = 0; i < 160; i++) {
- *ptr++ = (outbuffer[i] >> 0) & 0xff;
- *ptr++ = (outbuffer[i] >> 8) & 0xff;
- }
- wav_write_data(wav, littleendian, 320);
- }
- fclose(in);
- Decoder_Interface_exit(amr);
- wav_write_close(wav);
-
- [outData appendData:body];
- return 0;
- }
- int encode_amr(const char* infile, const char* outfile) {
- enum Mode mode = MR122;
- FILE *out;
- void *wav, *amr;
- int format, sampleRate, channels, bitsPerSample;
- int inputSize;
- uint8_t* inputBuf;
- wav = wav_read_open(infile);
- if (!wav) {
- fprintf(stderr, "Unable to open wav file %s\n", infile);
- return 1;
- }
- if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
- fprintf(stderr, "Bad wav file %s\n", infile);
- return 1;
- }
- if (format != 1) {
- fprintf(stderr, "Unsupported WAV format %d\n", format);
- return 1;
- }
- if (bitsPerSample != 16) {
- fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample);
- return 1;
- }
- if (channels != 1)
- fprintf(stderr, "Warning, only compressing one audio channel\n");
- if (sampleRate != 8000)
- fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate);
-
- inputSize = channels*2*160;
- inputBuf = (uint8_t*) malloc(inputSize);
-
- amr = Encoder_Interface_init(0);
- out = fopen(outfile, "wb");
- if (!out) {
- perror(outfile);
- return 1;
- }
-
- fwrite("#!AMR\n", 1, 6, out);
- while (1) {
- short buf[160];
- uint8_t outbuf[500];
- int read, i, n;
- read = wav_read_data(wav, inputBuf, inputSize);
- read /= channels;
- read /= 2;
- if (read < 160)
- break;
- for (i = 0; i < 160; i++) {
- const uint8_t* in = &inputBuf[2*channels*i];
- buf[i] = in[0] | (in[1] << 8);
- }
- n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0);
- fwrite(outbuf, 1, n, out);
- }
- free(inputBuf);
- fclose(out);
- Encoder_Interface_exit(amr);
- wav_read_close(wav);
-
- return 0;
- }
|