is there another function in matlab for compressing 1D data (speech or any signal) that is equivalent to wcompress ?

4 Comments

You can use other 2D discrete wavelet transform funtions in Wavelet toolbox to obtain the coefficients and perform compression by setting some values to zero. Wavelet toolbox also has wdencmp function that can used for denoising or compression.
The following example shows how to use wdencmp for compression.
https://www.mathworks.com/help/wavelet/ug/wavelet-data-compression.html
Thank you so much, yes i used wdencmp and it was great , but i notice that the size of the data file after and before the wdencmp is the same,
in wcompress the size of the image changed significantly and the effect of the compression was obvious
here is the code ( I Applied my code in speech file ), the size of 5.wav and 5-comp.wav was the same
[y,fs] = audioread('5.wav');
n = 3; w = 'db3';
[c,l] = wavedec(y,n,w);
% Compress using a fixed threshold.
thr = 35;
keepapp = 1;
[xd,cxd,lxd,perf0,perfl2] = ...
wdencmp('gbl',c,l,w,n,thr,'h',keepapp);
audiowrite('5-comp.wav',xd,fs);
Did you check how if the threshold you chose zeroed out significant number of coefficients? If not, chances are the file size won't change drastically. The functions must be using different algorithms under the hood. Can you attach the audio file here? I want to take a look.
Yes, i kept changing the threshold the signal changed rapidly but the file size kept the same, I think that wdencmp is not entirely equivalent to wcompress ,I think wcompress has more work involved than applying wavelet transformation

Sign in to comment.

 Accepted Answer

but i notice that the size of the data file after and before the wdencmp is the same,
What you are writing to the file is the reconstructed signal, not the wavelet coefficients. The size of the reconstructed signal is the same as the size of the input.
You are expecting that the output file will be smaller than the original file. That implies one of two possibilities:
  1. Perhaps you are getting confused about what is being written to the file, and are thinking that just the compressed coefficients are being written to the file; Or
  2. Perhaps you expecting that audiowrite() does compression on the signal it is asked to write, and you are expecting that the reconstructed signal will happen to be more compressible under whatever compression algorithm that audiowrite() might potentially be using.
But is audiowrite() compressing when you write with those parametes?
N = 32768;
Fs = 8000;
testsignal0 = zeros(N, 1); %should be entirely predictable
testsignal1 = linspace(-1, 1, N) .'; %should be pretty predictable
testsignal2 = rand(N, 1); %should be barely predictable
audiowrite('testsignal0.wav', testsignal0, Fs);
audiowrite('testsignal1.wav', testsignal1, Fs);
audiowrite('testsignal2.wav', testsignal2, Fs);
!ls -l testsignal*.wav
-rw-r--r-- 1 mluser worker 65580 Sep 25 01:37 testsignal0.wav -rw-r--r-- 1 mluser worker 65580 Sep 25 01:37 testsignal1.wav -rw-r--r-- 1 mluser worker 65580 Sep 25 01:37 testsignal2.wav
You can see that the files are all exactly the same size -- 2 bytes per sample (per channel) plus a 44 byte header.
So... any difference you are seeing in the size of the files is due to one of two possibilities:
  • the original .wav file might have been written with a different audio encoder; Or
  • the original .wav file had additional headers (such as copyright information or song name) that is not being written out when you audiowrite()

6 Comments

I agree about that the reconstruction give the signal exactly as it is, in my post I am discussing the compression concept applied in wcompression and the possibility to apply it in 1D data signal
But you are asking why the files written by audiowrite are the same size. You are not passing compression coefficients to audiowrite, you are passing the reconstructed signal that is the same size as the original signal.
I asked for wcompress equivalent function for 1d signal. And the asnwer I get that wdencmp is the equivalent , i am saying its not!
The first output of the function is described as
Denoised or compressed data, returned as a real-valued vector or matrix. XC and X have the same dimensions.
I was misreading about it being the decompressed signal, but still it is documented that it will be the same size as the input.
If you use wavedec wavelet decomposition, then you get two outputs, there called c and l . c contains coefficients and l contains bookkeeping information about where the coefficients are.
If you then take a leading prefix of l and you extract the leading coefficients of c based upon the last value stored in the prefix of l, you can store those in a file. Then you can later retrieve them from the file and do wavrec() on them, and the signal will be reconstructed, just with a less-detailed signal.
if ispc()
filename = '5.wav';
[y, fs] = audioread(filename);
else
filename = which('handel.mat');
load(filename);
fs = Fs;
end
n = 3; w = 'db3';
Levels_to_drop = 1;
[c,l] = wavedec(y,n,w);
lprefix = l(1:end-Levels_to_drop);
cprefix_len = sum(lprefix(1:end-1));
cprefix = c(1:cprefix_len, :);
fsprefix = ceil(Fs * cprefix_len / size(y,1));
savefilename = 'test_compress.mat';
save(savefilename, 'cprefix', 'lprefix', 'fsprefix', '-v7');
clearvars -except filename savefilename w
load(savefilename)
yrec = waverec(cprefix, lprefix, w);
sound(yrec, fsprefix)
In the above, Levels_to_drop is the number of levels of decomposition coefficients to drop. With handel dropping one level results in something that is still quite good; dropping 2 levels results in something somewhat muddy.
Now comes the question: is the compressed file smaller?
dinfo = dir(filename);
orig_size = dinfo.bytes;
dinfo = dir(savefilename);
new_size = dinfo.bytes;
[~, orig_basename, ~] = fileparts(filename);
[~, new_basename, ~] = fileparts(savefilename);
fprintf('Original file "%s" was %d bytes, new file "%s" is %d bytes\n', orig_basename, orig_size, new_basename, new_size);
Original file "handel" was 139569 bytes, new file "test_compress" is 281189 bytes
No! The new file is bigger -- notably so!
if ~ispc(); whos('-file', filename); end
Name Size Bytes Class Attributes Fs 1x1 8 double y 73113x1 584904 double
whos('-file', savefilename)
Name Size Bytes Class Attributes cprefix 36568x1 292544 double fsprefix 1x1 8 double lprefix 4x1 32 double
lprefix and fsprefix are small; most of the space to store them in the .mat will be headers.
cprefix is only about half the number of elements (and so the number of bytes) and yet takes nearly twice as much space to store in the .mat .
Why? Well, MATLAB .mat -v7 files compress double variables by default, using a level 4 bzip algorithm (if I recall correctly) -- and the detail coefficients stored in c are considerably less compressable under that algorithm than the original sound !
Thanks you so much! , I will test the code now

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!