From f9fa4bfda4122b3823a5a5cc875334bf60949a18 Mon Sep 17 00:00:00 2001 From: Ashok Bhat Date: Tue, 20 May 2014 14:24:30 +0100 Subject: Add test for AMR-NB decoder The test accepts a .amr file as input and dumps output PCM in a wav file. To run the test, use following command libstagefright_amrnbdec_test Change-Id: I2492c2ed4e670c9fd8cb4213201ccbd0cb9bf8fe Signed-off-by: Ashok Bhat --- media/libstagefright/codecs/amrnb/dec/Android.mk | 21 +++ .../codecs/amrnb/dec/test/amrnbdec_test.cpp | 149 +++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100755 media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp (limited to 'media') diff --git a/media/libstagefright/codecs/amrnb/dec/Android.mk b/media/libstagefright/codecs/amrnb/dec/Android.mk index 8d6c6f8..bc54c5d 100644 --- a/media/libstagefright/codecs/amrnb/dec/Android.mk +++ b/media/libstagefright/codecs/amrnb/dec/Android.mk @@ -79,3 +79,24 @@ LOCAL_MODULE := libstagefright_soft_amrdec LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) + +################################################################################ +include $(CLEAR_VARS) +LOCAL_SRC_FILES := \ + test/amrnbdec_test.cpp + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/src \ + $(LOCAL_PATH)/../common/include \ + $(call include-path-for, audio-utils) + +LOCAL_STATIC_LIBRARIES := \ + libstagefright_amrnbdec libsndfile + +LOCAL_SHARED_LIBRARIES := \ + libstagefright_amrnb_common libaudioutils + +LOCAL_MODULE := libstagefright_amrnbdec_test +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) 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 100755 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 +#include +#include +#include + +#include "gsmamr_dec.h" +#include + +// 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 \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; +} -- cgit v1.1