diff --git a/Level_3/AACoder3.m b/Level_3/AACoder3.m index 8a7945f..388158b 100644 --- a/Level_3/AACoder3.m +++ b/Level_3/AACoder3.m @@ -103,6 +103,7 @@ function AACSeq3 = AACoder3(fNameIn, fnameAACoded) frameTypes{i+1}, ... originalAudioData(prev1FrameStart:prev1FrameStop, 2), ... originalAudioData(prev2FrameStart:prev2FrameStop, 2)); + continue; [SL, sfcL, GL] = AACquantizer(frameF, frameTypes{i+1}, SMRL); [SR, sfcR, GR] = AACquantizer(frameF, frameTypes{i+1}, SMRR); end diff --git a/Level_3/psycho.m b/Level_3/psycho.m index e1d279f..93b7fd8 100644 --- a/Level_3/psycho.m +++ b/Level_3/psycho.m @@ -64,9 +64,9 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) tmpSum = tmpz + tmpy; spreadingShort(tmpy >= -100) = 10 .^ (tmpSum(tmpy >= -100) ./ 10); - hannLong = 0.5 - 0.5 * cos((pi * (0:2047 + 0.5)) / 1024); - hannShort = 0.5 - 0.5 * cos((pi * (0:255 + 0.5)) / 128); - + hannLong = 0.5 - 0.5 * cos(pi * ((0:2047) + 0.5) / 1024); + hannShort = 0.5 - 0.5 * cos(pi * ((0:255) + 0.5) / 128); + clearvars tmpx tmpz tmpy end @@ -122,24 +122,111 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) % Renormalizes values bandPredictabilityConv = bandPredictabilityConv ./ bandEnergyConv; bandEnergyConv = bandEnergyConv ./ sum(spreadingLong, 1)'; - + % Calculates the tonality index tonalIndex = -0.299 - 0.43 .* log(bandPredictabilityConv); tonalIndex(tonalIndex < 0) = 0; tonalIndex(tonalIndex > 1) = 1; - + % Calculates SNR and converts from dB to power ratio signalToNoiseRatio = tonalIndex .* TONE_MASKING_NOISE + ... (1 - tonalIndex) .* NOISE_MASKING_TONE; powerRatio = 10 .^ (-signalToNoiseRatio ./ 10); - + % Calculates the energy threshold energyThreshold = bandEnergyConv .* powerRatio; - + % Calculates the noise level qThrN = eps() * 1024 .* 10 .^ (TNSTables.B219a(:, 6) ./ 10); noiseLevel = max(energyThreshold, qThrN); - + SMR = bandEnergy ./ noiseLevel'; + else + % Splits the frame into sub-frames + [subFramesT, ~] = buffer(frameT(449:end-448), 256, 128, 'nodelay'); + [subFramesTprev1, ~] = buffer(frameTprev1(449:end-448), 256, 128, 'nodelay'); + + bandEnergy(SHORT_WINDOW_NUMBER_OF_BANDS) = 0; + bandPredictability(SHORT_WINDOW_NUMBER_OF_BANDS) = 0; + qThrN = eps() * 128 .* 10 .^ (TNSTables.B219b(:, 6) ./ 10); + SMR(SHORT_WINDOW_NUMBER_OF_BANDS, 8) = 0; + + for subFrameIndex = 1:8 + % Applies window to the frames + windowedFrameT = subFramesT(:, subFrameIndex) .* hannShort'; + if subFrameIndex == 1 + windowedFrameTprev1 = subFramesTprev1(:, 8) .* hannShort'; + windowedFrameTprev2 = subFramesTprev1(:, 7) .* hannShort'; + elseif subFrameIndex == 2 + windowedFrameTprev1 = subFramesT(:, subFrameIndex - 1) .* hannShort'; + windowedFrameTprev2 = subFramesTprev1(:, 8) .* hannShort'; + else + windowedFrameTprev1 = subFramesT(:, subFrameIndex - 1) .* hannShort'; + windowedFrameTprev2 = subFramesT(:, subFrameIndex - 1) .* hannShort'; + end + + % Calculates the FFT of each frame + frameF = fft(windowedFrameT); + frameFMag = abs(frameF(1:128)); + frameFPhase = angle(frameF(1:128)); + + frameFrameFprev1 = fft(windowedFrameTprev1); + frameFrameFprev1Mag = abs(frameFrameFprev1(1:128)); + frameFrameFprev1Phase = angle(frameFrameFprev1(1:128)); + + frameFrameFprev2 = fft(windowedFrameTprev2); + frameFrameFprev2Mag = abs(frameFrameFprev2(1:128)); + frameFrameFprev2Phase = angle(frameFrameFprev2(1:128)); + + % Calculates the predicted magnitude and phase compontents of each + % frequency + magPred = 2 .* frameFrameFprev1Mag - frameFrameFprev2Mag; + phasePred = 2 .* frameFrameFprev1Phase - frameFrameFprev2Phase; + + % Calculates this frame's predictability + framePredictability = sqrt((frameFMag .* cos(frameFPhase) - ... + magPred .* cos(phasePred)) .^ 2 + ... + (frameFMag .* sin(frameFPhase) - ... + magPred .* sin(phasePred)) .^ 2) ./ ... + (frameFMag + abs(magPred)); + + % Calculates the energy and weighted predictability in the + % threshold calculation partitions + for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS + bandEnergy(band) = sumsqr(frameFMag(TNSTables.B219b(band, 2) + 1: ... + TNSTables.B219b(band, 3) + 1)); + bandPredictability(band) = sum(frameFMag( ... + TNSTables.B219b(band, 2) + 1:TNSTables.B219b(band, 3) + 1) .^ 2 .* ... + framePredictability(TNSTables.B219b(band, 2) + 1: ... + TNSTables.B219b(band, 3) + 1)); + end + + % Convolves the partitioned energy and predictability with the + % spreading function + bandEnergyConv = sum(bandEnergy .* spreadingShort', 2); + bandPredictabilityConv = sum(bandPredictability .* spreadingShort', 2); + + % Renormalizes values + bandPredictabilityConv = bandPredictabilityConv ./ bandEnergyConv; + bandEnergyConv = bandEnergyConv ./ sum(spreadingShort, 1)'; + + % Calculates the tonality index + tonalIndex = -0.299 - 0.43 .* log(bandPredictabilityConv); + tonalIndex(tonalIndex < 0) = 0; + tonalIndex(tonalIndex > 1) = 1; + + % Calculates SNR and converts from dB to power ratio + signalToNoiseRatio = tonalIndex .* TONE_MASKING_NOISE + ... + (1 - tonalIndex) .* NOISE_MASKING_TONE; + powerRatio = 10 .^ (-signalToNoiseRatio ./ 10); + + % Calculates the energy threshold + energyThreshold = bandEnergyConv .* powerRatio; + + % Calculates the noise level + noiseLevel = max(energyThreshold, qThrN); + + SMR(:, subFrameIndex) = bandEnergy ./ noiseLevel'; + end end end