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 global FFT_SIZE MIN_POWER NOT_EXAMINED IRRELEVANT TONAL NON_TONAL global TH INDEX BARK ATH SPL Map CB LTq HAMMING_513 EXP_RAD_513 % Constants used by the psycho acoustic model load('Common_Const.mat'); load('Tables_fs_44100.mat'); % --- 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/'; else fileName = 'U:\docs\research\own-paper\DrDobbs\'; end % Get Filename and Path for Input-AudioFile [fname, pname] = uigetfile( strcat(fileName, '*.wav') ); if fname == 0 & pname == 0, message = ['Writing process canceled!']; result = 0; return end parameter.WavFile = strcat(pname, fname); end % --- 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; end % 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; end 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; return end % 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); end % --- 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, ... parameter); % 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,:)) ); else [fidNew, err, samples_append] = ... append_wavedat(parameter.WavFileNew, fmt, ... real(MarkedFrame) ); end end % 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; return end % Exit and report success message = ['Watermark successfully embedded!']; result = 1; return
To detect the watermark that's embedded in the dataset:
- 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.
- 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).
- 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.
- H0: E(z)
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).