Commit 7a6da198 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Support more than one --key / --test-key option for audiowmark get/cmp.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 2269477f
......@@ -449,29 +449,38 @@ public:
}
return false;
}
bool
parse_opt (const string& option, string& out_s)
vector<string>
parse_multi_opt (const string& option)
{
bool found_option = false;
vector<string> values;
auto it = m_args.begin();
while (it != m_args.end())
{
auto next_it = it + 1;
if (*it == option && next_it != m_args.end()) /* --option foo */
{
out_s = *next_it;
values.push_back (*next_it);
next_it = m_args.erase (it, it + 2);
found_option = true;
}
else if (starts_with (*it, (option + "="))) /* --option=foo */
{
out_s = it->substr (option.size() + 1);
values.push_back (it->substr (option.size() + 1));
next_it = m_args.erase (it);
found_option = true;
}
it = next_it;
}
return found_option;
return values;
}
bool
parse_opt (const string& option, string& out_s)
{
vector<string> values = parse_multi_opt (option);
if (values.size())
{
out_s = values.back();
return true;
}
return false;
}
bool
parse_opt (const string& option, int& out_i)
......@@ -561,6 +570,32 @@ parse_shared_options (ArgParser& ap)
}
}
vector<Key>
parse_key_list (ArgParser& ap)
{
vector<Key> key_list;
vector<string> key_files = ap.parse_multi_opt ("--key");
for (auto f : key_files)
{
Key key;
key.load_key (f);
key_list.push_back (key);
}
vector<string> test_keys = ap.parse_multi_opt ("--test-key");
for (auto t : test_keys)
{
Key key;
key.set_test_key (atoi (t.c_str()));
key_list.push_back (key);
}
if (key_list.empty())
{
Key key; // default initialized with zero key
key_list.push_back (key);
}
return key_list;
}
Key
parse_key (ArgParser& ap)
{
......@@ -812,9 +847,9 @@ main (int argc, char **argv)
parse_shared_options (ap);
parse_get_options (ap);
Key key = parse_key (ap); // TODO: key list
vector<Key> key_list = parse_key_list (ap);
args = parse_positional (ap, "watermarked_wav");
return get_watermark (key, args[0], /* no ber */ "");
return get_watermark (key_list, args[0], /* no ber */ "");
}
else if (ap.parse_cmd ("cmp"))
{
......@@ -823,9 +858,9 @@ main (int argc, char **argv)
ap.parse_opt ("--expect-matches", Params::expect_matches);
Key key = parse_key (ap); // TODO: key list
vector<Key> key_list = parse_key_list (ap);
args = parse_positional (ap, "watermarked_wav", "message_hex");
return get_watermark (key, args[0], args[1]);
return get_watermark (key_list, args[0], args[1]);
}
else if (ap.parse_cmd ("gen-key"))
{
......
......@@ -215,6 +215,6 @@ db_from_complex (std::complex<float> f, float min_dB)
int add_stream_watermark (const Key& key, AudioInputStream *in_stream, AudioOutputStream *out_stream, const std::string& bits, size_t zero_frames);
int add_watermark (const Key& key, const std::string& infile, const std::string& outfile, const std::string& bits);
int get_watermark (const Key& key, const std::string& infile, const std::string& orig_pattern);
int get_watermark (const std::vector<Key>& key_list, const std::string& infile, const std::string& orig_pattern);
#endif /* AUDIOWMARK_WM_COMMON_HH */
......@@ -581,49 +581,52 @@ public:
};
static int
decode_and_report (const Key& key, const WavData& wav_data, const vector<int>& orig_bits)
decode_and_report (const vector<Key>& key_list, const WavData& wav_data, const vector<int>& orig_bits)
{
ResultSet result_set;
double speed = 1.0;
/*
* The strategy for integrating speed detection into decoding is this:
* - we always (unconditionally) try to decode the watermark on the original wav data
* - if detected speed is somewhat different than 1.0, we also try to decode stretched data
* - we report all normal and speed results we get
*
* The reason to do it this way is that the detected speed may be wrong (on short clips)
* and we don't want to loose a successful clip decoder match in this case.
*/
if (Params::detect_speed || Params::detect_speed_patient || Params::try_speed > 0)
for (auto key : key_list)
{
if (Params::detect_speed || Params::detect_speed_patient)
speed = detect_speed (key, wav_data, !orig_bits.empty());
else
speed = Params::try_speed;
// speeds closer to 1.0 than this usually work without stretching before decode
if (speed < 0.9999 || speed > 1.0001)
/*
* The strategy for integrating speed detection into decoding is this:
* - we always (unconditionally) try to decode the watermark on the original wav data
* - if detected speed is somewhat different than 1.0, we also try to decode stretched data
* - we report all normal and speed results we get
*
* The reason to do it this way is that the detected speed may be wrong (on short clips)
* and we don't want to loose a successful clip decoder match in this case.
*/
if (Params::detect_speed || Params::detect_speed_patient || Params::try_speed > 0)
{
if (Params::json_output != "-")
printf ("speed %.6f\n", speed);
WavData wav_data_speed = resample (wav_data, Params::mark_sample_rate * speed);
if (Params::detect_speed || Params::detect_speed_patient)
speed = detect_speed (key, wav_data, !orig_bits.empty());
else
speed = Params::try_speed;
// speeds closer to 1.0 than this usually work without stretching before decode
if (speed < 0.9999 || speed > 1.0001)
{
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);
BlockDecoder block_decoder;
block_decoder.run (key, wav_data_speed, result_set);
result_set.set_speed_pattern (true);
BlockDecoder block_decoder;
block_decoder.run (key, wav_data_speed, result_set);
ClipDecoder clip_decoder;
clip_decoder.run (key, wav_data_speed, result_set);
result_set.set_speed_pattern (false);
ClipDecoder clip_decoder;
clip_decoder.run (key, wav_data_speed, result_set);
result_set.set_speed_pattern (false);
}
}
}
BlockDecoder block_decoder;
block_decoder.run (key, wav_data, result_set);
BlockDecoder block_decoder;
block_decoder.run (key, wav_data, result_set);
ClipDecoder clip_decoder;
clip_decoder.run (key, wav_data, result_set);
ClipDecoder clip_decoder;
clip_decoder.run (key, wav_data, result_set);
}
result_set.sort_by_time();
......@@ -637,7 +640,7 @@ decode_and_report (const Key& key, const WavData& wav_data, const vector<int>& o
{
int match_count = result_set.print_match_count (orig_bits);
block_decoder.print_debug_sync();
// block_decoder.print_debug_sync(); FIXME
if (Params::expect_matches >= 0)
{
......@@ -655,7 +658,7 @@ decode_and_report (const Key& key, const WavData& wav_data, const vector<int>& o
}
int
get_watermark (const Key& key, const string& infile, const string& orig_pattern)
get_watermark (const vector<Key>& key_list, const string& infile, const string& orig_pattern)
{
vector<int> orig_bitvec;
if (!orig_pattern.empty())
......@@ -686,10 +689,10 @@ get_watermark (const Key& key, const string& infile, const string& orig_pattern)
}
if (wav_data.sample_rate() == Params::mark_sample_rate)
{
return decode_and_report (key, wav_data, orig_bitvec);
return decode_and_report (key_list, wav_data, orig_bitvec);
}
else
{
return decode_and_report (key, resample (wav_data, Params::mark_sample_rate), orig_bitvec);
return decode_and_report (key_list, resample (wav_data, Params::mark_sample_rate), orig_bitvec);
}
}
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