static std::vector<float> train_snap_points;
static bool do_train = false;
+// The frequency to filter on (for do_auto_level), in Hertz.
+// Larger values makes the compressor react faster, but if it is too large,
+// you'll ruin the waveforms themselves.
+static float auto_level_freq = 200.0;
+
// The minimum estimated sound level (for do_auto_level) at any given point.
// If you decrease this, you'll be able to amplify really silent signals
// by more, but you'll also increase the level of silent (ie. noise-only) segments,
static struct option long_options[] = {
{"auto-level", 0, 0, 'a' },
+ {"auto-level-freq", required_argument, 0, 'b' },
{"output-leveled", 0, 0, 'A' },
{"min-level", required_argument, 0, 'm' },
{"no-calibrate", 0, 0, 's' },
fprintf(stderr, "decode [OPTIONS] AUDIO-FILE > TAP-FILE\n");
fprintf(stderr, "\n");
fprintf(stderr, " -a, --auto-level automatically adjust amplitude levels throughout the file\n");
+ fprintf(stderr, " -b, --auto-level-freq minimum frequency in Hertz of corrected level changes (default 200 Hz)\n");
fprintf(stderr, " -A, --output-leveled output leveled waveform to leveled.raw\n");
fprintf(stderr, " -m, --min-level minimum estimated sound level (0..32768) for --auto-level\n");
fprintf(stderr, " -s, --no-calibrate do not try to calibrate on sync pulse length\n");
{
for ( ;; ) {
int option_index = 0;
- int c = getopt_long(argc, argv, "aAm:spl:f:r:Fc:t:qh", long_options, &option_index);
+ int c = getopt_long(argc, argv, "ab:Am:spl:f:r:Fc:t:qh", long_options, &option_index);
if (c == -1)
break;
do_auto_level = true;
break;
+ case 'b':
+ auto_level_freq = atof(optarg);
+ break;
+
case 'A':
output_leveled = true;
break;
}
if (do_auto_level) {
- pcm = level_samples(pcm, min_level, sample_rate);
+ pcm = level_samples(pcm, min_level, auto_level_freq, sample_rate);
if (output_leveled) {
FILE *fp = fopen("leveled.raw", "wb");
fwrite(pcm.data(), pcm.size() * sizeof(pcm[0]), 1, fp);
#include "filter.h"
-// The frequency to filter on, in Hertz. Larger values makes the
-// compressor react faster, but if it is too large, you'll
-// ruin the waveforms themselves.
-#define LPFILTER_FREQ 50.0
-
// A final scalar to get the audio within approximately the right range.
// Increase to _lower_ overall volume.
#define DAMPENING_FACTOR 5.0
// 6dB/oct per round.
#define FILTER_DEPTH 4
-std::vector<float> level_samples(const std::vector<float> &pcm, float min_level, int sample_rate)
+std::vector<float> level_samples(const std::vector<float> &pcm, float min_level, float lpfilter_freq, int sample_rate)
{
// filter forwards, then backwards (perfect phase filtering)
std::vector<float> filtered_samples, refiltered_samples, leveled_samples;
refiltered_samples.resize(pcm.size());
leveled_samples.resize(pcm.size());
- Filter filter = Filter::lpf(2.0 * M_PI * LPFILTER_FREQ / sample_rate);
+ Filter filter = Filter::lpf(2.0 * M_PI * lpfilter_freq / sample_rate);
for (unsigned i = 0; i < pcm.size(); ++i) {
filtered_samples[i] = filter.update(fabs(pcm[i]));
}