ElvishArtisan / GlassCoder

Minimalist audio encoder for generating live streams.
GNU General Public License v2.0
23 stars 7 forks source link

Support faster AAC bitrates #11

Open deltecent opened 3 years ago

deltecent commented 3 years ago

I added the following to glasscoder and am currently testing at 96K:

    if (bitrate() <= 48) {
        aacEncoder_SetParam(fdk_encoder,AACENC_AOT,29);  // MPEG-4 HE-AAC/PS
    }
    else {
        aacEncoder_SetParam(fdk_encoder,AACENC_AOT,2);   // AAC-LC
    }

This sets the AOT to AAC-LC for bitrates above 48K. Does anyone see any problem with this?

djmasa1 commented 1 year ago

Where did you modify this at? I'm also interested in using AAC at 80K with glasscoder.

ElvishArtisan commented 1 year ago

@deltecent doesn't say, but somewhere in the FdkCodec::startCodec() method in glasscoder(1) would seem plausible.

Be aware that all this modification does is change the Audio Object Type [AOT] from HE-AAC to AAC-LC for bitrates higher than 48 kbits/sec. It won't cause those higher rates to actually appear in the bitrate dropdown in glassgui(1). They'd be available only via the command-line.

The following snippet from the Fraunhofer documentation also seems relevant:

2.11 Supported Bitrates The FDK AAC Encoder provides a wide range of supported bitrates. The minimum and maximum allowed bitrate depends on the Audio Object Type. For AAC-LC the minimum bitrate is the bitrate that is required to write the most basic and minimal valid bitstream. It consists of the bitstream format header information and other static/mandatory information within the AAC payload. The maximum AAC framesize allowed by the MPEG-4 standard determines the maximum allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a library internal look-up table is used.

A good working point in terms of audio quality, sampling rate and bitrate, is at 1 to 1.5 bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate HE-AAC, 1.125 bits/audio sample for downsampled HE-AAC and 0.5 bits/audio sample for HE-AAC v2. For example for one channel with a sampling frequency of 48 kHz, the range from 48 kbit/s to 72 kbit/s achieves reasonable audio quality for AAC-LC.

For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is 16 kHz because then the AAC-LC core encoder operates in dual rate mode at its lowest possible sampling frequency, which is 8 kHz. HE-AAC v2 requires stereo input audio data.

Please note that in HE-AAC or HE-AAC v2 mode the encoder supports much higher bitrates than are appropriate for HE-AAC or HE-AAC v2. For example, at a bitrate of more than 64 kbit/s for a stereo audio signal at 44.1 kHz it usually makes sense to use AAC-LC, which will produce better audio quality at that bitrate than HE-AAC or HE-AAC v2.

deltecent commented 1 year ago

I am in the process of recreating this modification which will include the drop downs, etc. I will push a change when I'm done.

deltecent commented 1 year ago

Here's what we're running now... looks good so far:

diff --git a/src/common/codecdialog.cpp b/src/common/codecdialog.cpp
index 005b5c9..c06b646 100644
--- a/src/common/codecdialog.cpp
+++ b/src/common/codecdialog.cpp
@@ -204,6 +204,10 @@ void CodecDialog::codecSamplerateChanged(int n)
     gui_codec_bitrate_box->insertItem(-1,"32 kbits/sec",32);
     gui_codec_bitrate_box->insertItem(-1,"40 kbits/sec",40);
     gui_codec_bitrate_box->insertItem(-1,"48 kbits/sec",48);
+    gui_codec_bitrate_box->insertItem(-1,"96 kbits/sec",96);
+    gui_codec_bitrate_box->insertItem(-1,"128 kbits/sec",128);
+    gui_codec_bitrate_box->insertItem(-1,"196 kbits/sec",196);
+    gui_codec_bitrate_box->insertItem(-1,"256 kbits/sec",256);
     break;

   case Codec::TypeMpegL2:
diff --git a/src/glasscoder/fdkcodec.cpp b/src/glasscoder/fdkcodec.cpp
index 81671c3..8bed7d8 100644
--- a/src/glasscoder/fdkcodec.cpp
+++ b/src/glasscoder/fdkcodec.cpp
@@ -159,7 +159,12 @@ bool FdkCodec::startCodec()
     break;

   case 2:
-    aacEncoder_SetParam(fdk_encoder,AACENC_AOT,29);  // MPEG-4 HE-AAC/PS
+    if (bitrate() <= 48) {
+      aacEncoder_SetParam(fdk_encoder,AACENC_AOT,29);  // MPEG-4 HE-AAC/PS
+    }
+    else {
+      aacEncoder_SetParam(fdk_encoder,AACENC_AOT,2);   // AAC-LC
+    }
     aacEncoder_SetParam(fdk_encoder,AACENC_CHANNELMODE,MODE_2);
     break;