function y = celp( x ) % function y = celp( x ) % % Simulation of pure CELP Codec % % x: codec input signal (sampled with 8 kHz, 16-bit quantized, i.e range -32768 ... 32767) % y: codec output signal (sampled with 8 kHz, 16-bit quantized, i.e range -32768 ... 32767) % % Author: Markus Hauenstein % Date: 03.01.2002 % Contact: www.markus-hauenstein.de % % This program is copyrighted. test = 0; fprintf(1,'\nSimulation of pure CELP') fprintf(1,'\nInitializing') % % init parameters identical for both coder and decoder which influence the bitrate % % lpc: bits for quantization of predictor coefficients predQuantBits = 3*[1 1 1 1 1 1 1 1 1]; blockLength = 320; % size of stochastic gain codebook stochGainCBSize = 64; % size of stochastic Vector codebook stochVecCBSize = 128; % % init parameters identical for both coder and decoder which do NOT influence the bitrate % % lpc lpcOrder = length(predQuantBits); %larMaxQ = 2.5; % create stochastic gain codebook minStochGain = -512; maxStochGain = 512; stochGainCBmu = 64; stochGainCB = crmucb(minStochGain, maxStochGain, stochGainCBmu, stochGainCBSize); % create normalized stochastic Vector codebook stochCBAmp = 16; randn('seed',0); stochVecCB = randn( blockLength, stochVecCBSize ); for i=1:stochVecCBSize, oneDivRms = 1/sqrt((stochVecCB(:,i)' * stochVecCB(:,i)) / blockLength); stochVecCB(:,i) = oneDivRms * stochVecCB(:,i); end stochVecCB = stochCBAmp * stochVecCB; % calculate and display required bitrate sampleFrequency = 8000; lpcBitRate = sum( predQuantBits ) * sampleFrequency / blockLength; stochVecBitRate = ceil( log(stochVecCBSize)/log(2) ) * sampleFrequency / blockLength; stochGainBitRate = ceil( log(stochGainCBSize)/log(2) ) * sampleFrequency / blockLength; bitRate = lpcBitRate + stochVecBitRate + stochGainBitRate; fprintf(1, '\nBitrate: %d bps', bitRate) % format Input signal x=x(:); % make column Vec inputLength = length(x); rest = inputLength - blockLength * floor(inputLength/blockLength); if rest == 0, numberOfBlocks = inputLength / blockLength; else numberOfBlocks = ceil( inputLength / blockLength ); x = [x; zeros( blockLength-rest, 1 )]; end % initialize data storage for transmitted parameters aChannel = zeros(lpcOrder, numberOfBlocks); stochVecChannel = zeros(1, numberOfBlocks); stochGainChannel = zeros(1, numberOfBlocks); % % THIS IS CODER % fprintf(1,'\nCoding ') % initialize coder variables % lpc zInvLpc = zeros(lpcOrder,1); % Vector quantization of LPC/LTP residual - helper variables for Vector quantization synFilterOutSignals = zeros( blockLength, stochVecCBSize ); zeroInput = zeros(blockLength,1); % coder main loop blockIndex = 1 : blockLength; for i=1:numberOfBlocks, fprintf(1,'.') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % get current block xBlock = x( blockIndex ); blockIndex = blockIndex + blockLength; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % LPC lpcInputBlock = xBlock; % calculate linear prediction coefficients a = linpred( lpcInputBlock, lpcOrder ); % simulate quantization of LPC parameters %aQ = larpredq( a, larMaxQ, predQuantBits ); aQ = lsfpredq( a, predQuantBits ); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Analysis-by-Synthesis: % take filter states into account zeroOutput = filter(1, [1;-aQ], zeroInput, zInvLpc); target = xBlock - zeroOutput; % calculate all possible synthezized speech vectors for l=1:stochVecCBSize, synFilterOutSignals(:,l) = filter( 1, [1;-aQ], stochVecCB(:,l) ); end % Vector quantization of target [bestStochGainIndex, bestStochVecIndex] = gsvecq( target, stochGainCB, synFilterOutSignals ); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % calculate lpc filter states for next looping invLpcInputBlock = stochGainCB(bestStochGainIndex) * stochVecCB(:,bestStochVecIndex); [dummy, zInvLpc] = filter(1, [1;-aQ], invLpcInputBlock, zInvLpc); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % simulate transmission of parameters via channel to decoder aChannel(:,i) = aQ; stochGainChannel(i) = bestStochGainIndex; stochVecChannel(i) = bestStochVecIndex; end % coder main loop % % THIS IS DECODER % fprintf(1,'\nDecoding') % initialize decoder variables y = zeros(numberOfBlocks*blockLength,1); % inverse lpc zInvLpc = zeros(lpcOrder,1); % decoder main loop blockIndex = 1 : blockLength; for i=1:numberOfBlocks, fprintf(1,'.') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Inverse LPC invLpcInputBlock = stochGainCB(stochGainChannel(i)) * stochVecCB(:,stochVecChannel(i)); a = aChannel(:,i); [invLpcOutputBlock, zInvLpc] = filter(1, [1;-a], invLpcInputBlock, zInvLpc); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % construct output signal yBlock = invLpcOutputBlock; y( blockIndex ) = yBlock; blockIndex = blockIndex + blockLength; end % decoder main loop % format Output signal y = y(1:inputLength); if test == 1, clg plot(x,'g') hold plot(y,'r') end fprintf(1,'\nReady\n')