aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2025-05-16 23:27:59 +0200
committerDaniil Cherednik <dan.cherednik@gmail.com>2025-05-16 23:48:26 +0200
commitc5ae2cec2c8308f96867e1620f0ec3a5c41395e4 (patch)
tree8291351078e27ece783f9495241cdf667cfd4e0b /src
parent2a143471b0898dd8b6257ca69309a6f2b1c20bf3 (diff)
downloadatracdenc-c5ae2cec2c8308f96867e1620f0ec3a5c41395e4.tar.gz
[AT3P] Add advanced option for GHA debug
There are 3 flags: GHA_PASS_INPUT - allows to pass source signal in to the filter GHA_WRITE_TONAL - allows to write result of GHA into the bitstream GHA_WRITE_RESIUDAL - allows to process signal after the filter If all 3 flags set it denotes normal processing. If we want to see only result of sinusoid extraction (tonal component) we can set only GHA_WRITE_TONAL flag. If we want to see signal after extraction we need to set GHA_PASS_INPUT and GHA_WRITE_RESIUDAL.
Diffstat (limited to 'src')
-rw-r--r--src/atrac/at3p/at3p.cpp107
-rw-r--r--src/atrac3p.h18
-rw-r--r--src/main.cpp17
3 files changed, 130 insertions, 12 deletions
diff --git a/src/atrac/at3p/at3p.cpp b/src/atrac/at3p/at3p.cpp
index 278d362..ceee283 100644
--- a/src/atrac/at3p/at3p.cpp
+++ b/src/atrac/at3p/at3p.cpp
@@ -28,6 +28,7 @@
#include <cassert>
#include <vector>
+#include <unordered_map>
using std::vector;
@@ -35,10 +36,11 @@ namespace NAtracDEnc {
class TAt3PEnc::TImpl {
public:
- TImpl(ICompressedOutput* out, int channels)
+ TImpl(ICompressedOutput* out, int channels, TSettings settings)
: BitStream(out, 2048)
, ChannelCtx(channels)
, GhaProcessor(MakeGhaProcessor0(channels == 2))
+ , Settings(settings)
{
delay.NumToneBands = 0;
}
@@ -72,6 +74,7 @@ private:
vector<TChannelCtx> ChannelCtx;
std::unique_ptr<IGhaProcessor> GhaProcessor;
TAt3PGhaData delay;
+ const TSettings Settings;
};
TPCMEngine::EProcessResult TAt3PEnc::TImpl::
@@ -121,8 +124,14 @@ EncodeFrame(const float* data, int channels)
TAt3pMDCT::TPcmBandsData p;
float tmp[2048];
//TODO: scale window
- for (size_t i = 0; i < 2048; i++) {
- tmp[i] = x[i] / 32768.0;
+ if (Settings.UseGha & TSettings::GHA_WRITE_RESIUDAL) {
+ for (size_t i = 0; i < 2048; i++) {
+ tmp[i] = x[i] / 32768.0;
+ }
+ } else {
+ for (size_t i = 0; i < 2048; i++) {
+ tmp[i] = 0.0;
+ }
}
for (size_t b = 0; b < 16; b++) {
p[b] = tmp + b * 128;
@@ -136,10 +145,14 @@ EncodeFrame(const float* data, int channels)
BitStream.WriteFrame(channels, p, scaledBlocks);
for (int ch = 0; ch < channels; ch++) {
- memcpy(ChannelCtx[ch].PrevBuf, ChannelCtx[ch].CurBuf, sizeof(float) * TAt3PEnc::NumSamples);
+ if (Settings.UseGha & TSettings::GHA_PASS_INPUT) {
+ memcpy(ChannelCtx[ch].PrevBuf, ChannelCtx[ch].CurBuf, sizeof(float) * TAt3PEnc::NumSamples);
+ } else {
+ memset(ChannelCtx[ch].PrevBuf, 0, sizeof(float) * TAt3PEnc::NumSamples);
+ }
std::swap(ChannelCtx[ch].NextBuf, ChannelCtx[ch].CurBuf);
}
- if (tonalBlock) {
+ if (tonalBlock && (Settings.UseGha & TSettings::GHA_WRITE_TONAL)) {
delay = *tonalBlock;
} else {
delay.NumToneBands = 0;
@@ -148,18 +161,96 @@ EncodeFrame(const float* data, int channels)
return TPCMEngine::EProcessResult::PROCESSED;
}
-TAt3PEnc::TAt3PEnc(TCompressedOutputPtr&& out, int channels)
+TAt3PEnc::TAt3PEnc(TCompressedOutputPtr&& out, int channels, TSettings settings)
: Out(std::move(out))
, Channels(channels)
+ , Impl(new TImpl(Out.get(), Channels, settings))
{
}
TPCMEngine::TProcessLambda TAt3PEnc::GetLambda() {
- Impl.reset(new TImpl(Out.get(), Channels));
-
return [this](float* data, const TPCMEngine::ProcessMeta&) {
return Impl->EncodeFrame(data, Channels);
};
}
+static void SetGha(const std::string& str, TAt3PEnc::TSettings& settings) {
+ int mask = std::stoi(str);
+ if (mask > 7 || mask < 0) {
+ throw std::runtime_error("invalud value of GHA processing mask");
+ }
+
+ if (mask & TAt3PEnc::TSettings::GHA_PASS_INPUT)
+ std::cerr << "GHA_PASS_INPUT" << std::endl;
+ if (mask & TAt3PEnc::TSettings::GHA_WRITE_RESIUDAL)
+ std::cerr << "GHA_WRITE_RESIUDAL" << std::endl;
+ if (mask & TAt3PEnc::TSettings::GHA_WRITE_TONAL)
+ std::cerr << "GHA_WRITE_TONAL" << std::endl;
+
+ settings.UseGha = mask;
+}
+
+
+
+void TAt3PEnc::ParseAdvancedOpt(const char* opt, TSettings& settings) {
+ typedef void (*processFn)(const std::string& str, TSettings& settings);
+ static std::unordered_map<std::string, processFn> keys {
+ {"ghadbg", &SetGha}
+ };
+
+ if (opt == nullptr)
+ return;
+
+ const char* start = opt;
+ bool vState = false; //false - key state, true - value state
+ processFn handler = nullptr;
+
+ while (opt) {
+ if (!vState) {
+ if (*opt == ',') {
+ throw std::runtime_error("unexpected \",\" just after key.");
+// if (opt - start > 0) {
+// }
+// opt++;
+// start = opt;
+ } else if (*opt == '=') {
+ auto it = keys.find(std::string(start, opt - start));
+ if (it == keys.end()) {
+ throw std::runtime_error(std::string("unexpected advanced option \"")
+ + std::string(start, opt - start));
+ }
+ handler = it->second;
+ vState = true;
+ opt++;
+ start = opt;
+ } else if (!*opt) {
+ throw std::runtime_error("unexpected end of key token");
+// if (opt - start > 0) {
+// }
+// opt = nullptr;
+ } else {
+ opt++;
+ }
+ } else {
+ if (*opt == ',') {
+ if (opt - start > 0) {
+ handler(std::string(start, opt - start), settings);
+ }
+ opt++;
+ start = opt;
+ vState = false;
+ } else if (*opt == '=') {
+ throw std::runtime_error("unexpected \"=\" inside value token.");
+ } else if (!*opt) {
+ if (opt - start > 0) {
+ handler(std::string(start, opt - start), settings);
+ }
+ opt = nullptr;
+ } else {
+ opt++;
+ }
+ }
+ }
+}
+
}
diff --git a/src/atrac3p.h b/src/atrac3p.h
index 258a6f1..779929d 100644
--- a/src/atrac3p.h
+++ b/src/atrac3p.h
@@ -26,9 +26,25 @@ namespace NAtracDEnc {
class TAt3PEnc : public IProcessor {
public:
- TAt3PEnc(TCompressedOutputPtr&& out, int channels);
+ struct TSettings {
+ enum GhaProcessingFlags : uint8_t {
+ GHA_PASS_INPUT = 1,
+ GHA_WRITE_TONAL = 1 << 1,
+ GHA_WRITE_RESIUDAL = 1 << 2,
+
+ GHA_ENABLED = GHA_PASS_INPUT | GHA_WRITE_TONAL | GHA_WRITE_RESIUDAL
+ };
+ uint8_t UseGha;
+
+ TSettings()
+ : UseGha(GHA_ENABLED)
+ {}
+ };
+ TAt3PEnc(TCompressedOutputPtr&& out, int channels, TSettings settings);
TPCMEngine::TProcessLambda GetLambda() override;
static constexpr int NumSamples = 2048;
+ static void ParseAdvancedOpt(const char* opt, TSettings& settings);
+
private:
TCompressedOutputPtr Out;
int Channels;
diff --git a/src/main.cpp b/src/main.cpp
index 8dbf700..861495f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -110,6 +110,7 @@ enum EOptions
O_NOSTDOUT = '4',
O_NOTONAL = 5,
O_NOGAINCONTROL = 6,
+ O_ADVANCED_OPT = 7,
};
static void CheckInputFormat(const TWav* p)
@@ -258,7 +259,8 @@ static void PrepareAtrac3PEncoder(const string& inFile,
uint64_t* totalSamples,
const TWavPtr& wavIO,
TPcmEnginePtr* pcmEngine,
- TAtracProcessorPtr* atracProcessor)
+ TAtracProcessorPtr* atracProcessor,
+ const char* advancedOpt)
{
*totalSamples = wavIO->GetTotalSamples();
const uint64_t numFrames = (*totalSamples) / 2048;
@@ -300,13 +302,18 @@ static void PrepareAtrac3PEncoder(const string& inFile,
pcmEngine->reset(new TPCMEngine(4096,
numChannels,
TPCMEngine::TReaderPtr(wavIO->GetPCMReader())));
- atracProcessor->reset(new TAt3PEnc(std::move(omaIO), numChannels));
+ TAt3PEnc::TSettings settings;
+ if (advancedOpt) {
+ TAt3PEnc::ParseAdvancedOpt(advancedOpt, settings);
+ }
+ atracProcessor->reset(new TAt3PEnc(std::move(omaIO), numChannels, settings));
}
int main_(int argc, char* const* argv)
{
const char* myName = argv[0];
+ const char* advancedOpt = nullptr;
static struct option longopts[] = {
{ "encode", optional_argument, NULL, O_ENCODE },
{ "decode", no_argument, NULL, O_DECODE },
@@ -317,6 +324,7 @@ int main_(int argc, char* const* argv)
{ "notransient", optional_argument, NULL, O_NOTRANSIENT},
{ "nostdout", no_argument, NULL, O_NOSTDOUT},
{ "nogaincontrol", no_argument, NULL, O_NOGAINCONTROL},
+ { "advanced", required_argument, NULL, O_ADVANCED_OPT},
{ NULL, 0, NULL, 0}
};
@@ -399,6 +407,9 @@ int main_(int argc, char* const* argv)
case O_NOGAINCONTROL:
noGainControl = true;
break;
+ case O_ADVANCED_OPT:
+ advancedOpt = optarg;
+ break;
default:
printUsage(myName);
return 1;
@@ -466,7 +477,7 @@ int main_(int argc, char* const* argv)
{
wavIO = OpenWavFile(inFile);
PrepareAtrac3PEncoder(inFile, outFile, noStdOut, wavIO->GetChannelNum(),
- &totalSamples, wavIO, &pcmEngine, &atracProcessor);
+ &totalSamples, wavIO, &pcmEngine, &atracProcessor, advancedOpt);
pcmFrameSz = 2048;
}
break;