Commit a383c9c5 authored by Tim Janik's avatar Tim Janik

SRC: audiowmark.cc: write --json output into an output file

Restore the ability to print out detection and debug info, while
writing the detection results into a separate file in JSON format.
Signed-off-by: 's avatarTim Janik <timj@gnu.org>
parent 696421cf
...@@ -58,7 +58,7 @@ print_usage() ...@@ -58,7 +58,7 @@ print_usage()
printf ("\n"); printf ("\n");
printf ("Global options:\n"); printf ("Global options:\n");
printf (" --strength <s> set watermark strength [%.6g]\n", Params::water_delta * 1000); printf (" --strength <s> set watermark strength [%.6g]\n", Params::water_delta * 1000);
printf (" --json produce JSON output\n"); printf (" --json <file> write JSON results into file\n");
printf (" --linear disable non-linear bit storage\n"); printf (" --linear disable non-linear bit storage\n");
printf (" --short <bits> enable short payload mode\n"); printf (" --short <bits> enable short payload mode\n");
printf (" --key <file> load watermarking key from file\n"); printf (" --key <file> load watermarking key from file\n");
...@@ -457,9 +457,9 @@ parse_shared_options (ArgParser& ap) ...@@ -457,9 +457,9 @@ parse_shared_options (ArgParser& ap)
{ {
Params::water_delta = f / 1000; Params::water_delta = f / 1000;
} }
if (ap.parse_opt ("--json")) if (ap.parse_opt ("--json", s))
{ {
Params::json_output = true; Params::json_output = s;
} }
if (ap.parse_opt ("--key", s)) if (ap.parse_opt ("--key", s))
{ {
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
int Params::frames_per_bit = 2; int Params::frames_per_bit = 2;
double Params::water_delta = 0.01; double Params::water_delta = 0.01;
bool Params::json_output = false;
bool Params::mix = true; bool Params::mix = true;
bool Params::hard = false; // hard decode bits? (soft decoding is better) bool Params::hard = false; // hard decode bits? (soft decoding is better)
bool Params::snr = false; // compute/show snr while adding watermark bool Params::snr = false; // compute/show snr while adding watermark
...@@ -44,6 +43,7 @@ RawFormat Params::raw_output_format; ...@@ -44,6 +43,7 @@ RawFormat Params::raw_output_format;
int Params::hls_bit_rate = 0; int Params::hls_bit_rate = 0;
std::string Params::json_output;
std::string Params::input_label; std::string Params::input_label;
std::string Params::output_label; std::string Params::output_label;
......
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
static constexpr int min_band = 20; static constexpr int min_band = 20;
static double water_delta; static double water_delta;
static bool json_output; static std::string json_output;
static bool mix; static bool mix;
static bool hard; // hard decode bits? (soft decoding is better) static bool hard; // hard decode bits? (soft decoding is better)
static bool snr; // compute/show snr while adding watermark static bool snr; // compute/show snr while adding watermark
......
...@@ -167,8 +167,14 @@ public: ...@@ -167,8 +167,14 @@ public:
patterns.push_back (p); patterns.push_back (p);
} }
void void
print_json (const WavData& wav_data) print_json (const WavData& wav_data, const std::string &json_file)
{ {
FILE *outfile = fopen (json_file.c_str(), "w");
if (!outfile)
{
perror (("audiowmark: failed to open \"" + json_file + "\":").c_str());
exit (127);
}
std::stable_sort (patterns.begin(), patterns.end(), [](const Pattern& p1, const Pattern& p2) { std::stable_sort (patterns.begin(), patterns.end(), [](const Pattern& p1, const Pattern& p2) {
const int all1 = p1.type == Type::ALL; const int all1 = p1.type == Type::ALL;
const int all2 = p2.type == Type::ALL; const int all2 = p2.type == Type::ALL;
...@@ -178,18 +184,18 @@ public: ...@@ -178,18 +184,18 @@ public:
return p1.sync_score.index < p2.sync_score.index; return p1.sync_score.index < p2.sync_score.index;
}); });
const size_t time_length = (wav_data.samples().size() / wav_data.n_channels() + wav_data.sample_rate()/2) / wav_data.sample_rate(); const size_t time_length = (wav_data.samples().size() / wav_data.n_channels() + wav_data.sample_rate()/2) / wav_data.sample_rate();
printf ("{ \"length\": \"%ld:%02ld\",\n", time_length / 60, time_length % 60); fprintf (outfile, "{ \"length\": \"%ld:%02ld\",\n", time_length / 60, time_length % 60);
printf (" \"matches\": [\n"); fprintf (outfile, " \"matches\": [\n");
int nth = 0; int nth = 0;
for (const auto& pattern : patterns) for (const auto& pattern : patterns)
{ {
if (nth++ != 0) if (nth++ != 0)
printf (",\n"); fprintf (outfile, ",\n");
if (pattern.type == Type::ALL) /* this is the combined pattern "all" */ if (pattern.type == Type::ALL) /* this is the combined pattern "all" */
{ {
printf (" { \"pos\": \"0:00\", \"bits\": \"%s\", \"quality\": %.5f, \"error\": %.6f, \"clip\": false, \"type\": \"ALL\" }", fprintf (outfile, " { \"pos\": \"0:00\", \"bits\": \"%s\", \"quality\": %.5f, \"error\": %.6f, \"clip\": false, \"type\": \"ALL\" }",
bit_vec_to_str (pattern.bit_vec).c_str(), bit_vec_to_str (pattern.bit_vec).c_str(),
pattern.sync_score.quality, pattern.decode_error); pattern.sync_score.quality, pattern.decode_error);
} }
else else
{ {
...@@ -201,14 +207,15 @@ public: ...@@ -201,14 +207,15 @@ public:
case ConvBlockType::ab: blockc = "\"AB\""; break; case ConvBlockType::ab: blockc = "\"AB\""; break;
} }
const int seconds = pattern.sync_score.index / Params::mark_sample_rate; const int seconds = pattern.sync_score.index / Params::mark_sample_rate;
printf (" { \"pos\": \"%d:%02d\", \"bits\": \"%s\", \"quality\": %.5f, \"error\": %.6f, \"clip\": %s, \"type\": %s }", fprintf (outfile, " { \"pos\": \"%d:%02d\", \"bits\": \"%s\", \"quality\": %.5f, \"error\": %.6f, \"clip\": %s, \"type\": %s }",
seconds / 60, seconds % 60, seconds / 60, seconds % 60,
bit_vec_to_str (pattern.bit_vec).c_str(), bit_vec_to_str (pattern.bit_vec).c_str(),
pattern.sync_score.quality, pattern.decode_error, pattern.sync_score.quality, pattern.decode_error,
pattern.type == Type::CLIP ? "true" : "false", blockc); pattern.type == Type::CLIP ? "true" : "false", blockc);
} }
} }
printf (" ]\n}\n"); fprintf (outfile, " ]\n}\n");
fclose (outfile);
} }
void void
print() print()
...@@ -619,11 +626,12 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern) ...@@ -619,11 +626,12 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern)
ClipDecoder clip_decoder; ClipDecoder clip_decoder;
clip_decoder.run (wav_data, result_set); clip_decoder.run (wav_data, result_set);
if (Params::json_output) if (!Params::json_output.empty())
{ result_set.print_json (wav_data, Params::json_output);
result_set.print_json (wav_data);
} result_set.print();
else if (!orig_pattern.empty())
if (!orig_pattern.empty())
{ {
int match_count = result_set.print_match_count (orig_pattern); int match_count = result_set.print_match_count (orig_pattern);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment