Quantization erorr in audio steganography
1 次查看(过去 30 天)
显示 更早的评论
if true
%Initialization
clc, clear all;
%Waveread
[x,fs,nbits]=wavread('one.wav');
%sound(x,fs)
%Analog-to-Digital Conversion
y=((2^(nbits-1)*x(:,1))); %change the samples into decimal
%store the sign
for i=1:length(y)
if y(i)<0
z(i)=1;
else
z(i)=0;
end
if y(i)<0
y(i)=-1*y(i);
end
end
y=dec2bin(y);
z=dec2bin(z);
%Steganography
data=fileread('data.txt');
temp_message=dec2bin(double(data),8);%secret message
%form row vector of secret message
message=[];
for v=1:size(temp_message,1)
message=[message temp_message(v,:)];
end
str = dec2bin(length(message),16);
if length(message)<length(y)
%embed message length in first 16 samples
for a=1:length(str)
y(a,nbits-1)=str(a);
end
%embed secret message from 17th sample
b=1;
for j=17:length(message)+16
if b<length(message)+1
y(j,nbits-1)=message(b);
b=b+1;
end
end
%Digital-to-Analaog Conversion
b=bin2dec(y);
%check the sign
for i=1:length(y)
if z(i)=='1'
b(i)=-1*b(i);
end
end
a=b/(2^(nbits-1));
%Analysis
wavplay(a,fs)
%save the sound contained secret message
wavwrite(a,fs,nbits,'stego_message.wav');
%plotting
subplot(1,2,1),plot(x(:,1));
title('Before Steganography');
xlabel('Sample Number');
ylabel('Amplitude');
subplot(1,2,2),plot(a);
title('After Steganography');
xlabel('Sample Number');
ylabel('Amplitude');
else
disp('error')
end
end
i am getting error while i am writing when my message length is 6464 than it doesn't show any error when i increase the length it show error "data clipped during write to file" and also my graph change please help me i don't want the change in graph please help me some one
0 个评论
采纳的回答
Geoff Hayes
2014-6-11
Muhammad - in some cases, rather than embedding the code for your function in the question body, it would be preferable to attach it to your question instead. That way, you can add more context surrounding your problem - what is the one.wav file? what is the error message? why do you think it works for messages with a length less than 6464? why 6464, is that related to one.wav? when does the data clipped message appear?
I created a sample wav file as follows
load gong.mat;
sound(y);
wavwrite(y,'one.wav')
When I ran your function/script, and the y vector was created, it was of size 42028 (in your code, y is a vector of the samples from the audio file, converted to integers) which is due to my choice of the wav file. You then store the sign of each element in y in the vector z. As an aside, since the length of y is known, then memory can be pre-allocated to z
n = length(y);
z = zeros(n,1);
for i=1:n
if y(i)<0
z(i)=1;
end
end
y = abs(y); % since you want all y's to be positive
What is important here is that both y and z are of the same length/size.
The message (data.txt) is then read, and each character converted to an 8-bit binary equivalent. Again, you may want to consider pre-allocating memory to message (since you know its length) so that you avoid the matrix re-sizing that would occur on each iteration of the for loop, causing a degradation in performance:
m = length(temp_message);
message=char(zeros(1,m*8));
for v=1:size(temp_message,1)
idx = (v-1)*8+1;
message(idx:idx+7) = temp_message(v,:);
end
You then grab the length of the message and come to the following if statement
if length(message)<length(y)
So right away, if the message is longer than the length of the number of samples in the audio file, then the error message is displayed and everything ends prematurely. Either a longer audio file will have to be loaded, or the message is broken down into blocks that are at most one less than the number of samples in the audio file. The code would take each block and do what it does now (conversion from the message to sound) and then just concatenate each block together to produce an audio file that is longer than one.wav. (This may or may not be desirable.)
Otherwise, if condition in the if statement passes, then the code embeds the length of the message in the 15th bit of each of the first 16 samples of the audio data (this is the vector y that is now being overwritten) and the (secret) message length is embedded in the 15th bit of the remaining samples (17th onwards) according to
b=1;
for j=17:length(message)+16
if b<length(message)+1
y(j,nbits-1)=message(b);
b=b+1;
end
end
The problem with the above is the +16 and the assignment to y. Even though the length of message is at most one less than the length of y we can still over-assign values to y and its length will increase. Which is not a big deal until we reach
%check the sign
for i=1:length(y)
if z(i)==1 % NOTE use integer one rather than character '1'
b(i)=-1*b(i);
end
end
If the length of y has increased, then it will be larger than z and the above code will try to access an element of z that does not exist, leading to the index out of bounds error. To avoid this, you will have to change your initial condition from
if length(message)<length(y)
to
if length(message)<length(y)-16
(or something similar).
Try changing the above and seeing it gets rid of one of your errors. You may have to modify your code to account for messages that are longer than the number of samples in the audio file (or just accept that it won't work for too long messages).
0 个评论
更多回答(3 个)
Muhammad fayyaz
2014-6-11
8 个评论
Geoff Hayes
2014-6-12
Using ylim(-1 1) will change the limits on the plot only and not affect the data that is saved to the audio file - so that is why you will still observe the clipping warning/error.
Muhammad fayyaz
2014-6-12
1 个评论
Geoff Hayes
2014-6-12
Muhammad - the intent of this site is to ask for help with MATLAB, not to ask someone to do your work for you. Good luck with your project!
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!