In this exercise, Huffman coding will be applied to compress pcm.wav le. The pro
ID: 3755376 • Letter: I
Question
In this exercise, Huffman coding will be applied to compress pcm.wav le. The program steps are
as follows:
1. Read pcm.wav le into vector y (you can truncate the original data to the desired length);
2. Quantize y into 8 levels (level 0-7) using uniform quantization;
3. Find the probability of each symbol (8 symbols: level 0-7); construct the Huffman tree; calculate
the entropy of the source.
4. Encode the symbols and form the bit stream.
5. Calculate the coding efciency (average length of bits/symbol over entropy), and compression
ratio compared with PCMencoding.
Write a programto decode the Huffman-coded bit streamgiven the Huffman table. Run this program
on your coded data in part I and compare the decoded symbols with the transmitted ones.
Explanation / Answer
function [y,Fs,bits,opt_ck] = wavread2(varargin) %WAVREAD Read Microsoft WAVE (".wav") sound file. % Y=WAVREAD(FILE) reads a WAVE file specified by the string FILE, % returning the sampled data in Y. The ".wav" extension is appended % if no extension is given. % % [Y,FS,NBITS]=WAVREAD(FILE) returns the sample rate (FS) in Hertz % and the number of bits per sample (NBITS) used to encode the % data in the file. % % [...]=WAVREAD(FILE,N) returns only the first N samples from each % channel in the file. % [...]=WAVREAD(FILE,[N1 N2]) returns only samples N1 through N2 from % each channel in the file. % % [Y,...]=WAVREAD(...,FMT) specifies the data type format of Y used % to represent samples read from the file. % If FMT='double', Y contains double-precision normalized samples. % If FMT='native', Y contains samples in the native data type % found in the file. Interpretation of FMT is case-insensitive, % and partial matching is supported. If omitted, FMT='double'. % % SIZ=WAVREAD(FILE,'size') returns the size of the audio data contained % in the file in place of the actual audio data, returning the % 2-element vector SIZ=[samples channels]. % % [Y,FS,NBITS,OPTS]=WAVREAD(...) returns a structure OPTS of additional % information contained in the WAV file. The content of this % structure differs from file to file. Typical structure fields % include '.fmt' (audio format information) and '.info' (text % which may describe title, author, etc.) % % Output Scaling % The range of values in Y depends on the data format FMT specified. % Some examples of output scaling based on typical bit-widths found % in a WAV file are given below for both 'double' and 'native' formats. % FMT='native' % #Bits MATLAB data type Data range % ----- ------------------------- ------------------- % 8 uint8 (unsigned integer) 0 ext(2) msg = 'Sample limits must be given in ascending order.'; return end end bytes_remaining = total_bytes; % Preset byte counter % Skip over leading samples: if ext(1)>1 % Skip over leading samples, if specified: skipcnt = BytesPerSample * (ext(1)-1) * wavefmt.nChannels; if(fseek(datack.fid, skipcnt,'cof') == -1), msg = 'Error reading PCM file format.'; return end % % Update count of bytes remaining: bytes_remaining = bytes_remaining - skipcnt; end % Read desired data: nSPCext = ext(2)-ext(1)+1; % # samples per channel in extraction range dat = datack; % Copy input structure to output % extSamples = wavefmt.nChannels*nSPCext; dat.Data = fread(datack.fid, [wavefmt.nChannels nSPCext], dtype); % % Update count of bytes remaining: skipcnt = BytesPerSample*nSPCext*wavefmt.nChannels; bytes_remaining = bytes_remaining - skipcnt; % if cnt~=extSamples, dat='Error reading file.'; return; end % Skip over trailing samples: if(fseek(datack.fid, BytesPerSample * ... (SamplesPerChannel-ext(2))*wavefmt.nChannels, 'cof')==-1), msg = 'Error reading PCM file format.'; return end % Update count of bytes remaining: skipcnt = BytesPerSample*(SamplesPerChannel-ext(2))*wavefmt.nChannels; bytes_remaining = bytes_remaining - skipcnt; % Determine if a pad-byte is appended to data chunk, % skipping over it if present: if rem(datack.Size,2), fseek(datack.fid, 1, 'cof'); end % Rearrange data into a matrix with one channel per column: dat.Data = dat.Data'; if ~isNative % Normalize data range: min will hit -1, max will not quite hit +1. if BytesPerSample==1, dat.Data = (dat.Data-128)/128; % [-1,1) elseif BytesPerSample==2, dat.Data = dat.Data/32768; % [-1,1) elseif BytesPerSample==3, dat.Data = dat.Data/(2^23); % [-1,1) elseif BytesPerSample==4, if wavefmt.wFormatTag ~= 3, % Type 3 32-bit is already normalized dat.Data = dat.Data/32768; % [-1,1) end end end % --------------------------------------------- function [file,ext,isNative] = parseArgs(varargin) %ParseArgs Parse input arguments to wavread % Supported syntax: % WAVREAD(FILE) % Caller must provide FILE % WAVREAD(FILE,EXT) % EXT may be N or [N1 N2] % If omitted, returns ext=[] (e.g., read all samples) % WAVREAD(FILE,EXT,FMT) % FMT = 'native' or 'double' % Default if omitted: 'double' % WAVREAD(FILE,'size') % No FMT arg can be passed with 'size' % % An apparently undocument behavior was: % EXT=[] maps to 'size' call % This behavior is maintained. % % Another apparently undocumented behavior was: % EXT=0 or EXT=[0 0] also map to 'size' % We maintain this behavior as well, but issue a warning. % % In the future, we will process this as "no data to read" and % return with an empty data set and no error. % Defaults: ext=[]; % extent: start and stop index of samples to read isNative=false; isSize=false; if nargin==0 error('wavread:TooFewArguments', ... 'Too few input arguments.'); end % Get file name: WAVREAD(FILE, ...) file = varargin{1}; varargin(1)=[]; if isempty(varargin), return; end % See if a FMT option or 'size' was passed fmt=varargin{end}; if ischar(fmt) idx = find(strncmpi(fmt,{'double','native','size'},numel(fmt))); if isempty(idx) error('wavread:UnrecognizedDataFormatSpecified', ... 'Unrecognized data format specified: "%s"', fmt); elseif idx==2 isNative=true; elseif idx==3 ext='size'; isSize=true; else % idx==1 isNative=false; end % Remove parsed option varargin(end)=[]; if isempty(varargin), return; end end % Another arg is present nargs = numel(varargin); if isSize && (nargs>0) error('wavread:SizeAndSampleRange', ... 'Too many arguments with ''size'' option.'); end % Can only be one more argument passed: extent if nargs>1 error('wavread:TooManyInputArgs', ... 'Too many input arguments, or invalid argument order.'); end ext = varargin{1}; exts = numel(ext); % length of extent info if ~isnumeric(ext) || ~isreal(ext) || ~isreal(ext) ... || issparse(ext) || (exts>2) error('wavread:InvalidSampleRange', ... 'Index range must be specified as a scalar or 2-element vector.'); end if isempty(ext) warning('wavread:ReturnZeroSamples', ... sprintf(['Passing [] for sample range currently returns total file size, ', ... 'equivalent to the ''size'' option. In the future, this behavior ', ... 'will be removed. Use the ''size'' option if you wish to obtain ', ... 'the file size.'])); % For now, map this to a 'size' call % In the future, remove this "elseif" entirely and flow % into the "isscalar" test below ext='size'; elseif isequal(ext,0) warning('wavread:ReturnZeroSamples', ... sprintf(['Requesting 0 samples currently returns total file size, ', ... 'equivalent to the ''size'' option. In the future, this ', ... 'behavior will change to return zero data samples from the ', ... 'file (i.e., return with an empty matrix). Use the ''size'' ', ... 'option if you wish to obtain the file size.'])); % For now, map this to a 'size' call % In the future, remove this "elseif" entirely and flow % into the "isscalar" test below ext='size'; elseif isscalar(ext) if (ext ~= floor(ext)) || (extRelated Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.