aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2016-06-19 02:58:23 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2016-06-19 03:31:55 +0300
commit1151d5831f19a9f24dd0c545a4968606712a62d2 (patch)
treec978c1b9a3fc86fef531dd412fe6b7668b7c0567 /src/main.cpp
parent8d65a0bd0774e03b3d10354e15f2f3361a2ce26a (diff)
downloadatracdenc-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.cpp263
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) {