amrnbdec_test.cpp revision f9fa4bfda4122b3823a5a5cc875334bf60949a18
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <stdio.h> 30#include <stdint.h> 31#include <string.h> 32#include <assert.h> 33 34#include "gsmamr_dec.h" 35#include <audio_utils/sndfile.h> 36 37// Constants for AMR-NB 38enum { 39 kInputBufferSize = 64, 40 kSamplesPerFrame = 160, 41 kBitsPerSample = 16, 42 kOutputBufferSize = kSamplesPerFrame * kBitsPerSample/8, 43 kSampleRate = 8000, 44 kChannels = 1, 45 kFileHeaderSize = 6 46}; 47const uint32_t kFrameSizes[] = {12, 13, 15, 17, 19, 20, 26, 31}; 48 49 50int main(int argc, char *argv[]) { 51 52 if(argc != 3) { 53 fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]); 54 return 1; 55 } 56 57 // Open the input file 58 FILE* fpInput = fopen(argv[1], "rb"); 59 if (!fpInput) { 60 fprintf(stderr, "Could not open %s\n", argv[1]); 61 return 1; 62 } 63 64 // Validate the input AMR file 65 char header[kFileHeaderSize]; 66 int bytesRead = fread(header, 1, kFileHeaderSize, fpInput); 67 if (bytesRead != kFileHeaderSize || memcmp(header, "#!AMR\n", kFileHeaderSize)) { 68 fprintf(stderr, "Invalid AMR-NB file\n"); 69 return 1; 70 } 71 72 // Open the output file 73 SF_INFO sfInfo; 74 memset(&sfInfo, 0, sizeof(SF_INFO)); 75 sfInfo.channels = kChannels; 76 sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; 77 sfInfo.samplerate = kSampleRate; 78 SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo); 79 if(!handle){ 80 fprintf(stderr, "Could not create %s\n", argv[2]); 81 return 1; 82 } 83 84 // Create AMR-NB decoder instance 85 void* amrHandle; 86 int err = GSMInitDecode(&amrHandle, (Word8*)"AMRNBDecoder"); 87 if(err != 0){ 88 fprintf(stderr, "Error creating AMR-NB decoder instance\n"); 89 return 1; 90 } 91 92 //Allocate input buffer 93 void *inputBuf = malloc(kInputBufferSize); 94 assert(inputBuf != NULL); 95 96 //Allocate output buffer 97 void *outputBuf = malloc(kOutputBufferSize); 98 assert(outputBuf != NULL); 99 100 101 // Decode loop 102 uint32_t retVal = 0; 103 while (1) { 104 // Read mode 105 uint8_t mode; 106 bytesRead = fread(&mode, 1, 1, fpInput); 107 if (bytesRead != 1) break; 108 109 // Find frame type 110 Frame_Type_3GPP frameType = (Frame_Type_3GPP)((mode >> 3) & 0x0f); 111 if (frameType >= AMR_SID){ 112 fprintf(stderr, "Frame type %d not supported\n",frameType); 113 retVal = 1; 114 break; 115 } 116 117 // Find frame type 118 int32_t frameSize = kFrameSizes[frameType]; 119 bytesRead = fread(inputBuf, 1, frameSize, fpInput); 120 if (bytesRead != frameSize) break; 121 122 //Decode frame 123 int32_t decodeStatus; 124 decodeStatus = AMRDecode(amrHandle, frameType, (uint8_t*)inputBuf, 125 (int16_t*)outputBuf, MIME_IETF); 126 if(decodeStatus == -1) { 127 fprintf(stderr, "Decoder encountered error\n"); 128 retVal = 1; 129 break; 130 } 131 132 //Write output to wav 133 sf_writef_short(handle, (int16_t*)outputBuf, kSamplesPerFrame); 134 135 } 136 137 // Close input and output file 138 fclose(fpInput); 139 sf_close(handle); 140 141 //Free allocated memory 142 free(inputBuf); 143 free(outputBuf); 144 145 // Close decoder instance 146 GSMDecodeFrameExit(&amrHandle); 147 148 return retVal; 149} 150