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

Precompute sync up/down bands to optimize search performance.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 65608419
...@@ -804,57 +804,68 @@ normalize_sync_quality (double raw_quality) ...@@ -804,57 +804,68 @@ normalize_sync_quality (double raw_quality)
return raw_quality / min (Params::water_delta, 0.080) / 2.9; return raw_quality / min (Params::water_delta, 0.080) / 2.9;
} }
double class SyncFinder
sync_decode (const WavData& wav_data, vector<vector<complex<float>>>& fft_out, vector<vector<complex<float>>>& fft_orig_out)
{ {
// FIXME: is copypasted vector<vector<int>> up;
const int frame_count = mark_sync_frame_count(); vector<vector<int>> down;
public:
double umag = 0, dmag = 0; SyncFinder()
double sync_quality = 0; {
up.resize (mark_sync_frame_count());
for (int f = 0; f < frame_count; f++) down.resize (mark_sync_frame_count());
{
for (int ch = 0; ch < wav_data.n_channels(); ch++) for (size_t i = 0; i < mark_sync_frame_count(); i++)
{ get_up_down (i, up[i], down[i]);
const size_t index = f * wav_data.n_channels() + ch; }
vector<int> up; double
vector<int> down; sync_decode (const WavData& wav_data, vector<vector<complex<float>>>& fft_out, vector<vector<complex<float>>>& fft_orig_out)
get_up_down (f, up, down); {
// FIXME: is copypasted
const double min_db = -96; const int frame_count = mark_sync_frame_count();
for (auto u : up)
{ double umag = 0, dmag = 0;
umag += db_from_factor (abs (fft_out[index][u]), min_db); double sync_quality = 0;
if (index < fft_orig_out.size()) for (int f = 0; f < frame_count; f++)
umag -= db_from_factor (abs (fft_orig_out[index][u]), min_db); {
} for (int ch = 0; ch < wav_data.n_channels(); ch++)
for (auto d : down) {
{ const size_t index = f * wav_data.n_channels() + ch;
dmag += db_from_factor (abs (fft_out[index][d]), min_db);
const double min_db = -96;
if (index < fft_orig_out.size()) for (auto u : up[f])
dmag -= db_from_factor (abs (fft_orig_out[index][d]), min_db); {
} umag += db_from_factor (abs (fft_out[index][u]), min_db);
}
if ((f % Params::sync_frames_per_bit) == (Params::sync_frames_per_bit - 1)) if (index < fft_orig_out.size())
{ umag -= db_from_factor (abs (fft_orig_out[index][u]), min_db);
const int data_bit = (umag < dmag) ? 0 : 1; }
const int expect_data_bit = (f / Params::sync_frames_per_bit) & 1; /* expect 010101 */ for (auto d : down[f])
if (data_bit != expect_data_bit) {
return 0; dmag += db_from_factor (abs (fft_out[index][d]), min_db);
const double q = expect_data_bit ? (1 - umag / dmag) : (umag / dmag - 1); if (index < fft_orig_out.size())
sync_quality += q; dmag -= db_from_factor (abs (fft_orig_out[index][d]), min_db);
umag = 0; }
dmag = 0; }
} if ((f % Params::sync_frames_per_bit) == (Params::sync_frames_per_bit - 1))
} {
sync_quality /= Params::sync_bits; const int data_bit = (umag < dmag) ? 0 : 1;
sync_quality = normalize_sync_quality (sync_quality); const int expect_data_bit = (f / Params::sync_frames_per_bit) & 1; /* expect 010101 */
return sync_quality; if (data_bit != expect_data_bit)
} return 0;
const double q = expect_data_bit ? (1 - umag / dmag) : (umag / dmag - 1);
sync_quality += q;
umag = 0;
dmag = 0;
}
}
sync_quality /= Params::sync_bits;
sync_quality = normalize_sync_quality (sync_quality);
return sync_quality;
}
};
vector<vector<complex<float>>> vector<vector<complex<float>>>
sync_fft (const WavData& wav_data, size_t index, size_t count) sync_fft (const WavData& wav_data, size_t index, size_t count)
...@@ -895,6 +906,8 @@ find_closest_sync (size_t index) ...@@ -895,6 +906,8 @@ find_closest_sync (size_t index)
int int
decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<vector<complex<float>>>& fft_out, vector<vector<complex<float>>>& fft_orig_out) decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<vector<complex<float>>>& fft_out, vector<vector<complex<float>>>& fft_orig_out)
{ {
SyncFinder sync_finder;
struct SyncScore { struct SyncScore {
size_t index; size_t index;
double quality; double quality;
...@@ -915,7 +928,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v ...@@ -915,7 +928,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v
{ {
vector<vector<complex<float>>> fft_out_range = get_frame_range (wav_data, fft_sync_shift_out[sync_shift / 128], start_frame, mark_sync_frame_count()); vector<vector<complex<float>>> fft_out_range = get_frame_range (wav_data, fft_sync_shift_out[sync_shift / 128], start_frame, mark_sync_frame_count());
double quality = sync_decode (wav_data, fft_out_range, /* FIXME: non-blind */ fft_orig_out); double quality = sync_finder.sync_decode (wav_data, fft_out_range, /* FIXME: non-blind */ fft_orig_out);
// printf ("%zd %f\n", sync_index, quality); // printf ("%zd %f\n", sync_index, quality);
sync_scores.emplace_back (SyncScore { sync_index, quality }); sync_scores.emplace_back (SyncScore { sync_index, quality });
} }
...@@ -937,7 +950,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v ...@@ -937,7 +950,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v
if (sync_scores[i].quality > q_last && sync_scores[i].quality > q_next) if (sync_scores[i].quality > q_last && sync_scores[i].quality > q_next)
{ {
printf ("%zd %s %f\n", sync_scores[i].index, find_closest_sync (sync_scores[i].index), sync_scores[i].quality); printf ("%zd %s %f", sync_scores[i].index, find_closest_sync (sync_scores[i].index), sync_scores[i].quality);
// refine match // refine match
double best_quality = sync_scores[i].quality; double best_quality = sync_scores[i].quality;
...@@ -951,7 +964,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v ...@@ -951,7 +964,7 @@ decode_and_report (const WavData& wav_data, const string& orig_pattern, vector<v
vector<vector<complex<float>>> fft_out_range = sync_fft (wav_data, fine_index, mark_sync_frame_count()); vector<vector<complex<float>>> fft_out_range = sync_fft (wav_data, fine_index, mark_sync_frame_count());
if (fft_out_range.size()) if (fft_out_range.size())
{ {
double q = sync_decode (wav_data, fft_out_range, fft_orig_out); double q = sync_finder.sync_decode (wav_data, fft_out_range, fft_orig_out);
if (q > best_quality) if (q > best_quality)
{ {
......
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