Channels ▼

Web Development

Audio Watermarking

Source Code Accompanies This Article. Download It Now.

Implementing the Watermark

The masking threshold defines the frequency response of the loudness threshold minimum LTMin-Filter, which shapes the watermark. The filtered watermark is scaled to shift the watermark noise and added to the delayed original signal to produce the watermarked track. Listing Two is MATLAB code that implements the watermarking algorithm just described. In this implementation, an ASCII string is converted in its bit representation. The individual bits are embedded by means of two different bit patterns in each frame of the audio sample. The bit patterns are derived from the secret key used in the embedding process.

Listing Two

function [result, message] = Write(watermark, password)
% [result, message] = Write(watermark, password)
% Embeds the string specified by watermark into an audio file. result = 1 if
% watermarking process is successful otherwise = 0. message contains a
% string reporting possible errors. The watermarking process is determined 
% by a secret key string in password.
% See also READ.
% Copyright (c) 2001 by Fraunhofer-IGD
% $Revision: 1.0 $  $Date: 2001/07/12 $
% M.Arnold, 07/01
% -- INPUT --
% watermark: Information string to be embedded.  
% password: Secret key used during embedding and detection process for
% generation of random sequences.
% -- OUTPUT --
% result: Flag scalar indicating success or failure of the embedding procedure.
% message: Message string reporting the result of the embedding process.

% Load tables for global variables only one time
% Constants used by the psycho acoustic model

% --- Set parameter ---
parameter.WavFile              = 'UseFileDialog';
% Name of the marked file
parameter.WavFileNew           = 'marked_1.wav';
parameter.Blocksize            = FFT_SIZE;
parameter.BlocksPerFrame       = 10;
parameter.SamplesPerFrame      = parameter.Blocksize*parameter.BlocksPerFrame; 
parameter.NumberOfFilterCoeffs = FFT_SIZE/2; 
parameter.FilterGroupDelay     = parameter.NumberOfFilterCoeffs/2;
% Specify number of frequency bands used in the psycho acoustic model
parameter.PAMResolution        = FFT_SIZE/2;
% Specify quality of watermarked audio track
parameter.LTMinWANoiseConstant = 0;
% Specify frequencies which will be altered
parameter.frequencyIdxVector   = [20:120];
parameter.watermark            = watermark;
parameter.demo_size            = 5;

% Check if WavFile is specified. Otherwise popup file dailog. 
if isempty(parameter.WavFile) | strcmp(parameter.WavFile, 'UseFileDialog'),
  % Prepend the path to the home directory.
  if isunix
    fileName = '~/docs/research/own-paper/DrDobbs/';
    fileName = 'U:\docs\research\own-paper\DrDobbs\';
  % Get Filename and Path for Input-AudioFile  
  [fname, pname] = uigetfile( strcat(fileName, '*.wav') );
  if fname == 0 & pname == 0,
    message = ['Writing process canceled!'];
    result = 0;
  parameter.WavFile = strcat(pname, fname);
% --- Load WAVE file and calculate algorithm parameter ---
[properties Fs bits] = wavread(parameter.WavFile, 'size');
samples = properties(1); numChannels = properties(2)  
if  numChannels > 1,  
  message = ['Only MONO files!'];
  result = 0;
% Calculate total number of frames for the file (fix rounds towards zero).
total_frames = fix(samples/parameter.SamplesPerFrame);
% --- Convert from ASCII to bit representation
stringLen = length(watermark);
if stringLen ~= parameter.demo_size,
  message = ['Length of watermark doesn''t match with configured size!'];
  result = 0;
wmBits = reshape(dec2bin(double(watermark), 8)', 1, stringLen*8);
% Exit if to few frames
if total_frames < length(wmBits),
  message = ['Audio file to short to embed whole watermark!'];
  result = 0;
% Write the WAVE header for output file
fmt = wavwrite_Header(samples, numChannels, Fs, bits, parameter.WavFileNew);
% --- Generate pattern matrix for different bits
for i = 0:1
  key = strcat(password, num2str(i));
  pattern(i + 1).Matrix = GeneratePatternMatrix(key, parameter);
% --- loop over bit frames --
for frameIdx = 0:total_frames - 1
  % Take bit frame from WAVE file
  Offset      = 1;
  StartSample = Offset + frameIdx*parameter.SamplesPerFrame;
  EndSample   = StartSample + parameter.SamplesPerFrame - 1;
  WavFrame    = wavread(parameter.WavFile, [StartSample EndSample]);  
  % Calculate index of Bit in wmBit, which has to be embedded.
  idx           = rem(frameIdx, length(wmBits)) + 1;
  pattIdx       = str2num(wmBits(idx)) + 1;
  patternMatrix = pattern(pattIdx).Matrix;
  % Embed watermark into frame. 
  [MarkedFrame, shiftSamples] = markFrame(WavFrame(:)', ...
                    patternMatrix, ...
  % Write bit frame to output file. Don't write delay for first frame.
  if frameIdx == 0,
    [fidNew, err, samples_append] = ...
        append_wavedat(parameter.WavFileNew, fmt, ...
           real(MarkedFrame(parameter.FilterGroupDelay+1:end,:)) );
    [fidNew, err, samples_append] = ...
        append_wavedat(parameter.WavFileNew, fmt, ...
                       real(MarkedFrame) );
% Read remaining samples
WavFrameNew = wavread(parameter.WavFile, [(EndSample + 1) samples])';
% Write delayed shiftSamples + remaining samples to file.
WavFrameNew = [shiftSamples WavFrameNew];
[fidNew, err, samples_append] = ...
    append_wavedat(parameter.WavFileNew, fmt, WavFrameNew);
% Close output file
if fclose(fidNew) == -1
  message = ['Error closing WAVE file!'];
  result = 0;
% Exit and report success
message = ['Watermark successfully embedded!'];
result = 1;

To detect the watermark that's embedded in the dataset:

  1. Map the secret key and watermark to the seed of the random-number generator to generate the subsets C and D. This step is exactly the same as in the embedding process. C=A and D=B if the right key is used.

  2. Decide for the probability of correct rejection 1-PI according to the application and calculate the threshold T from the equation in Figure 1(a).

  3. Calculate the sample mean E(z)=E(f(C,D)) and choose between the two mutually exclusive propositions:

    • H0: E(z)T watermark bit is not embedded.

    • H1: E(z)>T watermark bit is embedded.

The algorithm is based on hypothesis testing, which in turn depends on the appropriate test statistic.

Detecting the Watermark

During the detection process, the interpretation of the embedded bit is based on the comparison of the two different expectation values E(z) for the two different patterns. The different test statistics are implemented in CalcStatistic.m (available in the sourcecode that accompanies this article, download from opening page).

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.