diff --git a/Level_3/AACoder3.m b/Level_3/AACoder3.m index 388158b..98ec16b 100644 --- a/Level_3/AACoder3.m +++ b/Level_3/AACoder3.m @@ -39,16 +39,6 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) % Declares constant window type WINDOW_TYPE = 'SIN'; - - % Declares constant numbers of bands for long and short windows - LONG_WINDOW_NUMBER_OF_BANDS = 69; - SHORT_WINDOW_NUMBER_OF_BANDS = 42; - - % Declares persistent variable holding the TNS tables and initializes if empty - persistent TNSTables; - if isempty(TNSTables) - TNSTables = load('TableB219.mat'); - end % Reads the audio file [originalAudioData, ~] = audioread(fNameIn); @@ -74,8 +64,6 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) % Encodes audio file huffLUT = loadLUT(); AACSeq3(length(frameTypes)) = struct; - TL(LONG_WINDOW_NUMBER_OF_BANDS) = 0; - TR(LONG_WINDOW_NUMBER_OF_BANDS) = 0; for i = 0:length(frameTypes) - 1 currFrameStart = i * 1024 + 1; currFrameStop = currFrameStart + 2047; @@ -103,19 +91,10 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) frameTypes{i+1}, ... originalAudioData(prev1FrameStart:prev1FrameStop, 2), ... originalAudioData(prev2FrameStart:prev2FrameStop, 2)); + [SL, sfcL, GL] = AACquantizer(frameF(:, 1), frameTypes{i+1}, SMRL); + [SR, sfcR, GR] = AACquantizer(frameF(:, 2), frameTypes{i+1}, SMRR); continue; - [SL, sfcL, GL] = AACquantizer(frameF, frameTypes{i+1}, SMRL); - [SR, sfcR, GR] = AACquantizer(frameF, frameTypes{i+1}, SMRR); end - - for band = 1:LONG_WINDOW_NUMBER_OF_BANDS - TL(band) = sumsqr(frameF((TNSTables.B219a(band, 2) + 1: ... - TNSTables.B219a(band, 3) + 1), 1)); - TR(band) = sumsqr(frameF((TNSTables.B219a(band, 2) + 1: ... - TNSTables.B219a(band, 3) + 1), 2)); - end - TL = TL ./ SMRL; - TR = TR ./ SMRR; [streamL, huffcodebookL] = encodeHuff(SL, huffLUT); [streamR, huffcodebookR] = encodeHuff(SR, huffLUT); @@ -136,6 +115,8 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) AACSeq3(i + 1).chr.stream = streamR; AACSeq3(i + 1).chl.codebook = huffcodebookL; AACSeq3(i + 1).chr.codebook = huffcodebookR; + + clearvars TL TR; end save(fnameAACoded,AACSeq3); diff --git a/Level_3/AACquantizer.m b/Level_3/AACquantizer.m index 8cb4af4..67fd079 100644 --- a/Level_3/AACquantizer.m +++ b/Level_3/AACquantizer.m @@ -21,6 +21,62 @@ function [S, sfc, G] = AACquantizer(frameF, frameType, SMR) % - G is the global gain stored in an array of dimensions 1X8 for % EIGHT_SHORT_SEQUENCE frames and a single value otherwise + % Declares constant numbers of bands for long and short windows + LONG_WINDOW_NUMBER_OF_BANDS = 69; + SHORT_WINDOW_NUMBER_OF_BANDS = 42; -end + % Declares persistent variable holding the TNS tables and initializes if empty + persistent TNSTables; + if isempty(TNSTables) + TNSTables = load('TableB219.mat'); + end + + if ~strcmp(frameType, 'ESH') + T(LONG_WINDOW_NUMBER_OF_BANDS, 1) = 0; + quantCoeff(LONG_WINDOW_NUMBER_OF_BANDS, 1) = 0; + sfc(LONG_WINDOW_NUMBER_OF_BANDS, 1) = 0; + for band = 1:LONG_WINDOW_NUMBER_OF_BANDS + frameWlow = TNSTables.B219a(band, 2) + 1; + frameWhigh = TNSTables.B219a(band, 3) + 1; + subFrameF = frameF(frameWlow:frameWhigh); + + T(band) = sumsqr(subFrameF) ./ SMR(band); + + % Calculates an initial quantization coefficient and attempts + % quantization + quantCoeff(band) = 16 * log2(max(frameF) ^ (3 / 4) / 8191) / 3; + S(frameWlow:frameWhigh, 1) = sign(subFrameF) .* floor(( ... + abs(subFrameF) .* 2 ^ (-quantCoeff(band) / 4)) ... + .^ (3 / 4) + 0.4054); + + % Calculates current quantization error + quantErr = sumsqr(subFrameF - S(frameWlow:frameWhigh)); + % Gradually increases the quantization coefficient + while quantErr < T(band) && (band > 1 || ... + (quantErr(band) - quantErr(band - 1) + 1) <= 60) + quantCoeff(band) = quantCoeff(band) + 1; + + S(frameWlow:frameWhigh) = sign(subFrameF) .* round(( ... + abs(subFrameF) .* 2 ^ (-quantCoeff(band) / 4)) ... + .^ (3 / 4) + 0.4054); + + quantErr = sumsqr(subFrameF - S(frameWlow:frameWhigh)); + end + + if band == 1 + sfc(band) = quantCoeff(band); + else + sfc(band) = quantCoeff(band) - quantCoeff(band - 1); + end + end + G = quantCoeff(1); + else + T(SHORT_WINDOW_NUMBER_OF_BANDS) = 0; + for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS + T(band) = sumsqr(frameF((TNSTables.B219b(band, 2) + 1: ... + TNSTables.B219b(band, 3) + 1), 1)); + end + T = T ./ SMR; + end +end