Commit da3e6d45 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Support changing watermarking parameters using command line args.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 0c798b17
......@@ -7,6 +7,10 @@
#include "fft.hh"
#include "wavdata.hh"
#include <assert.h>
#include "config.h"
using std::string;
using std::vector;
using std::complex;
......@@ -14,15 +18,144 @@ using std::min;
namespace Params
{
static constexpr int frame_size = 1024;
static constexpr int frames_per_bit = 4;
static constexpr int bands_per_frame = 30;
static constexpr int max_band = 100;
static constexpr int min_band = 20;
static constexpr double water_delta = 0.015; // strength of the watermark
static constexpr double pre_scale = 0.75; // rescale the signal to avoid clipping after watermark is added
static size_t frame_size = 1024;
static int frames_per_bit = 4;
static int bands_per_frame = 30;
static int max_band = 100;
static int min_band = 20;
static double water_delta = 0.015; // strength of the watermark
static double pre_scale = 0.75; // rescale the signal to avoid clipping after watermark is added
}
void
print_usage()
{
printf ("usage: audiowmark <command> [ <args>... ]\n");
printf ("\n");
printf ("Commands:\n");
printf (" * create a watermarked wav file with a message\n");
printf (" audiowmark add <input_wav> <watermarked_wav> <message_hex>\n");
printf ("\n");
printf (" * blind decoding (retrieve message without original file)\n");
printf (" audiowmark get <watermarked_wav>\n");
printf ("\n");
printf (" * compute bit error rate for blind decoding\n");
printf (" audiowmark cmp <watermarked_wav> <message_hex>\n");
printf ("\n");
printf (" * retrieve message with original file\n");
printf (" audiowmark get-delta <input_wav> <watermarked_wav>\n");
printf ("\n");
printf (" * compute bit error rate for decoding with original file\n");
printf (" audiowmark cmp-delta <input_wav> <watermarked_wav> <message_hex>\n");
printf ("\n");
printf ("Global options:\n");
printf (" --frame-size frame size (must be power of 2) [%zd]\n", Params::frame_size);
printf (" --frames-per-bit number of frames per bit [%d]\n", Params::frames_per_bit);
printf (" --water-delta set watermarking delta [%.4f]\n", Params::water_delta);
printf (" --pre-scale set scaling used for normalization [%.3f]\n", Params::pre_scale);
}
static bool
check_arg (uint argc,
char *argv[],
uint *nth,
const char *opt, /* for example: --foo */
const char **opt_arg = nullptr) /* if foo needs an argument, pass a pointer to get the argument */
{
assert (opt != nullptr);
assert (*nth < argc);
const char *arg = argv[*nth];
if (!arg)
return false;
uint opt_len = strlen (opt);
if (strcmp (arg, opt) == 0)
{
if (opt_arg && *nth + 1 < argc) /* match foo option with argument: --foo bar */
{
argv[(*nth)++] = nullptr;
*opt_arg = argv[*nth];
argv[*nth] = nullptr;
return true;
}
else if (!opt_arg) /* match foo option without argument: --foo */
{
argv[*nth] = nullptr;
return true;
}
/* fall through to error message */
}
else if (strncmp (arg, opt, opt_len) == 0 && arg[opt_len] == '=')
{
if (opt_arg) /* match foo option with argument: --foo=bar */
{
*opt_arg = arg + opt_len + 1;
argv[*nth] = nullptr;
return true;
}
/* fall through to error message */
}
else
return false;
print_usage();
exit (1);
}
void
parse_options (int *argc_p,
char **argv_p[])
{
uint argc = *argc_p;
char **argv = *argv_p;
unsigned int i, e;
for (i = 1; i < argc; i++)
{
const char *opt_arg;
if (strcmp (argv[i], "--help") == 0 ||
strcmp (argv[i], "-h") == 0)
{
print_usage();
exit (0);
}
else if (strcmp (argv[i], "--version") == 0 || strcmp (argv[i], "-v") == 0)
{
printf ("audiowmark %s\n", VERSION);
exit (0);
}
else if (check_arg (argc, argv, &i, "--frame-size", &opt_arg))
{
Params::frame_size = atoi (opt_arg);
}
else if (check_arg (argc, argv, &i, "--frames-per-bit", &opt_arg))
{
Params::frames_per_bit = atoi (opt_arg);
}
else if (check_arg (argc, argv, &i, "--water-delta", &opt_arg))
{
Params::water_delta = atof (opt_arg);
}
else if (check_arg (argc, argv, &i, "--pre-scale", &opt_arg))
{
Params::pre_scale = atof (opt_arg);
}
}
/* resort argc/argv */
e = 1;
for (i = 1; i < argc; i++)
if (argv[i])
{
argv[e++] = argv[i];
if (i >= e)
argv[i] = nullptr;
}
*argc_p = e;
}
inline double
window_cos (double x) /* von Hann window */
{
......@@ -203,7 +336,7 @@ watermark_frame (const vector<float>& input_frame, int f, int data_bit)
vector<float> fft_delta_out = ifft (fft_delta_spect);
vector<float> synth_window (Params::frame_size);
for (int i = 0; i < Params::frame_size; i++)
for (size_t i = 0; i < Params::frame_size; i++)
{
const double threshold = 0.2;
......@@ -520,6 +653,8 @@ get_snr (const string& origfile, const string& wmfile)
int
main (int argc, char **argv)
{
parse_options (&argc, &argv);
string op = (argc >= 2) ? argv[1] : "";
if (op == "add" && argc == 5)
......
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