diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-06-19 02:58:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-06-19 03:31:55 +0300 |
commit | 1151d5831f19a9f24dd0c545a4968606712a62d2 (patch) | |
tree | c978c1b9a3fc86fef531dd412fe6b7668b7c0567 /src/main.cpp | |
parent | 8d65a0bd0774e03b3d10354e15f2f3361a2ce26a (diff) | |
download | atracdenc-1151d5831f19a9f24dd0c545a4968606712a62d2.tar.gz |
some improvements of ATRAC3 implementation:atrac3
- simple (ATRAC1 like) psychoacoustic added
- possibility to encode tonal components
- simple tonal component extractor
- refactoring
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 263 |
1 files changed, 187 insertions, 76 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5a9547e..b35f6bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,20 +6,23 @@ #include "pcmengin.h" #include "wav.h" #include "aea.h" -#include "atracdenc.h" +#include "config.h" +#include "atrac1denc.h" +#include "atrac3denc.h" using std::cout; using std::cerr; using std::endl; using std::string; -using std::unique_ptr; -using std::move; using std::stoi; using namespace NAtracDEnc; +typedef std::unique_ptr<TPCMEngine<TFloat>> TPcmEnginePtr; +typedef std::unique_ptr<IProcessor<TFloat>> TAtracProcessorPtr; -static void printUsage(const char* myName) { +static void printUsage(const char* myName) +{ cout << "\tusage: " << myName << " <-e|-d> <-i input> <-o output>\n" << endl; cout << "-e encode mode (PCM -> ATRAC), -i wav file, -o aea file" << endl; cout << "-d decode mode (ATRAC -> PCM), -i aea file, -o wav file" << endl; @@ -27,7 +30,8 @@ static void printUsage(const char* myName) { } -static void printProgress(int percent) { +static void printProgress(int percent) +{ static uint32_t counter; counter++; const char symbols[4] = {'-', '\\', '|', '/'}; @@ -35,18 +39,24 @@ static void printProgress(int percent) { fflush(stdout); } -static string GetHelp() { +static string GetHelp() +{ return "\n--encode -i \t - encode mode" "\n--decode -d \t - decode mode" "\n -i input file" "\n -o output file" "\n --bitrate (only if supported by codec)" - "\nAdvanced options:\n --bfuidxconst\t Set constant amount of used BFU. WARNING: It is not a lowpass filter! Do not use it to cut off hi frequency." - "\n --bfuidxfast\t enable fast search of BFU amount" - "\n --notransient[=mask] disable transient detection and use optional mask to set bands with short MDCT window"; + "\nAdvanced options:\n --bfuidxconst\t Set constant amount of used BFU (ATRAC1). " + "WARNING: It is not a lowpass filter! Do not use it to cut off hi frequency." + "\n --bfuidxfast\t enable fast search of BFU amount (ATRAC1)" + "\n --notransient[=mask] disable transient detection and use optional mask to set bands with short MDCT window " + "(ATRAC1)" + /*"\n --nogaincontrol disable gain control (ATRAC3)"*/ + "\n --notonal disable tonal components (ATRAC3)"; } -static int checkedStoi(const char* data, int min, int max, int def) { +static int checkedStoi(const char* data, int min, int max, int def) +{ int tmp = 0; try { tmp = stoi(data); @@ -59,18 +69,114 @@ static int checkedStoi(const char* data, int min, int max, int def) { } } -int main(int argc, char* const* argv) { +enum EOptions +{ + O_ENCODE = 'e', + O_DECODE = 'd', + O_HELP = 'h', + O_BITRATE = 'b', + O_BFUIDXCONST = 1, + O_BFUIDXFAST = 2, + O_NOTRANSIENT = 3, + O_MONO = 'm', + O_NOSTDOUT = '4', + O_NOTONAL = 5, + O_NOGAINCONTROL = 6, +}; + +static void PrepareAtrac1Encoder(const string& inFile, + const string& outFile, + const bool noStdOut, + NAtrac1::TAtrac1EncodeSettings&& encoderSettings, + uint64_t* totalSamples, + TWavPtr* wavIO, + TPcmEnginePtr* pcmEngine, + TAtracProcessorPtr* atracProcessor) +{ + using NAtrac1::TAtrac1Data; + + wavIO->reset(new TWav(inFile)); + const int numChannels = (*wavIO)->GetChannelNum(); + *totalSamples = (*wavIO)->GetTotalSamples(); + //TODO: recheck it + const uint32_t numFrames = numChannels * (*totalSamples) / TAtrac1Data::NumSamples; + TCompressedIOPtr aeaIO = TCompressedIOPtr(new TAea(outFile, "test", numChannels, numFrames)); + pcmEngine->reset(new TPCMEngine<TFloat>(4096, + numChannels, + TPCMEngine<TFloat>::TReaderPtr((*wavIO)->GetPCMReader<TFloat>()))); + if (!noStdOut) + cout << "Input file: " << inFile + << "\n Channels: " << numChannels + << "\n SampleRate: " << (*wavIO)->GetSampleRate() + << "\n TotalSamples: " << totalSamples + << endl; + atracProcessor->reset(new TAtrac1Processor(std::move(aeaIO), std::move(encoderSettings))); +} + +static void PrepareAtrac1Decoder(const string& inFile, + const string& outFile, + const bool noStdOut, + uint64_t* totalSamples, + TWavPtr* wavIO, + TPcmEnginePtr* pcmEngine, + TAtracProcessorPtr* atracProcessor) +{ + TCompressedIOPtr aeaIO = TCompressedIOPtr(new TAea(inFile)); + *totalSamples = aeaIO->GetLengthInSamples(); + uint32_t length = aeaIO->GetLengthInSamples(); + if (!noStdOut) + cout << "Name: " << aeaIO->GetName() + << "\n Channels: " << aeaIO->GetChannelNum() + << "\n Length: " << length + << endl; + wavIO->reset(new TWav(outFile, aeaIO->GetChannelNum(), 44100)); + pcmEngine->reset(new TPCMEngine<TFloat>(4096, + aeaIO->GetChannelNum(), + TPCMEngine<TFloat>::TWriterPtr((*wavIO)->GetPCMWriter<TFloat>()))); + atracProcessor->reset(new TAtrac1Processor(std::move(aeaIO), NAtrac1::TAtrac1EncodeSettings())); +} + +static void PrepareAtrac3Encoder(const string& inFile, + const string& outFile, + const bool noStdOut, + NAtrac3::TAtrac3EncoderSettings&& encoderSettings, + uint64_t* totalSamples, + TWavPtr* wavIO, + TPcmEnginePtr* pcmEngine, + TAtracProcessorPtr* atracProcessor) +{ + std::cout << "WARNING: ATRAC3 is uncompleted, result will be not good )))" << std::endl; + if (!noStdOut) + std::cout << "bitrate " << encoderSettings.ConteinerParams->Bitrate << std::endl; + wavIO->reset(new TWav(inFile)); + const int numChannels = (*wavIO)->GetChannelNum(); + *totalSamples = (*wavIO)->GetTotalSamples(); + TCompressedIOPtr omaIO = TCompressedIOPtr(new TOma(outFile, + "test", + numChannels, + numChannels * (*totalSamples) / 512, OMAC_ID_ATRAC3, + encoderSettings.ConteinerParams->FrameSz)); + pcmEngine->reset(new TPCMEngine<TFloat>(4096, + numChannels, + TPCMEngine<TFloat>::TReaderPtr((*wavIO)->GetPCMReader<TFloat>()))); + atracProcessor->reset(new TAtrac3Processor(std::move(omaIO), std::move(encoderSettings))); +} + +int main(int argc, char* const* argv) +{ const char* myName = argv[0]; static struct option longopts[] = { - { "encode", optional_argument, NULL, 'e' }, - { "decode", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "bitrate", required_argument, NULL, 'b'}, - { "bfuidxconst", required_argument, NULL, 1}, - { "bfuidxfast", no_argument, NULL, 2}, - { "notransient", optional_argument, NULL, 3}, - { "mono", no_argument, NULL, 'm'}, - { "nostdout", no_argument, NULL, 4}, + { "encode", optional_argument, NULL, O_ENCODE }, + { "decode", no_argument, NULL, O_DECODE }, + { "help", no_argument, NULL, O_HELP }, + { "bitrate", required_argument, NULL, O_BITRATE}, + { "bfuidxconst", required_argument, NULL, O_BFUIDXCONST}, + { "bfuidxfast", no_argument, NULL, O_BFUIDXFAST}, + { "notransient", optional_argument, NULL, O_NOTRANSIENT}, + { "mono", no_argument, NULL, O_MONO}, + { "nostdout", no_argument, NULL, O_NOSTDOUT}, + { "notonal", no_argument, NULL, O_NOTONAL}, + { "nogaincontrol", no_argument, NULL, O_NOGAINCONTROL}, { NULL, 0, NULL, 0} }; @@ -81,13 +187,15 @@ int main(int argc, char* const* argv) { uint32_t bfuIdxConst = 0; //0 - auto, no const bool fastBfuNumSearch = false; bool mono = false; - bool nostdout = false; - TAtrac1EncodeSettings::EWindowMode windowMode = TAtrac1EncodeSettings::EWindowMode::EWM_AUTO; + bool noStdOut = false; + bool noGainControl = true; + bool noTonalComponents = false; + NAtrac1::TAtrac1EncodeSettings::EWindowMode windowMode = NAtrac1::TAtrac1EncodeSettings::EWindowMode::EWM_AUTO; uint32_t winMask = 0; //0 - all is long uint32_t bitrate = 0; //0 - use default for codec while ((ch = getopt_long(argc, argv, "edhi:o:m", longopts, NULL)) != -1) { switch (ch) { - case 'e': + case O_ENCODE: mode |= E_ENCODE; if (optarg) { if (strcmp(optarg, "atrac3") == 0) { @@ -95,7 +203,7 @@ int main(int argc, char* const* argv) { } } break; - case 'd': + case O_DECODE: mode |= E_DECODE; break; case 'i': @@ -104,26 +212,27 @@ int main(int argc, char* const* argv) { case 'o': outFile = optarg; if (outFile == "-") - nostdout = true; + noStdOut = true; break; - case 'm': + case O_MONO: mono = true; break; - case 'h': + case O_HELP: cout << GetHelp() << endl; return 0; break; - case 'b': + case O_BITRATE: bitrate = checkedStoi(optarg, 32, 384, 0); + std::cout << "BITRATE" << bitrate << std::endl; break; - case 1: + case O_BFUIDXCONST: bfuIdxConst = checkedStoi(optarg, 1, 8, 0); break; - case 2: + case O_BFUIDXFAST: fastBfuNumSearch = true; break; - case 3: - windowMode = TAtrac1EncodeSettings::EWindowMode::EWM_NOTRANSIENT; + case O_NOTRANSIENT: + windowMode = NAtrac1::TAtrac1EncodeSettings::EWindowMode::EWM_NOTRANSIENT; if (optarg) { winMask = stoi(optarg); } @@ -132,8 +241,14 @@ int main(int argc, char* const* argv) { ((winMask & 2) ? "short": "long") << ", hi - " << ((winMask & 4) ? "short": "long") << endl; break; - case 4: - nostdout = true; + case O_NOSTDOUT: + noStdOut = true; + break; + case O_NOTONAL: + noTonalComponents = true; + break; + case O_NOGAINCONTROL: + noGainControl = true; break; default: printUsage(myName); @@ -152,54 +267,50 @@ int main(int argc, char* const* argv) { return 1; } if (bfuIdxConst > 8) { - cerr << "Wrong bfuidxconst value ("<< bfuIdxConst << "). This is advanced options, use --help to get more information" << endl; + cerr << "Wrong bfuidxconst value ("<< bfuIdxConst << "). " + << "This is advanced options, use --help to get more information" + << endl; return 1; } - TPCMEngine<double>* pcmEngine = nullptr; - IProcessor<double>* atracProcessor; + + TPcmEnginePtr pcmEngine; + TAtracProcessorPtr atracProcessor; uint64_t totalSamples = 0; TWavPtr wavIO; uint32_t pcmFrameSz = 0; //size of one pcm frame to process - if (mode == E_ENCODE) { - wavIO = TWavPtr(new TWav(inFile)); - const int numChannels = wavIO->GetChannelNum(); - totalSamples = wavIO->GetTotalSamples(); - //TODO: recheck it - TAeaPtr aeaIO = TAeaPtr(new TAea(outFile, "test", numChannels, numChannels * totalSamples / 512)); - pcmEngine = new TPCMEngine<double>(4096, numChannels, TPCMEngine<double>::TReaderPtr(wavIO->GetPCMReader<double>())); - if (!nostdout) - cout << "Input file: " << inFile << "\n Channels: " << numChannels << "\n SampleRate: " << wavIO->GetSampleRate() << "\n TotalSamples: " << totalSamples << endl; - atracProcessor = new TAtrac1Processor(move(aeaIO), TAtrac1EncodeSettings(bfuIdxConst, fastBfuNumSearch, windowMode, winMask)); - pcmFrameSz = 512; - } else if (mode == E_DECODE) { - TAeaPtr aeaIO = TAeaPtr(new TAea(inFile)); - totalSamples = aeaIO->GetLengthInSamples(); - uint32_t length = aeaIO->GetLengthInSamples(); - if (!nostdout) - cout << "Name: " << aeaIO->GetName() << "\n Channels: " << aeaIO->GetChannelNum() << "\n Length: " << length << endl; - wavIO = TWavPtr(new TWav(outFile, aeaIO->GetChannelNum(), 44100)); - pcmEngine = new TPCMEngine<double>(4096, aeaIO->GetChannelNum(), TPCMEngine<double>::TWriterPtr(wavIO->GetPCMWriter<double>())); - atracProcessor = new TAtrac1Processor(move(aeaIO), TAtrac1EncodeSettings(bfuIdxConst, fastBfuNumSearch, windowMode, winMask)); - pcmFrameSz = 512; - } else if (mode == (E_ENCODE | E_ATRAC3)) { - std::cout << "WARNING: ATRAC3 is uncompleted mode (no psy, tonal encoding, gc), result will be not good )))" << std::endl; - const TContainerParams* atrac3params = TAtrac3Data::GetContainerParamsForBitrate(bitrate*1024); - if (atrac3params == nullptr) { - std::cerr << "wrong atrac3 params, exiting" << std::endl; + switch (mode) { + case E_ENCODE: + { + using NAtrac1::TAtrac1Data; + NAtrac1::TAtrac1EncodeSettings encoderSettings(bfuIdxConst, fastBfuNumSearch, windowMode, winMask); + PrepareAtrac1Encoder(inFile, outFile, noStdOut, std::move(encoderSettings), + &totalSamples, &wavIO, &pcmEngine, &atracProcessor); + pcmFrameSz = TAtrac1Data::NumSamples; + } + break; + case E_DECODE: + { + using NAtrac1::TAtrac1Data; + PrepareAtrac1Decoder(inFile, outFile, noStdOut, + &totalSamples, &wavIO, &pcmEngine, &atracProcessor); + pcmFrameSz = TAtrac1Data::NumSamples; + } + break; + case (E_ENCODE | E_ATRAC3): + { + using NAtrac3::TAtrac3Data; + NAtrac3::TAtrac3EncoderSettings encoderSettings(bitrate * 1024, noGainControl, noTonalComponents); + PrepareAtrac3Encoder(inFile, outFile, noStdOut, std::move(encoderSettings), + &totalSamples, &wavIO, &pcmEngine, &atracProcessor); + pcmFrameSz = TAtrac3Data::NumSamples;; + } + break; + default: + { + cerr << "Processing mode was not specified" << endl; return 1; } - std::cout << "bitrate " << atrac3params->Bitrate << std::endl; - wavIO = TWavPtr(new TWav(inFile)); - const int numChannels = wavIO->GetChannelNum(); - totalSamples = wavIO->GetTotalSamples(); - TAeaPtr omaIO = TAeaPtr(new TOma(outFile, "test", numChannels, numChannels * totalSamples / 512, OMAC_ID_ATRAC3, atrac3params->FrameSz)); - pcmEngine = new TPCMEngine<double>(4096, numChannels, TPCMEngine<double>::TReaderPtr(wavIO->GetPCMReader<double>())); - atracProcessor = new TAtrac3Processor(move(omaIO), *atrac3params); - pcmFrameSz = 1024; - } else { - cerr << "Processing mode was not specified" << endl; - return 1; } auto atracLambda = (mode == E_DECODE) ? atracProcessor->GetDecodeLambda() : @@ -209,10 +320,10 @@ int main(int argc, char* const* argv) { try { while (totalSamples > (processed = pcmEngine->ApplyProcess(pcmFrameSz, atracLambda))) { - if (!nostdout) + if (!noStdOut) printProgress(processed*100/totalSamples); } - if (!nostdout) + if (!noStdOut) cout << "\nDone" << endl; } catch (TAeaIOError err) { |