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
a4525f59
Commit
a4525f59
authored
Feb 04, 2019
by
Stefan Westerfeld
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sample-rate'
parents
af85c13c
af977c42
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
260 additions
and
94 deletions
+260
-94
Dockerfile
Dockerfile
+1
-0
README
README
+0
-30
README.adoc
README.adoc
+88
-0
configure.ac
configure.ac
+13
-0
audiowmark.cc
src/audiowmark.cc
+143
-35
ber-test.sh
src/ber-test.sh
+2
-16
random.cc
src/random.cc
+1
-1
wavdata.cc
src/wavdata.cc
+7
-7
wavdata.hh
src/wavdata.hh
+5
-5
No files found.
Dockerfile
View file @
a4525f59
...
...
@@ -8,6 +8,7 @@ RUN apt-get install -y autoconf
RUN
apt-get
install
-y
libtool
RUN
apt-get
install
-y
autoconf-archive
RUN
apt-get
install
-y
libgcrypt20-dev
RUN
apt-get
install
-y
libzita-resampler-dev
ADD
. /audiowmark
WORKDIR
/audiowmark
...
...
README
deleted
100644 → 0
View file @
af85c13c
Audio Watermarking
(TODO)
Building fftw
audiowmark needs the single prevision variant of fftw3.
If you are building fftw3 from source, use the `--enable-float`
configure parameter to build it, e.g.::
cd ${FFTW3_SOURCE}
./configure --enable-float --enable-sse && \
make && \
sudo make install
or, when building from git
cd ${FFTW3_GIT}
./bootstrap.sh --enable-shared --enable-sse --enable-float && \
make && \
sudo make install
Docker Build
You should be able to execute audiowmark via Docker.
Example that outputs the usage message:
docker build -t audiowmark .
docker run -v <local-data-directory>:/data -it audiowmark -h
README.adoc
0 → 100644
View file @
a4525f59
= audiowmark - Audio Watermarking
== Description
`audiowmark` is an Open Source solution for audio watermarking. A sound file
(typically wav) is read by the software, and a 128-bit message is stored in a
watermark in the output sound file. For human listeners, the files typically
sound the same.
However, the 128-bit message can be retrieved from the output sound file. Our
tests show, that even if the file is converted to mp3 or ogg (with bitrates
higher than 128 kbit/s), the watermark usually can be retrieved without
problems. The process of retrieving the message does not need the original
audio file (blind decoding).
Internally, audiowmark is using the patchwork algorithm to hide the data in the
spectrum of the audio file. Some pseoudo-randomly selected amplitudes of the
frequency bands of a 1024-value FFTs are increased or decreased slightly, which
can be detected later. The algorithm used here is inspired by
Martin Steinebach: Digitale Wasserzeichen für Audiodaten.
Darmstadt University of Technology 2004, ISBN 3-8322-2507-2
== Adding/Retrieving a Watermark
To add a watermark to the soundfile in.wav with a 128-bit message (which is
specified as hex-string):
audiowmark add in.wav out.wav 0123456789abcdef0011223344556677
To get the 128-bit message from the watermarked file, use:
audiowmark get out.wav
== Watermark Key
Since the software is Open Source, a watermarking key should be used to ensure
that the message bits cannot be retrieved by somebody else (which would also
allow removing the watermark without loss of quality). The watermark key
controls all pseudo-random parameters of the algorithm. This means that
it determines which frequency bands are increased or decreased to store a
0 bit or a 1 bit. Without the key, it is impossible to decode the message
bits from the audio file alone.
Our watermarking key is a 128-bit AES key. A key can be generated using
audiowmark gen-key test.key
and can be used for the add/get commands as follows:
audiowmark add --key test.key in.wav out.wav 0123456789abcdef0011223344556677
audiowmark get --key test.key out.wav
== Dependencies
If you compile from source, audiowmark needs the follwing libraries:
* libfftw3
* libsndfile
* libgcrypt
* libzita-resampler
== Building fftw
audiowmark needs the single prevision variant of fftw3.
If you are building fftw3 from source, use the `--enable-float`
configure parameter to build it, e.g.::
cd ${FFTW3_SOURCE}
./configure --enable-float --enable-sse && \
make && \
sudo make install
or, when building from git
cd ${FFTW3_GIT}
./bootstrap.sh --enable-shared --enable-sse --enable-float && \
make && \
sudo make install
== Docker Build
You should be able to execute audiowmark via Docker.
Example that outputs the usage message:
docker build -t audiowmark .
docker run -v <local-data-directory>:/data -it audiowmark -h
configure.ac
View file @
a4525f59
...
...
@@ -17,6 +17,18 @@ AC_DEFUN([AC_SNDFILE_REQUIREMENTS],
AC_SUBST(SNDFILE_LIBS)
])
dnl
dnl zita resampler
dnl
AC_DEFUN([AC_ZITA_REQUIREMENTS],
[
AC_CHECK_LIB(zita-resampler, _Z28zita_resampler_major_versionv,[],
[
AC_MSG_ERROR([You need to install libzita-resampler to build this package.])
]
)
])
dnl FFTW3
AC_DEFUN([AC_FFTW_CHECK],
[
...
...
@@ -45,6 +57,7 @@ AC_DEFUN([AC_FFTW_CHECK],
])
AC_SNDFILE_REQUIREMENTS
AC_ZITA_REQUIREMENTS
AC_FFTW_CHECK
AM_PATH_LIBGCRYPT
...
...
src/audiowmark.cc
View file @
a4525f59
This diff is collapsed.
Click to expand it.
src/ber-test.sh
View file @
a4525f59
...
...
@@ -19,10 +19,8 @@ fi
ls test
/T
*
elif
[
"x
$AWM_SET
"
==
"xbig"
]
;
then
cat
test_list
elif
[
"x
$AWM_SET
"
==
"xhuge"
]
;
then
ls
huge/T
*
elif
[
"x
$AWM_SET
"
==
"xhuge2"
]
;
then
ls
huge2/T
*
elif
[
"x
$AWM_SET
"
!=
"x"
]
&&
[
-d
"
$AWM_SET
"
]
&&
[
-f
"
$AWM_SET
/T001"
*
wav
]
;
then
ls
$AWM_SET
/T
*
else
echo
"bad AWM_SET
$AWM_SET
"
>
&2
exit
1
...
...
@@ -62,12 +60,6 @@ do
lame
-b
$2
${
AWM_FILE
}
.wav
${
AWM_FILE
}
.mp3
--quiet
rm
${
AWM_FILE
}
.wav
ffmpeg
-i
${
AWM_FILE
}
.mp3
${
AWM_FILE
}
.wav
-v
quiet
-nostdin
# some (low) mpeg quality settings use a lower sample rate
if
[
"x
$(
soxi
-r
${
AWM_FILE
}
.wav
)
"
!=
"x44100"
]
;
then
sox
${
AWM_FILE
}
.wav
${
AWM_FILE
}
r.wav rate 44100
mv
${
AWM_FILE
}
r.wav
${
AWM_FILE
}
.wav
fi
elif
[
"x
$TRANSFORM
"
==
"xdouble-mp3"
]
;
then
if
[
"x
$2
"
==
"x"
]
;
then
echo
"need mp3 bitrate"
>
&2
...
...
@@ -82,12 +74,6 @@ do
lame
-b
$2
${
AWM_FILE
}
.wav
${
AWM_FILE
}
.mp3
--quiet
rm
${
AWM_FILE
}
.wav
ffmpeg
-i
${
AWM_FILE
}
.mp3
${
AWM_FILE
}
.wav
-v
quiet
-nostdin
# some (low) mpeg quality settings use a lower sample rate
if
[
"x
$(
soxi
-r
${
AWM_FILE
}
.wav
)
"
!=
"x44100"
]
;
then
sox
${
AWM_FILE
}
.wav
${
AWM_FILE
}
r.wav rate 44100
mv
${
AWM_FILE
}
r.wav
${
AWM_FILE
}
.wav
fi
elif
[
"x
$TRANSFORM
"
==
"xogg"
]
;
then
if
[
"x
$2
"
==
"x"
]
;
then
echo
"need ogg bitrate"
>
&2
...
...
src/random.cc
View file @
a4525f59
...
...
@@ -108,7 +108,7 @@ void
Random
::
refill_buffer
()
{
const
size_t
block_size
=
256
;
unsigned
char
zeros
[
block_size
]
=
{
0
,
};
static
unsigned
char
zeros
[
block_size
]
=
{
0
,
};
unsigned
char
cipher_text
[
block_size
];
gcry_error_t
gcry_ret
=
gcry_cipher_encrypt
(
aes_ctr_cipher
,
cipher_text
,
block_size
,
zeros
,
block_size
);
...
...
src/wavdata.cc
View file @
a4525f59
...
...
@@ -17,11 +17,11 @@ WavData::WavData()
{
}
WavData
::
WavData
(
const
vector
<
float
>&
samples
,
int
n_channels
,
float
mix_freq
,
int
bit_depth
)
WavData
::
WavData
(
const
vector
<
float
>&
samples
,
int
n_channels
,
int
sample_rate
,
int
bit_depth
)
{
m_samples
=
samples
;
m_n_channels
=
n_channels
;
m_
mix_freq
=
mix_freq
;
m_
sample_rate
=
sample_rate
;
m_bit_depth
=
bit_depth
;
}
...
...
@@ -76,7 +76,7 @@ WavData::load (const string& filename)
for
(
size_t
i
=
0
;
i
<
m_samples
.
size
();
i
++
)
m_samples
[
i
]
=
isamples
[
i
]
*
norm
;
m_
mix_freq
=
sfinfo
.
samplerate
;
m_
sample_rate
=
sfinfo
.
samplerate
;
m_n_channels
=
sfinfo
.
channels
;
switch
(
sfinfo
.
format
&
SF_FORMAT_SUBMASK
)
...
...
@@ -121,7 +121,7 @@ WavData::save (const string& filename)
{
SF_INFO
sfinfo
=
{
0
,};
sfinfo
.
samplerate
=
lrint
(
m_mix_freq
)
;
sfinfo
.
samplerate
=
m_sample_rate
;
sfinfo
.
channels
=
m_n_channels
;
if
(
m_bit_depth
>
16
)
...
...
@@ -179,10 +179,10 @@ WavData::save (const string& filename)
return
true
;
}
floa
t
WavData
::
mix_freq
()
const
in
t
WavData
::
sample_rate
()
const
{
return
m_
mix_freq
;
return
m_
sample_rate
;
}
int
...
...
src/wavdata.hh
View file @
a4525f59
...
...
@@ -7,19 +7,19 @@
class
WavData
{
std
::
vector
<
float
>
m_samples
;
float
m_mix_freq
=
0
;
int
m_n_channels
=
0
;
int
m_bit_depth
=
0
;
int
m_sample_rate
=
0
;
int
m_n_channels
=
0
;
int
m_bit_depth
=
0
;
std
::
string
m_error_blurb
;
public
:
WavData
();
WavData
(
const
std
::
vector
<
float
>&
samples
,
int
n_channels
,
float
mix_freq
,
int
bit_depth
);
WavData
(
const
std
::
vector
<
float
>&
samples
,
int
n_channels
,
int
sample_rate
,
int
bit_depth
);
bool
load
(
const
std
::
string
&
filename
);
bool
save
(
const
std
::
string
&
filename
);
float
mix_freq
()
const
;
int
sample_rate
()
const
;
int
bit_depth
()
const
;
const
char
*
error_blurb
()
const
;
...
...
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