Home | History | Annotate | Download | only in test
      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 
     38 using namespace std;
     39 
     40 enum {
     41     kInputBufferSize = 10 * 1024,
     42     kOutputBufferSize = 4608 * 2,
     43 };
     44 
     45 int 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