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 <stdlib.h> 30#include <stdio.h> 31#include <assert.h> 32#include <string.h> 33 34#include "pvmp3decoder_api.h" 35#include "mp3reader.h" 36#include <audio_utils/sndfile.h> 37 38using namespace std; 39 40enum { 41 kInputBufferSize = 10 * 1024, 42 kOutputBufferSize = 4608 * 2, 43}; 44 45int main(int argc, const char **argv) { 46 47 if (argc != 3) { 48 fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]); 49 return EXIT_FAILURE; 50 } 51 52 // Initialize the config. 53 tPVMP3DecoderExternal config; 54 config.equalizerType = flat; 55 config.crcEnabled = false; 56 57 // Allocate the decoder memory. 58 uint32_t memRequirements = pvmp3_decoderMemRequirements(); 59 void *decoderBuf = malloc(memRequirements); 60 assert(decoderBuf != NULL); 61 62 // Initialize the decoder. 63 pvmp3_InitDecoder(&config, decoderBuf); 64 65 // Open the input file. 66 Mp3Reader mp3Reader; 67 bool success = mp3Reader.init(argv[1]); 68 if (!success) { 69 fprintf(stderr, "Encountered error reading %s\n", argv[1]); 70 free(decoderBuf); 71 return EXIT_FAILURE; 72 } 73 74 // Open the output file. 75 SF_INFO sfInfo; 76 memset(&sfInfo, 0, sizeof(SF_INFO)); 77 sfInfo.channels = mp3Reader.getNumChannels(); 78 sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; 79 sfInfo.samplerate = mp3Reader.getSampleRate(); 80 SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo); 81 if (handle == NULL) { 82 fprintf(stderr, "Encountered error writing %s\n", argv[2]); 83 mp3Reader.close(); 84 free(decoderBuf); 85 return EXIT_FAILURE; 86 } 87 88 // Allocate input buffer. 89 uint8_t *inputBuf = static_cast<uint8_t*>(malloc(kInputBufferSize)); 90 assert(inputBuf != NULL); 91 92 // Allocate output buffer. 93 int16_t *outputBuf = static_cast<int16_t*>(malloc(kOutputBufferSize)); 94 assert(outputBuf != NULL); 95 96 // Decode loop. 97 int retVal = EXIT_SUCCESS; 98 while (1) { 99 // Read input from the file. 100 uint32_t bytesRead; 101 bool success = mp3Reader.getFrame(inputBuf, &bytesRead); 102 if (!success) break; 103 104 // Set the input config. 105 config.inputBufferCurrentLength = bytesRead; 106 config.inputBufferMaxLength = 0; 107 config.inputBufferUsedLength = 0; 108 config.pInputBuffer = inputBuf; 109 config.pOutputBuffer = outputBuf; 110 config.outputFrameSize = kOutputBufferSize / sizeof(int16_t); 111 112 ERROR_CODE decoderErr; 113 decoderErr = pvmp3_framedecoder(&config, decoderBuf); 114 if (decoderErr != NO_DECODING_ERROR) { 115 fprintf(stderr, "Decoder encountered error\n"); 116 retVal = EXIT_FAILURE; 117 break; 118 } 119 sf_writef_short(handle, outputBuf, 120 config.outputFrameSize / sfInfo.channels); 121 } 122 123 // Close input reader and output writer. 124 mp3Reader.close(); 125 sf_close(handle); 126 127 // Free allocated memory. 128 free(inputBuf); 129 free(outputBuf); 130 free(decoderBuf); 131 132 return retVal; 133} 134