summaryrefslogtreecommitdiff
path: root/libavcodec/aacenc_tns.c
Commit message (Collapse)AuthorAgeFilesLines
* AAC encoder: check for NaNs/inf in TNS gainClaudio Freire2016-01-211-7/+10
| | | | | Can happen in cases where's there's zero autocorrelation (pulses), and it also implies NaN/inf coeffs
* libavcodec/aacenc_tnc.c: remove unused variable w2Claudio Freire2016-01-171-1/+1
| | | | No longer needed since previous commit
* AAC encoder: TNS fixes on short windowsClaudio Freire2016-01-171-11/+7
| | | | | | TNS was computing filter coefficients incorrectly for short windows due to a few coefficient addressing bugs. Fixing them fixes lots of instability with transients (short windows).
* aacenc_tns: use 4 bits for short windowsRostislav Pehlivanov2015-12-081-1/+1
| | | | | | | | With only 7 coefficients per short window at most the extra precision makes a difference and seems to reduce crackling and stddev even further. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: tune and reduce artifactsRostislav Pehlivanov2015-12-061-40/+26
| | | | | | | | | | | | | | | | | | | | There are a couple of major changes here: 1. Start using TNS coefficient compression. 2. Start using 3 bits per coefficient maximum for short windows. The bits we save from these 2 changes seem to make a nice impact on the rest of the file/windows. 3. Remove special case gain checking for short windows. 4. Modify the coefficient loop to support up to 3 windows. The additional restrictions on TNS were something that was no in the specifications and furthermore restricting TNS to only low energy short windows was done to compensate for bugs elsewhere in the code. Overall, the improvements here reduce crackling artifacts heard in very noisy tracks. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_ltp: use an AR filter for LTP encoding as wellRostislav Pehlivanov2015-12-051-14/+5
| | | | | | | Seems to work better. Information on why the decoder does this is lacking. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: rework TNS descision logicRostislav Pehlivanov2015-10-171-35/+40
| | | | | | | | | | | | | | | | | Changes: - strongly prefer dual filters to a single filter - less strict about using 2 filters w.r.t. energy - scrap the usage of threshold and spread, useless - use odd-shaped windows to set the filter direction - use 4 bits instead of 3 bits for short windows - simplify and reduce the main loop to a single level - add stricter regulations for short windows All of this now makes the TNS implementation operate as good as it can and it definitely shows. The frequency thresholds are now even better defined by looking at the spectrals and the overall sound has been improved at the price of just a few bits that are well worth it.
* aacenc_tns: simplify encoding functionRostislav Pehlivanov2015-10-171-18/+18
| | | | | | It's simpler and has 2 less levels than the previous which was practically lifted from the decoder with put_bits() instead of get_bits().
* aacenc_tns: disable coefficient compression by defaultRostislav Pehlivanov2015-10-171-11/+15
| | | | | | | | | | Too much effort and work has been spent on such a simple function. It simply refuses to work as the specifications say, the transformation is NOT lossless and creates some crackling and distortions. Therefore disable it by default and add a couple of warnings to scare people away from touching it or wasting their time the way I did.
* aacenc_tns: add moving average filter for LTPRostislav Pehlivanov2015-10-171-5/+16
| | | | | | The decoder does this so I guess we better do that as well. There's barely any difference between the autoregressive and the moving average filters looking at spectrals though.
* aacenc_tns: fix coefficient compression conditionRostislav Pehlivanov2015-09-161-1/+1
| | | | Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: encode coefficients directly and reenable compressionRostislav Pehlivanov2015-09-121-8/+25
| | | | | | | | | | | | | | | This commit was made possible with the earlier commits since the new quantization method basically means we're working always with unsigned values. The specifications mention to use compression when the first 2 bits are identical but they didn't mention if this should happen before or after the conversion to signed values. Actually they said nothing about conversion to signed values. With this commit, coefficient compression usually always happens which saves a lot of space, especially at extremely low bitrates and doesn't change the quality at all. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: redo coefficient quantization and decision makingRostislav Pehlivanov2015-09-121-26/+34
| | | | | | | | | | | | | | | | | | This finally (and again) gets rid of basically everything the specifications say about how TNS should be done. The main problem used to be that a single filter was used for all coefficients which despite being explicitly recommended by the specifications usually sounds wrong, therefore it's a corner case in the current TNS implementation. This commit also changes the coefficient bit size, as apparently it's better to use lower precision in case the windows are eight short. This is apparently what fdk_aac uses, looking at the bit stream and makes sense. Also the order when 8 SHORT windows happen is important as 7 was too much and according to PSNR was worse while 5 is just about correct. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: adjust coefficient calculation, add double filter supportRostislav Pehlivanov2015-09-051-18/+30
| | | | | | | | | | | | | | | | | | | | This commit improves the TNS implementation to the point where it's actually usable and very rarely results in nastyness (in all bitrates except extremely low bitrates it's increasing the quality and prevents some distortions from the coder being audiable). Also adds a double filter support which is only used if the energy difference between the top and bottom of the SFBs is above the thresholds defined in the header file. Looking at the bitstream that fdk_aac generates it sometimes used a double filter despite the specs stating that a single filter should be enough for almost all cases and purposes. Unlike FAAC or fdk_aac we sometimes use a reverse filter in case the energy difference isn't enought to use a double filter. This actually works better. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: rework coefficient quantization and filter applicationRostislav Pehlivanov2015-09-011-125/+78
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit reworks the TNS implementation to a hybrid between what the specifications say, what the decoder does and what's the best thing to do. The filter application function was copied from the decoder and modified such that it applies the inverse AR filter to the coefficients. The LPC coefficients themselves are fed into the same quantization expression that the specifications say should be used however further processing is not done, instead they're converted to the form that the decoder expects them to be in and are sent off to the compute_lpc_coeffs function exactly the way the decoder does. This function does all conversions and will return the exact coefficients that the decoder will generate, which are then applied to the coefficients. Having the exact same coefficients on both the encoder and decoder is a must since otherwise the entire sfb's over which the filter is applied will be attenuated. Despite this major rework, TNS might not work fine on some audio types at very low bitrates (e.g. sub 90kbps) as it can attenuate some coefficients too much. Users are advised to experiment with TNS at higher bitrates if they wish to use this tool or simply wait for the implementation to be improved. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: do not limit the filter sizeRostislav Pehlivanov2015-08-291-3/+2
| | | | | | | | This was copied from the decoder, but is unneeded for the encoder. tns_max_bands is unused and set to zero which zeroed out start, end and size and thus no filter was actually applied. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* lpc: rename ff_lpc_calc_levinsion to ff_lpc_calc_levinsonRostislav Pehlivanov2015-08-291-2/+2
| | | | Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: fix out-of-bounds array accessRostislav Pehlivanov2015-08-291-1/+4
| | | | | | | | Since the coefficients are stepped up to order + 1 it was possible that it went over TNS_MAX_ORDER. Also just return in case the only coefficient is less than the threshold. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: actually apply TNS filter to the coefficientsRostislav Pehlivanov2015-08-291-2/+0
| | | | | | | The encoder-side filter isn't that important. The PSNR shouldn't change so the FATE test should still be fine. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc: initialize LPC context with MAX_LPC_ORDERRostislav Pehlivanov2015-08-291-1/+1
| | | | | | | | | The order should never go above TNS_MAX_ORDER (and thus cause the context to be reinitialized) but this is just in case. Also fix a comparison, since the coefficients are zero-indexed. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: fix triggering an assertion with assert-level=2Rostislav Pehlivanov2015-08-291-2/+2
| | | | | | | It also made no sense to actually make the filter span the entire window including the first band of the next window. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: rework the way coefficients are calculatedRostislav Pehlivanov2015-08-291-112/+99
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit abandons the way the specifications state to quantize the coefficients, makes use of the new LPC float functions and is much better. The original way of converting non-normalized float samples to int32_t which out LPC system expects was wrong and it was wrong to assume the coefficients that are generated are also valid. It was essentially a full garbage-in, garbage-out system and it definitely shows when looking at spectrals and listening. The high frequencies were very overattenuated. The new LPC function performs the analysis directly. The specifications state to quantize the coefficients into four bit index values using an asin() function which of course had to have ugly ternary operators because the function turns negative if the coefficients are negative which when encoding causes invalid bitstream to get generated. This deviates from this by using the direct TNS tables, which are fairly small since you only have 4 bits at most for index values. The LPC values are directly quantized against the tables and are then used to perform filtering after the requantization, which simply fetches the array values. The end result is that TNS works much better now and doesn't attenuate anything but the actual signal, e.g. TNS removes quantization errors and does it's job correctly now. It might be enabled by default soon since it doesn't hurt and helps reduce nastyness at low bitrates. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: temporarily disableRostislav Pehlivanov2015-08-221-0/+3
| | | | | | Due to segfaults on some platforms, fix will take a bit longer. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc: Add missing ff_ prefixesTimothy Gu2015-08-221-3/+4
| | | | | Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com> Reviewed-by: Ganesh Ajjanagadde <gajjanag@mit.edu>
* aacenc_tns: remove unused headerRostislav Pehlivanov2015-08-211-1/+0
| | | | | | | Thanks to @nevcairiel for pointing this one out. Another thing which stopped msvc from compiling. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: re-enable coefficient compressionRostislav Pehlivanov2015-08-211-7/+11
| | | | | | This time in a platform/compiler-generic way. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: temporarily disable coefficient compressionRostislav Pehlivanov2015-08-211-4/+4
| | | | | | | Hotfix to deal with msvc. Sane compilers lack POSIX ffs(). It only saves a single bit or so and isn't worth it that much. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* aacenc_tns: implement temporal noise shapingRostislav Pehlivanov2015-08-211-0/+235
This commit implements temporal noise shaping support in the encoder, along with an -aac_tns option to toggle it on or off (off by default for now). TNS will increase audio quality and reduce quantization noise by applying a multitap FIR filter across allowed coefficients and transmit side information to the decoder so it could create an inverse filter. Users are encouraged to test the new functionality by enabling -aac_tns 1 during encoding. No major bugs are observable at this time so after a while if no new problems appear and if the current implementation is deemed of high enough quality and stability it will be enabled by default, possibly at the same time the encoder has its experimental flag removed and becomes the standard aac encoder in ffmpeg. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>