134 lines
4.3 KiB
C++
134 lines
4.3 KiB
C++
/*
|
|
* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#include "pvmp3decoder_api.h"
|
|
#include "mp3reader.h"
|
|
#include <audio_utils/sndfile.h>
|
|
|
|
using namespace std;
|
|
|
|
enum {
|
|
kInputBufferSize = 10 * 1024,
|
|
kOutputBufferSize = 4608 * 2,
|
|
};
|
|
|
|
int main(int argc, const char **argv) {
|
|
|
|
if (argc != 3) {
|
|
fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Initialize the config.
|
|
tPVMP3DecoderExternal config;
|
|
config.equalizerType = flat;
|
|
config.crcEnabled = false;
|
|
|
|
// Allocate the decoder memory.
|
|
uint32_t memRequirements = pvmp3_decoderMemRequirements();
|
|
void *decoderBuf = malloc(memRequirements);
|
|
assert(decoderBuf != NULL);
|
|
|
|
// Initialize the decoder.
|
|
pvmp3_InitDecoder(&config, decoderBuf);
|
|
|
|
// Open the input file.
|
|
Mp3Reader mp3Reader;
|
|
bool success = mp3Reader.init(argv[1]);
|
|
if (!success) {
|
|
fprintf(stderr, "Encountered error reading %s\n", argv[1]);
|
|
free(decoderBuf);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Open the output file.
|
|
SF_INFO sfInfo;
|
|
memset(&sfInfo, 0, sizeof(SF_INFO));
|
|
sfInfo.channels = mp3Reader.getNumChannels();
|
|
sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
|
|
sfInfo.samplerate = mp3Reader.getSampleRate();
|
|
SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
|
|
if (handle == NULL) {
|
|
fprintf(stderr, "Encountered error writing %s\n", argv[2]);
|
|
mp3Reader.close();
|
|
free(decoderBuf);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Allocate input buffer.
|
|
uint8_t *inputBuf = static_cast<uint8_t*>(malloc(kInputBufferSize));
|
|
assert(inputBuf != NULL);
|
|
|
|
// Allocate output buffer.
|
|
int16_t *outputBuf = static_cast<int16_t*>(malloc(kOutputBufferSize));
|
|
assert(outputBuf != NULL);
|
|
|
|
// Decode loop.
|
|
int retVal = EXIT_SUCCESS;
|
|
while (1) {
|
|
// Read input from the file.
|
|
uint32_t bytesRead;
|
|
bool success = mp3Reader.getFrame(inputBuf, &bytesRead);
|
|
if (!success) break;
|
|
|
|
// Set the input config.
|
|
config.inputBufferCurrentLength = bytesRead;
|
|
config.inputBufferMaxLength = 0;
|
|
config.inputBufferUsedLength = 0;
|
|
config.pInputBuffer = inputBuf;
|
|
config.pOutputBuffer = outputBuf;
|
|
config.outputFrameSize = kOutputBufferSize / sizeof(int16_t);
|
|
|
|
ERROR_CODE decoderErr;
|
|
decoderErr = pvmp3_framedecoder(&config, decoderBuf);
|
|
if (decoderErr != NO_DECODING_ERROR) {
|
|
fprintf(stderr, "Decoder encountered error\n");
|
|
retVal = EXIT_FAILURE;
|
|
break;
|
|
}
|
|
sf_writef_short(handle, outputBuf,
|
|
config.outputFrameSize / sfInfo.channels);
|
|
}
|
|
|
|
// Close input reader and output writer.
|
|
mp3Reader.close();
|
|
sf_close(handle);
|
|
|
|
// Free allocated memory.
|
|
free(inputBuf);
|
|
free(outputBuf);
|
|
free(decoderBuf);
|
|
|
|
return retVal;
|
|
}
|