diff --git a/Level_3/AACoder3.m b/Level_3/AACoder3.m index d322cb2..712b50d 100644 --- a/Level_3/AACoder3.m +++ b/Level_3/AACoder3.m @@ -75,7 +75,10 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) % TODO: what happens on the first two frames? SL = frameF(:, 1); SR = frameF(:, 2); - continue; + GL = 0; + GR = 0; + sfcL = 0; + sfcR = 0; else prev1FrameStart = (i - 1) * 1024 + 1; prev1FrameStop = prev1FrameStart + 2047; @@ -93,13 +96,19 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) 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; end - [streamL, huffcodebookL] = encodeHuff(SL, huffLUT); - [streamR, huffcodebookR] = encodeHuff(SR, huffLUT); - [sfcL, ~] = encodeHuff(sfcL, huffLUT, 12); - [sfcR, ~] = encodeHuff(sfcR, huffLUT, 12); + TL = 0; + TR = 0; + streamL = SL; + huffcodebookL = 0; + streamR = SR; + huffcodebookR = 0; + +% [streamL, huffcodebookL] = encodeHuff(SL, huffLUT); +% [streamR, huffcodebookR] = encodeHuff(SR, huffLUT); +% [sfcL, ~] = encodeHuff(sfcL, huffLUT, 12); +% [sfcR, ~] = encodeHuff(sfcR, huffLUT, 12); AACSeq3(i + 1).frameType = frameTypes(i + 1); AACSeq3(i + 1).winType = WINDOW_TYPE; @@ -115,20 +124,7 @@ 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); - - if false - [idx,label] = grp2idx(sort(frameTypes)); - hist(idx,unique(idx)); - set(gca,'xTickLabel',label) - - sum(idx(:) == 1) - sum(idx(:) == 2) - sum(idx(:) == 3) - sum(idx(:) == 4) - end + save(fnameAACoded, 'AACSeq3'); end diff --git a/Level_3/AACquantizer.m b/Level_3/AACquantizer.m index 67fd079..382d195 100644 --- a/Level_3/AACquantizer.m +++ b/Level_3/AACquantizer.m @@ -72,11 +72,49 @@ function [S, sfc, G] = AACquantizer(frameF, frameType, SMR) 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)); + T(SHORT_WINDOW_NUMBER_OF_BANDS, 1) = 0; + quantCoeff(SHORT_WINDOW_NUMBER_OF_BANDS, 1) = 0; + sfc(SHORT_WINDOW_NUMBER_OF_BANDS, 8) = 0; + G(1, 8) = 0; + for subFrameIndex = 1:8 + currFrameStart = (subFrameIndex - 1) * 128 + 1; + currFrameStop = currFrameStart + 127; + subFrame = frameF(currFrameStart:currFrameStop); + for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS + frameWlow = TNSTables.B219b(band, 2); + frameWhigh = TNSTables.B219b(band, 3); + subFrameF = subFrame(frameWlow + 1:frameWhigh + 1); + + T(band) = sumsqr(subFrameF) ./ SMR(band); + + % Calculates an initial quantization coefficient and attempts + % quantization + quantCoeff(band) = 16 * log2(max(subFrame) ^ (3 / 4) / 8191) / 3; + S(currFrameStart + frameWlow:currFrameStart + frameWhigh, 1) = sign(subFrameF) .* floor(( ... + abs(subFrameF) .* 2 ^ (-quantCoeff(band) / 4)) ... + .^ (3 / 4) + 0.4054); + + % Calculates current quantization error + quantErr = sumsqr(subFrameF - S(currFrameStart + frameWlow:currFrameStart + 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(currFrameStart + frameWlow:currFrameStart + frameWhigh) = sign(subFrameF) .* round(( ... + abs(subFrameF) .* 2 ^ (-quantCoeff(band) / 4)) ... + .^ (3 / 4) + 0.4054); + + quantErr = sumsqr(subFrameF - S(currFrameStart + frameWlow:currFrameStart + frameWhigh)); + end + + if band == 1 + sfc(band, subFrameIndex) = quantCoeff(band); + else + sfc(band, subFrameIndex) = quantCoeff(band) - quantCoeff(band - 1); + end + end + G(1, subFrameIndex) = quantCoeff(1); end - T = T ./ SMR; end end diff --git a/Level_3/decoded2.wav b/Level_3/decoded2.wav new file mode 100644 index 0000000..acd03f6 Binary files /dev/null and b/Level_3/decoded2.wav differ diff --git a/Level_3/encoded.mat b/Level_3/encoded.mat new file mode 100644 index 0000000..d2d4dec Binary files /dev/null and b/Level_3/encoded.mat differ diff --git a/Level_3/iAACoder3.m b/Level_3/iAACoder3.m index 972c557..df53e1f 100644 --- a/Level_3/iAACoder3.m +++ b/Level_3/iAACoder3.m @@ -41,30 +41,50 @@ function x = iAACoder3(AACSeq3, fNameOut) decodedAudio(1024 * (length(AACSeq3) + 1), 2) = 0; % Initializes an array to hold both audio channels frameF(1024, 2) = 0; - + % Decodes audio file huffLUT = loadLUT(); for i = 0:length(AACSeq3) - 1 currFrameStart = i * 1024 + 1; currFrameStop = currFrameStart + 2047; - - SL = decodeHuff(AACSeq3(i + 1).chl.stream, ... - AACSeq3(i + 1).chl.codebook, huffLUT); - SR = decodeHuff(AACSeq3(i + 1).chr.stream, ... - AACSeq3(i + 1).chr.codebook, huffLUT); - - sfcL = decodeHuff(AACSeq3(i + 1).chl.sfc, 12, huffLUT); % TODO: maybe LUT(12); - sfcR = decodeHuff(AACSeq3(i + 1).chr.sfc, 12, huffLUT); - - frameF(:, 1) = iAACquantizer(SL, sfcL, AACSeq3(i + 1).chl.G, AACSeq3(i+1).frameType); - frameF(:, 2) = iAACquantizer(SR, sfcR, AACSeq3(i + 1).chr.G, AACSeq3(i+1).frameType); - - TNScoeffsL = AACSeq3(i + 1).chl.TNScoeffs; - TNScoeffsR = AACSeq3(i + 1).chr.TNScoeffs; - frameF(:, 1) = iTNS(frameF(:, 1), AACSeq3(i+1).frameType, TNScoeffsL); - frameF(:, 2) = iTNS(frameF(:, 2), AACSeq3(i+1).frameType, TNScoeffsR); - frameT = iFilterbank(frameF, AACSeq3(i+1).frameType, AACSeq3(i+1).winType); - + + if i < 2 + frameF(:, 1) = iTNS(AACSeq3(i + 1).chl.stream, ... + AACSeq3(i+1).frameType, ... + AACSeq3(i + 1).chl.TNScoeffs); + frameF(:, 2) = iTNS(AACSeq3(i + 1).chr.stream, ... + AACSeq3(i+1).frameType, ... + AACSeq3(i + 1).chr.TNScoeffs); + + frameT = iFilterbank(frameF, AACSeq3(i+1).frameType, AACSeq3(i+1).winType); + else + % SL = decodeHuff(AACSeq3(i + 1).chl.stream, ... + % AACSeq3(i + 1).chl.codebook, huffLUT); + % SR = decodeHuff(AACSeq3(i + 1).chr.stream, ... + % AACSeq3(i + 1).chr.codebook, huffLUT); + % + % sfcL = decodeHuff(AACSeq3(i + 1).chl.sfc, 12, huffLUT); + % sfcR = decodeHuff(AACSeq3(i + 1).chr.sfc, 12, huffLUT); + + frameF(:, 1) = iAACquantizer(AACSeq3(i + 1).chl.stream, ... + AACSeq3(i + 1).chl.sfc, ... + AACSeq3(i + 1).chl.G, ... + AACSeq3(i+1).frameType); + frameF(:, 2) = iAACquantizer(AACSeq3(i + 1).chr.stream, ... + AACSeq3(i + 1).chr.sfc, ... + AACSeq3(i + 1).chr.G, ... + AACSeq3(i+1).frameType); + + frameF(:, 1) = iTNS(frameF(:, 1), ... + AACSeq3(i+1).frameType, ... + AACSeq3(i + 1).chl.TNScoeffs); + frameF(:, 2) = iTNS(frameF(:, 2), ... + AACSeq3(i+1).frameType, ... + AACSeq3(i + 1).chr.TNScoeffs); + + frameT = iFilterbank(frameF, AACSeq3(i+1).frameType, AACSeq3(i+1).winType); + end + decodedAudio(currFrameStart:currFrameStop, :) = decodedAudio(currFrameStart:currFrameStop, :) + frameT; end diff --git a/Level_3/iAACquantizer.m b/Level_3/iAACquantizer.m index 9f24167..778019e 100644 --- a/Level_3/iAACquantizer.m +++ b/Level_3/iAACquantizer.m @@ -19,6 +19,47 @@ function frameF = iAACquantizer(S, sfc, G, frameType) % representation containing only one of the audio channels stored in % a vector of length 1024 + % 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') + for band = 1:LONG_WINDOW_NUMBER_OF_BANDS + frameWlow = TNSTables.B219a(band, 2) + 1; + frameWhigh = TNSTables.B219a(band, 3) + 1; + subFrameS = S(frameWlow:frameWhigh); + + if band > 1 + sfc(band) = sfc(band) + sfc(band - 1); + end + frameF(frameWlow:frameWhigh) = sign(subFrameS) .* ... + abs(subFrameS) .^ (4 / 3) .* 2 ^ (sfc(band) / 4); + end + else + for subFrameIndex = 1:8 + currFrameStart = (subFrameIndex - 1) * 128 + 1; + currFrameStop = currFrameStart + 127; + subFrame = S(currFrameStart:currFrameStop); + for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS + frameWlow = TNSTables.B219b(band, 2); + frameWhigh = TNSTables.B219b(band, 3); + subFrameS = subFrame(frameWlow + 1:frameWhigh + 1); + + if band > 1 + sfc(band, subFrameIndex) = sfc(band, subFrameIndex) + ... + sfc(band - 1, subFrameIndex); + end + + frameF(currFrameStart + frameWlow:currFrameStart + frameWhigh) = sign(subFrameS) .* ... + abs(subFrameS) .^ (4 / 3) .* 2 ^ (sfc(band) / 4); + end + end + end +end