13508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat/* 23508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * Copyright (C) 2014 The Android Open Source Project 33508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * All rights reserved. 43508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * 53508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * Redistribution and use in source and binary forms, with or without 63508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * modification, are permitted provided that the following conditions 73508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * are met: 83508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * * Redistributions of source code must retain the above copyright 93508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * notice, this list of conditions and the following disclaimer. 103508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * * Redistributions in binary form must reproduce the above copyright 113508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * notice, this list of conditions and the following disclaimer in 123508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * the documentation and/or other materials provided with the 133508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * distribution. 143508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * 153508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 183508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 193508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 203508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 213508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 223508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 233508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 243508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 253508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 263508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat * SUCH DAMAGE. 273508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat */ 283508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 293508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include <stdlib.h> 303508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include <stdio.h> 313508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include <assert.h> 323508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include <string.h> 333508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 343508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include "pvmp3decoder_api.h" 353508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include "mp3reader.h" 363508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat#include <audio_utils/sndfile.h> 373508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 383508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhatusing namespace std; 393508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 403508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhatenum { 413508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat kInputBufferSize = 10 * 1024, 423508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat kOutputBufferSize = 4608 * 2, 433508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat}; 443508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 453508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhatint main(int argc, const char **argv) { 463508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 473508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat if (argc != 3) { 483508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]); 493508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat return EXIT_FAILURE; 503508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat } 513508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 523508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Initialize the config. 533508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat tPVMP3DecoderExternal config; 543508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.equalizerType = flat; 553508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.crcEnabled = false; 563508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 573508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Allocate the decoder memory. 583508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat uint32_t memRequirements = pvmp3_decoderMemRequirements(); 593508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat void *decoderBuf = malloc(memRequirements); 603508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat assert(decoderBuf != NULL); 613508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 623508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Initialize the decoder. 633508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat pvmp3_InitDecoder(&config, decoderBuf); 643508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 653508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Open the input file. 663508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat Mp3Reader mp3Reader; 673508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat bool success = mp3Reader.init(argv[1]); 683508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat if (!success) { 693508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat fprintf(stderr, "Encountered error reading %s\n", argv[1]); 703508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat free(decoderBuf); 713508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat return EXIT_FAILURE; 723508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat } 733508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 743508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Open the output file. 753508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat SF_INFO sfInfo; 763508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat memset(&sfInfo, 0, sizeof(SF_INFO)); 773508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat sfInfo.channels = mp3Reader.getNumChannels(); 783508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; 793508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat sfInfo.samplerate = mp3Reader.getSampleRate(); 803508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo); 813508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat if (handle == NULL) { 823508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat fprintf(stderr, "Encountered error writing %s\n", argv[2]); 833508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat mp3Reader.close(); 843508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat free(decoderBuf); 853508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat return EXIT_FAILURE; 863508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat } 873508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 883508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Allocate input buffer. 893508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat uint8_t *inputBuf = static_cast<uint8_t*>(malloc(kInputBufferSize)); 903508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat assert(inputBuf != NULL); 913508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 923508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Allocate output buffer. 933508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat int16_t *outputBuf = static_cast<int16_t*>(malloc(kOutputBufferSize)); 943508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat assert(outputBuf != NULL); 953508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 963508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Decode loop. 973508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat int retVal = EXIT_SUCCESS; 983508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat while (1) { 993508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Read input from the file. 1003508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat uint32_t bytesRead; 1013508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat bool success = mp3Reader.getFrame(inputBuf, &bytesRead); 1023508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat if (!success) break; 1033508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 1043508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Set the input config. 1053508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.inputBufferCurrentLength = bytesRead; 1063508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.inputBufferMaxLength = 0; 1073508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.inputBufferUsedLength = 0; 1083508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.pInputBuffer = inputBuf; 1093508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.pOutputBuffer = outputBuf; 1103508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.outputFrameSize = kOutputBufferSize / sizeof(int16_t); 1113508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 1123508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat ERROR_CODE decoderErr; 1133508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat decoderErr = pvmp3_framedecoder(&config, decoderBuf); 1143508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat if (decoderErr != NO_DECODING_ERROR) { 1153508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat fprintf(stderr, "Decoder encountered error\n"); 1163508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat retVal = EXIT_FAILURE; 1173508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat break; 1183508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat } 1193508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat sf_writef_short(handle, outputBuf, 1203508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat config.outputFrameSize / sfInfo.channels); 1213508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat } 1223508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 1233508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Close input reader and output writer. 1243508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat mp3Reader.close(); 1253508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat sf_close(handle); 1263508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 1273508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat // Free allocated memory. 1283508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat free(inputBuf); 1293508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat free(outputBuf); 1303508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat free(decoderBuf); 1313508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat 1323508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat return retVal; 1333508d77cf7b619d33d236533a45eea1a7321cc5aAshok Bhat} 134