mstorsjo / fdk-aac

A standalone library of the Fraunhofer FDK AAC code from Android.
https://sourceforge.net/projects/opencore-amr/
Other
1.18k stars 389 forks source link

decoding an aac file (made using aac-enc.c) using aac-dec.c creates a noisy and sped up wav file #106

Closed mahaju closed 5 years ago

mahaju commented 5 years ago

I am using this aac-enc.c file to encode a wav file to aac: (https://github.com/mstorsjo/fdk-aac/blob/master/aac-enc.c)

I am using this aac-dec.c to decode the resulting aac file: https://github.com/mstorsjo/fdk-aac/commit/a4ba6cc6168c061e6c30b0f8194732f9f297c9de

For the decoder I got the wavwriter.c file from here: https://github.com/BelledonneCommunications/opencore-amr/tree/master/test

The wav file is 44100 hz stereo and about 10 seconds

wav -> acc conversion is working fine and creates an MPEG-4 AAC-LC aac file I can decode this using windows media player and the mac computer's default aac player

I can also decode this using the faad decoder

Using the aac-dec.c file however, I am getting a wav file that is half the duration (about 5 sec) sounds sped up and contains a constant buzzing noise mixed with the wav file audio. The entire wav file is there, but plays in double speed (hence the 10 second music clip plays in 5 seconds) and it's mixed with a buzzing noise in the background

The aac-dec.c file code seems to correctly follow the procedures described in the decoder api documentation https://android.googlesource.com/platform/external/aac/+/android-9.0.0_r3/documentation/

There aren't many input parameters that can be supplied to the decoder either, and it looks like all the decoding information is obtained from the aac frame header and raw aac data itself

What is the mistake here? Ideally, I want to be able to convert a wav to aac using the aac-enc.c file (basic MPEG 2/4 AAC-LC for now) and then reconstruct the original wav from this aac using the aac-dec.c program

mstorsjo commented 5 years ago

I am using this aac-enc.c file to encode a wav file to aac: (https://github.com/mstorsjo/fdk-aac/blob/master/aac-enc.c)

I am using this aac-dec.c to decode the resulting aac file: https://github.com/mstorsjo/fdk-aac/commit/a4ba6cc6168c061e6c30b0f8194732f9f297c9de

For the decoder I got the wavwriter.c file from here: https://github.com/BelledonneCommunications/opencore-amr/tree/master/test

Why do you need to pick that file from some random other repository? The same repository where you took aac-dec.c also contains that file. (Luckily for you, that file actually turns out to be identical to the right one.)

The wav file is 44100 hz stereo and about 10 seconds

wav -> acc conversion is working fine and creates an MPEG-4 AAC-LC aac file I can decode this using windows media player and the mac computer's default aac player

I can also decode this using the faad decoder

Using the aac-dec.c file however, I am getting a wav file that is half the duration (about 5 sec) sounds sped up and contains a constant buzzing noise mixed with the wav file audio. The entire wav file is there, but plays in double speed (hence the 10 second music clip plays in 5 seconds) and it's mixed with a buzzing noise in the background

The aac-dec.c file code seems to correctly follow the procedures described in the decoder api documentation https://android.googlesource.com/platform/external/aac/+/android-9.0.0_r3/documentation/

There aren't many input parameters that can be supplied to the decoder either, and it looks like all the decoding information is obtained from the aac frame header and raw aac data itself

What is the mistake here? Ideally, I want to be able to convert a wav to aac using the aac-enc.c file (basic MPEG 2/4 AAC-LC for now) and then reconstruct the original wav from this aac using the aac-dec.c program

I tried this, but can't reprodue it. Certain profiles can't be used in ADTS, but in that case it wouldn't work with other apps either.

To build it properly, check out the decoder-example branch from this repo, run ./autogen.sh, configure with ./configure --enable-example and it'll build both aac-enc and aac-dec. Then give the exact aac-enc command you use.

mahaju commented 5 years ago

if i use the aac-enc.c and aac-dec.c files from the decoder-example branch you mentioned (https://github.com/mstorsjo/fdk-aac/tree/decoder-example) it's working as expected

I must have used an older version of aac-dec.c before, since I think I found it from some other location

thank you for the help

mahaju commented 5 years ago

Hi sorry but i just have a quick question in the aac-enc.c file from the branhc you mentioned above, aac encoding for aot = 2,5 and 29 are working, but aot = 23, 39 are not working (AAC-LD and AAC-ELD)

These give me error = 0x0043, AACENC_INIT_TP_ERROR, Transport library initialization error

I have tried setting eld_sbr to both 1 and -1, with aot = 39 and I have the same problem

Everything else in the code as well as the input wav file are the same, I only changed the aot value

Is there anything else I need to change in order to do aac-ld or aac-eld encoding?

mstorsjo commented 5 years ago

Yes. As I mentioned, "Certain profiles can't be used in ADTS", that's this issue. You can't mux AAC-LD or -ELD into ADTS.

To mux those profiles, you need to encode with AACENC_TRANSMUX set to TT_MP4_RAW, get the ASC from info.confBuf and info.confSize and mux that together with the raw packages into a different container format like MP4. It should work in LATM (which goes into e.g. mpegts) as well, but I'm not quite as familiar with that format.

I guess I should just remove those profiles from the listing in aac-enc.c as they don't really work there.

mahaju commented 5 years ago

Hi I tried the LD/ELD decoder from the LOAS branch, and it's working fine for the most part, but at very specific locations in the final reconstructed wav file, it sounds as if it is skipping a few milliseconds of audio

Could you give me a hint on why that could be happening please? For encoding I set AACENC_TRANSMUX to TT_MP4_LOAS, and the rest is same as the aac-enc.c code, and for decoding I used the aac-dec.c in the loas branch.

aac_ld_eld_compare.zip

The abnormality I mentioned in the reconstructed aac_ld wav file is between 5 sec and 6 sec, but is subtle and bit hard to hear. The problem section in the aac_eld wav file is between 7 sec and 8 sec and is clearly audible. The original wav clip is included as well.

The AAC file generated by the LD/ELD encoder is not playable in the PC default media player. I am reading the other issues here as well, and I am supposing I have to first convert these files to an mp4 or m4a file to be able to play it on the PC. Is this correct? Just trying to make sure I am understanding everything correctly.

In the decoder-example branch, there is a file called m4a-dec.c that uses #include <libavformat/avformat.h> and calls avformat_open_input(), but these are not present in the decoder-example branch source code files. Do you have a brach that include these, or are these a part of a different library I need add to the fdk-aac project separately? Assuming I am able to get my fdk-aac project to read m4a files, will I then be able to decode xHE-AAC/USAC encoded files provided as an mp4 file?

mstorsjo commented 5 years ago

The abnormality I mentioned in the reconstructed aac_ld wav file is between 5 sec and 6 sec, but is subtle and bit hard to hear. The problem section in the aac_eld wav file is between 7 sec and 8 sec and is clearly audible. The original wav clip is included as well.

I'm afraid I can't really say for sure that I hear the problem in those encodings - unfortunately. The waveform clearly looks different though.

As general guesses, the LD/ELD profiles are most intended for voice communication I think, so it could be the encoder being to harsh with music like this. Or it could be an encoder bug triggered by this input data.

The AAC file generated by the LD/ELD encoder is not playable in the PC default media player.

Most media players probably can't play back LOAS files no, that's not a common container format as such (it's probably most often used as part in a larger stream transport). And in that case, .aac is probably not the right file extension for it anyway.

I have to first convert these files to an mp4 or m4a file to be able to play it on the PC. Is this correct? Just trying to make sure I am understanding everything correctly.

I would suggest encoding them into an mp4/m4a file directly. If you can build ffmpeg/libav and enable libfdk-aac there, you can use that tool to directly encode with libfdk-aac and package it into an mp4/m4a file. By testing that way, you would rule out potential bugs with the LOAS packaging (which I'm not sure how frequently used it is). Or you could test https://github.com/nu774/fdkaac which is a slightly bigger standalone tool for encoding with this library.

I don't have a version of the standalone encoder tool that supports encoding directly to m4a though.

Even after getting it to m4a, most third party PC applications probably don't support decoding it.

In the decoder-example branch, there is a file called m4a-dec.c that uses #include <libavformat/avformat.h> and calls avformat_open_input(), but these are not present in the decoder-example branch source code files. Do you have a brach that include these, or are these a part of a different library I need add to the fdk-aac project separately?

You need to have the libavformat library available, which is a third party library not included here.

Assuming I am able to get my fdk-aac project to read m4a files, will I then be able to decode xHE-AAC/USAC encoded files provided as an mp4 file?

Sorry I can't comment on xHE-AAC. Allegedly the decoder supports it, but I haven't tested it myself and I don't have samples for it, so I don't know how it normally is handled.

mahaju commented 5 years ago

You need to have the libavformat library available, which is a third party library not included here.

Is it possible to use just the libavformat source code in my program? While looking around I see that it is distributed as part of ffmpeg or libav. I just need to read and parse mp4 files as shown in your m4a-dec.c file. Do I need to have the entire libav or ffmpeg library if I just want to use the mp4 opening functions from libavformat?

I've had a look at avformat.h from the ffmpeg source code and it looks like it includes header files from other parts of ffmpeg such as libavcodec, so it doesn't look like I can simple copy the libavformat folder from ffmpeg source code into my program and expect it to compile, but I am also having trouble integrating the entire ffmpeg source code into my program.

Is there a simpler version of libavformat or some other sample code available, that will let me read and parse mp4 files to use them in the fdk-decoder? I have looked into parsing mp4 files myself, but it looks too complicated and I can't find a simple guide. My final goal is to try decoding xHE-AAC using the fdk-aac decoder.

mstorsjo commented 5 years ago

You need a large part of ffmpeg/libav to use the mp4 reading/writing routines, yes - it's not designed to be possible to split out just that one part.

There are lots of other libraries that also allow reading/writing mp4 files, but I'm not familiar with them so I don't have any particular I can recommend directly.