Commit 83e9291d authored by Stefan Westerfeld's avatar Stefan Westerfeld

Merge branch 'json'

parents 09e50c8d 4e5a8574
Overview of Changes in audiowmark-0.6.0:
* implement speed detection/correction (--detect-speed)
* Add '--json' CLI option for machine readable results.
Overview of Changes in audiowmark-0.5.0:
......
......@@ -132,6 +132,9 @@ Set the watermarking strength (see <<strength>>).
--detect-speed::
Detect and correct replay speed difference (see <<speed>>).
--json <file>::
Write results to <file> in machine readable JSON format.
[[key]]
== Watermark Key
......
......@@ -41,6 +41,7 @@ using std::max;
void
print_usage()
{
// 01234567891123456789212345678931234567894123456789512345678961234567897123456789
printf ("usage: audiowmark <command> [ <args>... ]\n");
printf ("\n");
printf ("Commands:\n");
......@@ -57,11 +58,12 @@ print_usage()
printf (" audiowmark gen-key <key_file>\n");
printf ("\n");
printf ("Global options:\n");
printf (" --strength <s> set watermark strength [%.6g]\n", Params::water_delta * 1000);
printf (" --detect-speed detect and correct replay speed difference (get & cmp)\n");
printf (" --json <file> write JSON results into file (get & cmp)\n");
printf (" --key <file> load watermarking key from file\n");
printf (" --linear disable non-linear bit storage\n");
printf (" --short <bits> enable short payload mode\n");
printf (" --key <file> load watermarking key from file\n");
printf (" --detect-speed detect/correct replay speed difference (get/cmp)\n");
printf (" --strength <s> set watermark strength [%.6g]\n", Params::water_delta * 1000);
printf (" -q, --quiet disable information messages\n");
printf ("\n");
printf (" --input-format raw use raw stream as input\n");
......@@ -456,6 +458,10 @@ parse_shared_options (ArgParser& ap)
{
Params::water_delta = f / 1000;
}
if (ap.parse_opt ("--json", s))
{
Params::json_output = s;
}
if (ap.parse_opt ("--key", s))
{
Params::have_key++;
......
......@@ -43,6 +43,7 @@ RawFormat Params::raw_output_format;
int Params::hls_bit_rate = 0;
std::string Params::json_output;
std::string Params::input_label;
std::string Params::output_label;
......
......@@ -40,6 +40,7 @@ public:
static constexpr int min_band = 20;
static double water_delta;
static std::string json_output;
static bool mix;
static bool hard; // hard decode bits? (soft decoding is better)
static bool snr; // compute/show snr while adding watermark
......
......@@ -167,6 +167,58 @@ public:
patterns.push_back (p);
}
void
print_json (const WavData& wav_data, const std::string &json_file, const double speed)
{
FILE *outfile = fopen (json_file == "-" ? "/dev/stdout" : 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) {
const int all1 = p1.type == Type::ALL;
const int all2 = p2.type == Type::ALL;
if (all1 != all2)
return all1 < all2;
else
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();
fprintf (outfile, "{ \"length\": \"%ld:%02ld\",\n", time_length / 60, time_length % 60);
fprintf (outfile, " \"speed\": %.6f,\n", speed);
fprintf (outfile, " \"matches\": [\n");
int nth = 0;
for (const auto& pattern : patterns)
{
if (nth++ != 0)
fprintf (outfile, ",\n");
std::string btype;
switch (pattern.sync_score.block_type)
{
case ConvBlockType::a: btype = "A"; break;
case ConvBlockType::b: btype = "B"; break;
case ConvBlockType::ab: btype = "AB"; break;
}
if (pattern.type == Type::ALL)
btype = "ALL";
if (pattern.type == Type::CLIP)
btype = "CLIP-" + btype;
if (pattern.speed_pattern)
btype += "-SPEED";
const int seconds = pattern.type == Type::ALL ? 0 : pattern.sync_score.index / Params::mark_sample_rate;
fprintf (outfile, " { \"pos\": \"%d:%02d\", \"bits\": \"%s\", \"quality\": %.5f, \"error\": %.6f, \"type\": \"%s\" }",
seconds / 60, seconds % 60,
bit_vec_to_str (pattern.bit_vec).c_str(),
pattern.sync_score.quality, pattern.decode_error,
btype.c_str());
}
fprintf (outfile, " ]\n}\n");
fclose (outfile);
}
void
print()
{
std::stable_sort (patterns.begin(), patterns.end(), [](const Pattern& p1, const Pattern& p2) {
......@@ -539,6 +591,7 @@ static int
decode_and_report (const WavData& wav_data, const string& orig_pattern)
{
ResultSet result_set;
double speed = 1.0;
/*
* The strategy for integrating speed detection into decoding is this:
......@@ -551,12 +604,13 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern)
*/
if (Params::detect_speed)
{
double speed = detect_speed (wav_data, !orig_pattern.empty());
speed = detect_speed (wav_data, !orig_pattern.empty());
// speeds closer to 1.0 than this usually work without stretching before decode
if (speed < 0.9999 || speed > 1.0001)
{
printf ("speed %.6f\n", speed);
if (Params::json_output != "-")
printf ("speed %.6f\n", speed);
WavData wav_data_speed = resample (wav_data, Params::mark_sample_rate * speed);
result_set.set_speed_pattern (true);
......@@ -574,7 +628,12 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern)
ClipDecoder clip_decoder;
clip_decoder.run (wav_data, result_set);
result_set.print();
if (!Params::json_output.empty())
result_set.print_json (wav_data, Params::json_output, speed);
if (Params::json_output != "-")
result_set.print();
if (!orig_pattern.empty())
{
......
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