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

 채택된 답변

Geoff Hayes
Geoff Hayes 2014년 6월 11일

0 개 추천

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).

추가 답변 (3개)

Muhammad fayyaz
Muhammad fayyaz 2014년 6월 11일

0 개 추천

there is still a problem sir please give me your email address i want to send you my audio file as well as my text file

댓글 수: 8

Geoff Hayes
Geoff Hayes 2014년 6월 11일
Muhammad - you can attach your audio file and text file to any comment you make. Just use the paperclip icon.
Please also describe your problem in more detail. Did you modify the code as described in my above answer?
yes sir i modified it as you described.
When i try to extend my message length (which is in .txt file) the graph become very change and at the exact time the data clipped error display. it doesn't upload the audio file sir. below the graph(after steganography) portion show -1.5 while there is no -1 value in (before steganography). so i need both same to (before steganography graph
Put a breakpoint at the line just before the above plot is created. In the command window type
min(x) % the minimum value of the original audio data
max(x) % the maximum value of the original audio data
min(a) % the minimum value of the audio data with secret message
max(a) % the maximum value of the audio data with secret message
What do you notice?
i write
min(x)
max(x)
min(a)
max(a)
it before the plot is created. but it doesn't work sir.
i understand that there is values which are less than -1 and i found it in the variables of a which is -1.0001 this value make a problem how to remove .0001 or how to change it to -1
You can do the following: since you are modifying the 15th bit of the 16-bit string, i.e. x in 11111111111111x1, then a change from a one to a zero is really the addition of 2 to whatever the number that 16-bit binary string represents.
Since you allow negative integers, then your range for the audio data which is composed of 16-bit signed integers is -32768 to 32767. Which is then promptly converted to positive integers by taking the absolute value of the data.
We can't go outside of this range (now 0 to 32768) when we modify the 15th bit. Since we are adding at most 2 to the 16-bit binary string, then our range on the audio data - prior to the insertion of the secret text and prior to the absolute value - must be -32766 to 32765. That way, when the 15th bit is modified (and so add the 2) we will still be in the range of -32768 to 32767 (once converted back to positive and negative integers).
There is one of two things you can do - when you do the analog-to-digital conversion
%Analog-to-Digital Conversion
y=((2^(nbits-1)*x(:,1))); %change the samples into decimal
you can either subtract two from all positive integers in y and add two to all negative integers of y to force the audio data to the range -32766 to 32765 or you can modify just those integers that - when two is added to them - cannot fall outside the just mentioned range
%Analog-to-Digital Conversion
y=((2^(nbits-1)*x(:,1))); %change the samples into decimal
y(y==32767 | y==32766) = 32765;
y(y==-32768 | y==-32767) = -32766;
So the above forces all positive integers that are 32767 or 32766 to 32765, and all negative integers that are -32768 or -32767 to -32766. That way when 2 is added to the absolute value of any of these integers, we will, once converted back to positive and negative values, still be in the range of -32768 to 32767.
I tried the above and was able to avoid the *Warning: Data clipped during write to <file:stego_message.wav*> message and both sub-plots looked identical.
NOTE that the above is valid so long as you always modify the 15th bit. If you were to modify another bit, then a similar adjustment would have to be made.
Try it nd see what happens.
Respected sir,
sir i got it i use "ylimt(-1 1)" function before after subplot(1,2,2),plot(a);
and it's work correctly there is still warning: but my graph become identical.
Geoff Hayes
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
Muhammad fayyaz 2014년 6월 12일

0 개 추천

Respected Sir,
I am doing project can you help me more. i want you to implement the formula in matlab for me which is on page number 10. i want to use it on my project to make it further strong ful Thanks

댓글 수: 1

Geoff Hayes
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!

댓글을 달려면 로그인하십시오.

Muhammad fayyaz
Muhammad fayyaz 2014년 6월 12일

0 개 추천

OK sir Thanks, i made this code now can you please tell me, is it works for SNR of audio or not.
clc
k=wavread('one.wav');
j=wavread('stego_message.wav');
n=j-k
pk=power(k,2);
pn=power(n,2);
SNR=pk/pn;
SNRdb=10*log10(SNR);

카테고리

도움말 센터File Exchange에서 Audio I/O and Waveform Generation에 대해 자세히 알아보기

질문:

2014년 6월 11일

답변:

2014년 6월 12일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by