Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
audiowmark
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
audiowmark
Commits
95f008b9
Commit
95f008b9
authored
Jan 13, 2024
by
Stefan Westerfeld
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move key list loop into SyncFinder/BlockDecoder/ClipDecoder.
Signed-off-by:
Stefan Westerfeld
<
stefan@space.twc.de
>
parent
3949cd7d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
222 additions
and
175 deletions
+222
-175
syncfinder.cc
src/syncfinder.cc
+59
-33
syncfinder.hh
src/syncfinder.hh
+14
-7
wmget.cc
src/wmget.cc
+149
-135
No files found.
src/syncfinder.cc
View file @
95f008b9
...
...
@@ -26,10 +26,10 @@ using std::vector;
using
std
::
string
;
using
std
::
min
;
v
oid
v
ector
<
vector
<
SyncFinder
::
FrameBit
>>
SyncFinder
::
init_up_down
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
)
{
sync_bits
.
clear
()
;
vector
<
vector
<
SyncFinder
::
FrameBit
>>
sync_bits
;
// "long" blocks consist of two "normal" blocks, which means
// the sync bits pattern is repeated after the end of the first block
...
...
@@ -76,6 +76,7 @@ SyncFinder::init_up_down (const Key& key, const WavData& wav_data, Mode mode)
std
::
sort
(
frame_bits
.
begin
(),
frame_bits
.
end
(),
[]
(
FrameBit
&
f1
,
FrameBit
&
f2
)
{
return
f1
.
frame
<
f2
.
frame
;
});
sync_bits
.
push_back
(
frame_bits
);
}
return
sync_bits
;
}
/* safe to call from any thread */
...
...
@@ -116,7 +117,8 @@ SyncFinder::bit_quality (float umag, float dmag, int bit)
}
double
SyncFinder
::
sync_decode
(
const
WavData
&
wav_data
,
const
size_t
start_frame
,
SyncFinder
::
sync_decode
(
const
vector
<
vector
<
FrameBit
>>&
sync_bits
,
const
WavData
&
wav_data
,
const
size_t
start_frame
,
const
vector
<
float
>&
fft_out_db
,
const
vector
<
char
>&
have_frames
,
ConvBlockType
*
block_type
)
...
...
@@ -179,12 +181,22 @@ SyncFinder::scan_silence (const WavData& wav_data)
wav_data_last
--
;
}
vector
<
SyncFinder
::
Score
>
SyncFinder
::
search_approx
(
const
WavData
&
wav_data
,
Mode
mode
)
vector
<
SyncFinder
::
KeyResult
>
SyncFinder
::
search_approx
(
const
std
::
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
)
{
vector
<
float
>
fft_db
;
vector
<
char
>
have_frames
;
vector
<
Score
>
sync_scores
;
vector
<
KeyResult
>
key_results
;
for
(
const
auto
&
key
:
key_list
)
{
KeyResult
key_result
;
key_result
.
key
=
key
;
key_result
.
sync_bits
=
init_up_down
(
key
,
wav_data
,
mode
);
key_results
.
push_back
(
key_result
);
}
// compute multiple time-shifted fft vectors
size_t
n_bands
=
Params
::
max_band
-
Params
::
min_band
+
1
;
...
...
@@ -198,16 +210,21 @@ SyncFinder::search_approx (const WavData& wav_data, Mode mode)
{
const
size_t
sync_index
=
start_frame
*
Params
::
frame_size
+
sync_shift
;
if
((
start_frame
+
total_frame_count
)
*
wav_data
.
n_channels
()
*
n_bands
<
fft_db
.
size
())
{
for
(
auto
&
key_result
:
key_results
)
{
ConvBlockType
block_type
;
double
quality
=
sync_decode
(
wav_data
,
start_frame
,
fft_db
,
have_frames
,
&
block_type
);
double
quality
=
sync_decode
(
key_result
.
sync_bits
,
wav_data
,
start_frame
,
fft_db
,
have_frames
,
&
block_type
);
// printf ("%zd %f\n", sync_index, quality);
sync_scores
.
emplace_back
(
Score
{
sync_index
,
quality
,
block_type
});
key_result
.
sync_scores
.
emplace_back
(
Score
{
sync_index
,
quality
,
block_type
});
}
}
}
sort
(
sync_scores
.
begin
(),
sync_scores
.
end
(),
[]
(
const
Score
&
a
,
const
Score
&
b
)
{
return
a
.
index
<
b
.
index
;
});
return
sync_scores
;
}
for
(
auto
&
key_result
:
key_results
)
sort
(
key_result
.
sync_scores
.
begin
(),
key_result
.
sync_scores
.
end
(),
[]
(
const
Score
&
a
,
const
Score
&
b
)
{
return
a
.
index
<
b
.
index
;
});
return
key_results
;
}
void
...
...
@@ -255,12 +272,12 @@ SyncFinder::sync_select_n_best (vector<Score>& sync_scores, size_t n)
}
void
SyncFinder
::
search_refine
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
,
vector
<
Score
>&
sync_scores
)
SyncFinder
::
search_refine
(
const
WavData
&
wav_data
,
Mode
mode
,
KeyResult
&
key_result
)
{
vector
<
float
>
fft_db
;
vector
<
char
>
have_frames
;
vector
<
Score
>
result_scores
;
BitPosGen
bit_pos_gen
(
key
);
BitPosGen
bit_pos_gen
(
key
_result
.
key
);
int
total_frame_count
=
mark_sync_frame_count
()
+
mark_data_frame_count
();
const
int
first_block_end
=
total_frame_count
;
...
...
@@ -275,7 +292,7 @@ SyncFinder::search_refine (const Key& key, const WavData& wav_data, Mode mode, v
want_frames
[
first_block_end
+
bit_pos_gen
.
sync_frame
(
f
)]
=
1
;
}
for
(
const
auto
&
score
:
sync_scores
)
for
(
const
auto
&
score
:
key_result
.
sync_scores
)
{
//printf ("%zd %s %f", score.index, find_closest_sync (score.index).c_str(), score.quality);
...
...
@@ -292,7 +309,7 @@ SyncFinder::search_refine (const Key& key, const WavData& wav_data, Mode mode, v
if
(
fft_db
.
size
())
{
ConvBlockType
block_type
;
double
q
=
sync_decode
(
wav_data
,
0
,
fft_db
,
have_frames
,
&
block_type
);
double
q
=
sync_decode
(
key_result
.
sync_bits
,
wav_data
,
0
,
fft_db
,
have_frames
,
&
block_type
);
if
(
q
>
best_quality
)
{
...
...
@@ -305,11 +322,11 @@ SyncFinder::search_refine (const Key& key, const WavData& wav_data, Mode mode, v
if
(
best_quality
>
Params
::
sync_threshold2
)
result_scores
.
push_back
(
Score
{
best_index
,
best_quality
,
best_block_type
});
}
sync_scores
=
result_scores
;
key_result
.
sync_scores
=
result_scores
;
}
vector
<
SyncFinder
::
Score
>
SyncFinder
::
fake_sync
(
const
WavData
&
wav_data
,
Mode
mode
)
vector
<
SyncFinder
::
KeyResult
>
SyncFinder
::
fake_sync
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
)
{
vector
<
Score
>
result_scores
;
...
...
@@ -324,16 +341,22 @@ SyncFinder::fake_sync (const WavData& wav_data, Mode mode)
result_scores
.
push_back
(
Score
{
expect_index
,
1.0
,
(
ab
++
&
1
)
?
ConvBlockType
::
b
:
ConvBlockType
::
a
});
}
return
result_scores
;
vector
<
KeyResult
>
key_results
;
for
(
auto
key
:
key_list
)
{
KeyResult
key_result
;
key_result
.
key
=
key
;
key_result
.
sync_scores
=
result_scores
;
key_results
.
push_back
(
key_result
);
}
return
key_results
;
}
vector
<
SyncFinder
::
Score
>
SyncFinder
::
search
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
)
vector
<
SyncFinder
::
KeyResult
>
SyncFinder
::
search
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
)
{
if
(
Params
::
test_no_sync
)
return
fake_sync
(
wav_data
,
mode
);
init_up_down
(
key
,
wav_data
,
mode
);
return
fake_sync
(
key_list
,
wav_data
,
mode
);
if
(
mode
==
Mode
::
CLIP
)
{
...
...
@@ -346,22 +369,25 @@ SyncFinder::search (const Key& key, const WavData& wav_data, Mode mode)
wav_data_first
=
0
;
wav_data_last
=
wav_data
.
samples
().
size
();
}
vector
<
Score
>
sync_scores
=
search_approx
(
wav_data
,
mode
);
sync_select_by_threshold
(
sync_scores
);
vector
<
KeyResult
>
key_results
=
search_approx
(
key_list
,
wav_data
,
mode
);
for
(
auto
&
key_result
:
key_results
)
{
/* find local maxima, select by threshold */
sync_select_by_threshold
(
key_result
.
sync_scores
);
if
(
mode
==
Mode
::
CLIP
)
sync_select_n_best
(
sync_scores
,
5
);
sync_select_n_best
(
key_result
.
sync_scores
,
5
);
search_refine
(
key
,
wav_data
,
mode
,
sync_scores
);
search_refine
(
wav_data
,
mode
,
key_result
);
}
return
sync_score
s
;
return
key_result
s
;
}
vector
<
vector
<
SyncFinder
::
FrameBit
>>
SyncFinder
::
get_sync_bits
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
)
{
init_up_down
(
key
,
wav_data
,
mode
);
return
sync_bits
;
return
init_up_down
(
key
,
wav_data
,
mode
);
}
void
...
...
src/syncfinder.hh
View file @
95f008b9
...
...
@@ -78,26 +78,33 @@ public:
std
::
vector
<
int
>
up
;
std
::
vector
<
int
>
down
;
};
private
:
struct
KeyResult
{
Key
key
;
std
::
vector
<
std
::
vector
<
FrameBit
>>
sync_bits
;
std
::
vector
<
Score
>
sync_scores
;
};
private
:
std
::
vector
<
std
::
vector
<
FrameBit
>>
init_up_down
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
);
void
init_up_down
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
);
double
sync_decode
(
const
WavData
&
wav_data
,
const
size_t
start_frame
,
double
sync_decode
(
const
std
::
vector
<
std
::
vector
<
FrameBit
>>&
sync_bits
,
const
WavData
&
wav_data
,
const
size_t
start_frame
,
const
std
::
vector
<
float
>&
fft_out_db
,
const
std
::
vector
<
char
>&
have_frames
,
ConvBlockType
*
block_type
);
void
scan_silence
(
const
WavData
&
wav_data
);
std
::
vector
<
Score
>
search_approx
(
const
WavData
&
wav_data
,
Mode
mode
);
std
::
vector
<
KeyResult
>
search_approx
(
const
std
::
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
);
void
sync_select_by_threshold
(
std
::
vector
<
Score
>&
sync_scores
);
void
sync_select_n_best
(
std
::
vector
<
Score
>&
sync_scores
,
size_t
n
);
void
search_refine
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
,
std
::
vector
<
Score
>&
sync_scores
);
std
::
vector
<
Score
>
fake_sync
(
const
WavData
&
wav_data
,
Mode
mode
);
void
search_refine
(
const
WavData
&
wav_data
,
Mode
mode
,
KeyResult
&
key_result
);
std
::
vector
<
KeyResult
>
fake_sync
(
const
std
::
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
);
// non-zero sample range: [wav_data_first, wav_data_last)
size_t
wav_data_first
=
0
;
size_t
wav_data_last
=
0
;
public
:
std
::
vector
<
Score
>
search
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
);
std
::
vector
<
KeyResult
>
search
(
const
std
::
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
Mode
mode
);
std
::
vector
<
std
::
vector
<
FrameBit
>>
get_sync_bits
(
const
Key
&
key
,
const
WavData
&
wav_data
,
Mode
mode
);
static
double
bit_quality
(
float
umag
,
float
dmag
,
int
bit
);
...
...
src/wmget.cc
View file @
95f008b9
...
...
@@ -307,27 +307,30 @@ public:
class
BlockDecoder
{
int
debug_sync_frame_count
=
0
;
vector
<
SyncFinder
::
Score
>
sync_score
s
;
// stored here for sync debugging
vector
<
SyncFinder
::
KeyResult
>
key_result
s
;
// stored here for sync debugging
public
:
void
run
(
const
Key
&
key
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
)
run
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
)
{
int
total_count
=
0
;
SyncFinder
sync_finder
;
sync_scores
=
sync_finder
.
search
(
key
,
wav_data
,
SyncFinder
::
Mode
::
BLOCK
);
FFTAnalyzer
fft_analyzer
(
wav_data
.
n_channels
());
key_results
=
sync_finder
.
search
(
key_list
,
wav_data
,
SyncFinder
::
Mode
::
BLOCK
);
for
(
const
auto
&
key_result
:
key_results
)
{
int
total_count
=
0
;
vector
<
float
>
raw_bit_vec_all
(
code_size
(
ConvBlockType
::
ab
,
Params
::
payload_size
));
vector
<
int
>
raw_bit_vec_norm
(
2
);
const
Key
&
key
=
key_result
.
key
;
SyncFinder
::
Score
score_all
{
0
,
0
};
SyncFinder
::
Score
score_ab
{
0
,
0
,
ConvBlockType
::
ab
};
ConvBlockType
last_block_type
=
ConvBlockType
::
b
;
vector
<
vector
<
float
>>
ab_raw_bit_vec
(
2
);
vector
<
float
>
ab_quality
(
2
);
FFTAnalyzer
fft_analyzer
(
wav_data
.
n_channels
());
for
(
auto
sync_score
:
sync_scores
)
for
(
auto
sync_score
:
key_result
.
sync_scores
)
{
const
size_t
count
=
mark_sync_frame_count
()
+
mark_data_frame_count
();
const
size_t
index
=
sync_score
.
index
;
...
...
@@ -408,12 +411,19 @@ public:
if
(
!
bit_vec
.
empty
())
result_set
.
add_pattern
(
/* time */
0.0
,
score_all
,
bit_vec
,
decode_error
,
ResultSet
::
Type
::
ALL
);
}
}
debug_sync_frame_count
=
frame_count
(
wav_data
);
}
void
print_debug_sync
()
{
/* this is really only useful for debugging, and should be used with exactly one key */
if
(
key_results
.
size
()
!=
1
)
return
;
const
auto
&
sync_scores
=
key_results
[
0
].
sync_scores
;
/* search sync markers at typical positions */
const
int
expect0
=
Params
::
frames_pad_start
*
Params
::
frame_size
;
const
int
expect_step
=
(
mark_sync_frame_count
()
+
mark_data_frame_count
())
*
Params
::
frame_size
;
...
...
@@ -475,13 +485,16 @@ class ClipDecoder
return
linear_decode
(
key
,
fft_out
,
n_channels
);
}
void
run_padded
(
const
Key
&
key
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
,
double
time_offset_sec
)
run_padded
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
,
double
time_offset_sec
)
{
SyncFinder
sync_finder
;
vector
<
SyncFinder
::
Score
>
sync_scores
=
sync_finder
.
search
(
key
,
wav_data
,
SyncFinder
::
Mode
::
CLIP
);
vector
<
SyncFinder
::
KeyResult
>
key_results
=
sync_finder
.
search
(
key_list
,
wav_data
,
SyncFinder
::
Mode
::
CLIP
);
FFTAnalyzer
fft_analyzer
(
wav_data
.
n_channels
());
for
(
auto
sync_score
:
sync_scores
)
for
(
const
auto
&
key_result
:
key_results
)
{
const
Key
&
key
=
key_result
.
key
;
for
(
const
auto
&
sync_score
:
key_result
.
sync_scores
)
{
const
size_t
count
=
mark_sync_frame_count
()
+
mark_data_frame_count
();
const
size_t
index
=
sync_score
.
index
;
...
...
@@ -518,9 +531,10 @@ class ClipDecoder
}
}
}
}
enum
class
Pos
{
START
,
END
};
void
run_block
(
const
Key
&
key
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
,
Pos
pos
)
run_block
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
,
Pos
pos
)
{
const
size_t
n
=
(
frames_per_block
+
5
)
*
Params
::
frame_size
*
wav_data
.
n_channels
();
...
...
@@ -562,7 +576,7 @@ class ClipDecoder
ext_samples
.
insert
(
ext_samples
.
end
(),
pad_samples_end
,
0
);
WavData
l_wav_data
(
ext_samples
,
wav_data
.
n_channels
(),
wav_data
.
sample_rate
(),
wav_data
.
bit_depth
());
run_padded
(
key
,
l_wav_data
,
result_set
,
time_offset
);
run_padded
(
key
_list
,
l_wav_data
,
result_set
,
time_offset
);
}
public
:
ClipDecoder
()
:
...
...
@@ -570,13 +584,13 @@ public:
{
}
void
run
(
const
Key
&
key
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
)
run
(
const
vector
<
Key
>&
key_list
,
const
WavData
&
wav_data
,
ResultSet
&
result_set
)
{
const
int
wav_frames
=
wav_data
.
n_values
()
/
(
Params
::
frame_size
*
wav_data
.
n_channels
());
if
(
wav_frames
<
frames_per_block
*
3.1
)
/* clip decoder is only used for small wavs */
{
run_block
(
key
,
wav_data
,
result_set
,
Pos
::
START
);
run_block
(
key
,
wav_data
,
result_set
,
Pos
::
END
);
run_block
(
key
_list
,
wav_data
,
result_set
,
Pos
::
START
);
run_block
(
key
_list
,
wav_data
,
result_set
,
Pos
::
END
);
}
}
};
...
...
@@ -614,20 +628,20 @@ decode_and_report (const vector<Key>& key_list, const WavData& wav_data, const v
result_set
.
set_speed_pattern
(
true
);
BlockDecoder
block_decoder
;
block_decoder
.
run
(
key
,
wav_data_speed
,
result_set
);
block_decoder
.
run
(
{
key
}
,
wav_data_speed
,
result_set
);
ClipDecoder
clip_decoder
;
clip_decoder
.
run
(
key
,
wav_data_speed
,
result_set
);
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
);
block_decoder
.
run
(
key_list
,
wav_data
,
result_set
);
ClipDecoder
clip_decoder
;
clip_decoder
.
run
(
key
,
wav_data
,
result_set
);
}
clip_decoder
.
run
(
key_list
,
wav_data
,
result_set
);
result_set
.
sort_by_time
();
...
...
@@ -641,7 +655,7 @@ decode_and_report (const vector<Key>& key_list, const WavData& wav_data, const v
{
int
match_count
=
result_set
.
print_match_count
(
orig_bits
);
// block_decoder.print_debug_sync(); FIXME
block_decoder
.
print_debug_sync
();
if
(
Params
::
expect_matches
>=
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment