diff options
Diffstat (limited to 'media/libstagefright/codecs/amrnb/dec/test')
-rw-r--r-- | media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp new file mode 100644 index 0000000..521fe2b --- /dev/null +++ b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "gsmamr_dec.h" +#include <audio_utils/sndfile.h> + +// Constants for AMR-NB +enum { + kInputBufferSize = 64, + kSamplesPerFrame = 160, + kBitsPerSample = 16, + kOutputBufferSize = kSamplesPerFrame * kBitsPerSample/8, + kSampleRate = 8000, + kChannels = 1, + kFileHeaderSize = 6 +}; +const uint32_t kFrameSizes[] = {12, 13, 15, 17, 19, 20, 26, 31}; + + +int main(int argc, char *argv[]) { + + if(argc != 3) { + fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]); + return 1; + } + + // Open the input file + FILE* fpInput = fopen(argv[1], "rb"); + if (!fpInput) { + fprintf(stderr, "Could not open %s\n", argv[1]); + return 1; + } + + // Validate the input AMR file + char header[kFileHeaderSize]; + int bytesRead = fread(header, 1, kFileHeaderSize, fpInput); + if (bytesRead != kFileHeaderSize || memcmp(header, "#!AMR\n", kFileHeaderSize)) { + fprintf(stderr, "Invalid AMR-NB file\n"); + return 1; + } + + // Open the output file + SF_INFO sfInfo; + memset(&sfInfo, 0, sizeof(SF_INFO)); + sfInfo.channels = kChannels; + sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; + sfInfo.samplerate = kSampleRate; + SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo); + if(!handle){ + fprintf(stderr, "Could not create %s\n", argv[2]); + return 1; + } + + // Create AMR-NB decoder instance + void* amrHandle; + int err = GSMInitDecode(&amrHandle, (Word8*)"AMRNBDecoder"); + if(err != 0){ + fprintf(stderr, "Error creating AMR-NB decoder instance\n"); + return 1; + } + + //Allocate input buffer + void *inputBuf = malloc(kInputBufferSize); + assert(inputBuf != NULL); + + //Allocate output buffer + void *outputBuf = malloc(kOutputBufferSize); + assert(outputBuf != NULL); + + + // Decode loop + uint32_t retVal = 0; + while (1) { + // Read mode + uint8_t mode; + bytesRead = fread(&mode, 1, 1, fpInput); + if (bytesRead != 1) break; + + // Find frame type + Frame_Type_3GPP frameType = (Frame_Type_3GPP)((mode >> 3) & 0x0f); + if (frameType >= AMR_SID){ + fprintf(stderr, "Frame type %d not supported\n",frameType); + retVal = 1; + break; + } + + // Find frame type + int32_t frameSize = kFrameSizes[frameType]; + bytesRead = fread(inputBuf, 1, frameSize, fpInput); + if (bytesRead != frameSize) break; + + //Decode frame + int32_t decodeStatus; + decodeStatus = AMRDecode(amrHandle, frameType, (uint8_t*)inputBuf, + (int16_t*)outputBuf, MIME_IETF); + if(decodeStatus == -1) { + fprintf(stderr, "Decoder encountered error\n"); + retVal = 1; + break; + } + + //Write output to wav + sf_writef_short(handle, (int16_t*)outputBuf, kSamplesPerFrame); + + } + + // Close input and output file + fclose(fpInput); + sf_close(handle); + + //Free allocated memory + free(inputBuf); + free(outputBuf); + + // Close decoder instance + GSMDecodeFrameExit(&amrHandle); + + return retVal; +} |