The codec library
bAAC
AAC encoding and decoding for Bånder.
bAAC is a C++17 codec library with a C API, a command-line tool and a Node/Electron binding. Explore what it implements and how its recorded measurements compare with other AAC codecs.
Pre-release · Version 0.1.0 · Source-build and API guidance
What it does
A library and an Electron bridge.
Profiles and transports
The package exposes AAC-LC, HE-AAC v1/v2, AAC-LD/ELD and USAC/xHE-AAC. It handles ADTS, LOAS/LATM and configured raw access units, subject to profile restrictions. Raw MP4 sample support does not include an MP4 file demuxer.
Implemented tools and checked interoperability differ. ER RVLC/HCR, LD-SBR and several USAC/spatial tools have approximations, unverified external streams or refused modes. Read the capabilities and limitations before choosing a profile.
Current Bånder integration
Electron's main-process AacService exposes the native binding through registered IPC handlers and a preload bridge. The packaging configuration includes native files. This integration does not establish bAAC as the default playback path in the web application.
Start with the source-build guide, C API and Node-API binding. Public package availability and release binaries are not established by these measurements.
Planned: transcoder and FFmpeg integration
We plan to integrate bAAC into Bånder's server-side transcoder and FFmpeg build, extending its use beyond the Electron application. That work is planned; the current integration described above is the Electron service and bridge.
Recorded quality
Compare the rate and the model score.
These plots compare default constant-bitrate settings on ten TCDAudio14 music excerpts: 48 kHz, 16-bit stereo. Each point is a mean over the ten excerpts. The horizontal axis uses mean measured file rate, including transport framing; the tables also show the nominal setting.
Quality recorded 30 October 2026; bAAC remeasured 31 October. Reference scores remain from 30 October. Measurement revisions and protocol.
AAC-LCQuality · two models
Five encoders, five nominal settings: 64, 96, 128, 192 and 256 kbit/s.
AAC-LC: PEAQ Basic against measured bitrate
Inspect 25 data points
| Encoder | Nominal kbit/s | Actual kbit/s | PEAQ basic ODG |
|---|---|---|---|
| bAAC | 64 | 63.908 | -3.073 |
| bAAC | 96 | 95.967 | -1.470 |
| bAAC | 128 | 127.943 | -0.682 |
| bAAC | 192 | 191.983 | -0.073 |
| bAAC | 256 | 255.769 | -0.023 |
| FFmpeg | 64 | 67.017 | -3.005 |
| FFmpeg | 96 | 99.260 | -1.971 |
| FFmpeg | 128 | 131.768 | -1.137 |
| FFmpeg | 192 | 198.900 | -0.393 |
| FFmpeg | 256 | 262.079 | -0.270 |
| FDK | 64 | 64.836 | -2.993 |
| FDK | 96 | 96.760 | -1.706 |
| FDK | 128 | 128.732 | -0.787 |
| FDK | 192 | 192.902 | -0.099 |
| FDK | 256 | 257.135 | 0.054 |
| libxaac | 64 | 67.070 | -2.936 |
| libxaac | 96 | 98.936 | -1.647 |
| libxaac | 128 | 130.923 | -0.740 |
| libxaac | 192 | 192.257 | -0.213 |
| libxaac | 256 | 256.261 | -0.175 |
| Apple | 64 | 67.176 | -2.925 |
| Apple | 96 | 99.271 | -1.877 |
| Apple | 128 | 131.272 | -0.674 |
| Apple | 192 | 195.565 | -0.072 |
| Apple | 256 | 259.818 | 0.019 |
AAC-LC: ViSQOL against measured bitrate
Inspect 25 data points
| Encoder | Nominal kbit/s | Actual kbit/s | ViSQOL v3 MOS-LQO |
|---|---|---|---|
| bAAC | 64 | 63.908 | 3.867 |
| bAAC | 96 | 95.967 | 4.354 |
| bAAC | 128 | 127.943 | 4.521 |
| bAAC | 192 | 191.983 | 4.510 |
| bAAC | 256 | 255.769 | 4.718 |
| FFmpeg | 64 | 67.017 | 3.496 |
| FFmpeg | 96 | 99.260 | 4.076 |
| FFmpeg | 128 | 131.768 | 4.200 |
| FFmpeg | 192 | 198.900 | 4.480 |
| FFmpeg | 256 | 262.079 | 4.675 |
| FDK | 64 | 64.836 | 3.771 |
| FDK | 96 | 96.760 | 4.091 |
| FDK | 128 | 128.732 | 4.283 |
| FDK | 192 | 192.902 | 4.466 |
| FDK | 256 | 257.135 | 4.486 |
| libxaac | 64 | 67.070 | 3.813 |
| libxaac | 96 | 98.936 | 4.116 |
| libxaac | 128 | 130.923 | 4.293 |
| libxaac | 192 | 192.257 | 4.622 |
| libxaac | 256 | 256.261 | 4.645 |
| Apple | 64 | 67.176 | 3.496 |
| Apple | 96 | 99.271 | 4.254 |
| Apple | 128 | 131.272 | 4.429 |
| Apple | 192 | 195.565 | 4.669 |
| Apple | 256 | 259.818 | 4.717 |
HE-AAC v1Quality · two models
Four encoders at nominal 32, 48 and 64 kbit/s. FFmpeg native AAC has no observation in this profile.
HE-AAC v1: PEAQ Basic against measured bitrate
Inspect 12 data points
| Encoder | Nominal kbit/s | Actual kbit/s | PEAQ basic ODG |
|---|---|---|---|
| bAAC | 32 | 32.027 | -3.554 |
| bAAC | 48 | 48.089 | -2.771 |
| bAAC | 64 | 64.165 | -2.431 |
| FDK | 32 | 32.813 | -3.527 |
| FDK | 48 | 48.661 | -3.063 |
| FDK | 64 | 64.724 | -2.428 |
| libxaac | 32 | 33.803 | -3.487 |
| libxaac | 48 | 49.600 | -3.105 |
| libxaac | 64 | 65.561 | -2.451 |
| Apple | 32 | 33.850 | -3.560 |
| Apple | 48 | 49.948 | -2.678 |
| Apple | 64 | 66.047 | -2.474 |
HE-AAC v1: ViSQOL against measured bitrate
Inspect 12 data points
| Encoder | Nominal kbit/s | Actual kbit/s | ViSQOL v3 MOS-LQO |
|---|---|---|---|
| bAAC | 32 | 32.027 | 3.645 |
| bAAC | 48 | 48.089 | 4.091 |
| bAAC | 64 | 64.165 | 4.292 |
| FDK | 32 | 32.813 | 3.680 |
| FDK | 48 | 48.661 | 3.925 |
| FDK | 64 | 64.724 | 4.294 |
| libxaac | 32 | 33.803 | 3.639 |
| libxaac | 48 | 49.600 | 3.924 |
| libxaac | 64 | 65.561 | 4.308 |
| Apple | 32 | 33.850 | 3.649 |
| Apple | 48 | 49.948 | 4.059 |
| Apple | 64 | 66.047 | 4.315 |
HE-AAC v2Quality · two models
Three encoders at nominal 24 and 32 kbit/s. Apple and FFmpeg have no observations in this profile.
HE-AAC v2: PEAQ Basic against measured bitrate
Inspect 6 data points
| Encoder | Nominal kbit/s | Actual kbit/s | PEAQ basic ODG |
|---|---|---|---|
| bAAC | 24 | 23.981 | -3.634 |
| bAAC | 32 | 32.070 | -3.503 |
| FDK | 24 | 24.471 | -3.636 |
| FDK | 32 | 32.514 | -3.506 |
| libxaac | 24 | 25.496 | -3.562 |
| libxaac | 32 | 33.503 | -3.447 |
HE-AAC v2: ViSQOL against measured bitrate
Inspect 6 data points
| Encoder | Nominal kbit/s | Actual kbit/s | ViSQOL v3 MOS-LQO |
|---|---|---|---|
| bAAC | 24 | 23.981 | 3.715 |
| bAAC | 32 | 32.070 | 3.881 |
| FDK | 24 | 24.471 | 3.734 |
| FDK | 32 | 32.514 | 3.897 |
| libxaac | 24 | 25.496 | 3.714 |
| libxaac | 32 | 33.503 | 3.865 |
xHE-AACQuality · two models
bAAC and FDK at nominal 24, 32, 48, 64 and 96 kbit/s; libxaac at 64 and 96 only. Other combinations are unavailable.
Low-rate limitation: bAAC trails FDK on the recorded low-rate ViSQOL scores. The current source documents further tool and interoperability limits; these recorded results do not measure subsequent code changes.
xHE-AAC: PEAQ Basic against measured bitrate
Inspect 12 data points
| Encoder | Nominal kbit/s | Actual kbit/s | PEAQ basic ODG |
|---|---|---|---|
| bAAC | 24 | 25.678 | -3.682 |
| bAAC | 32 | 34.393 | -3.538 |
| bAAC | 48 | 51.796 | -2.424 |
| bAAC | 64 | 69.330 | -2.129 |
| bAAC | 96 | 104.016 | -1.302 |
| FDK | 24 | 27.667 | -3.404 |
| FDK | 32 | 36.332 | -3.271 |
| FDK | 48 | 54.096 | -3.000 |
| FDK | 64 | 71.628 | -1.788 |
| FDK | 96 | 96.367 | -1.531 |
| libxaac | 64 | 64.304 | -2.770 |
| libxaac | 96 | 96.387 | -1.432 |
xHE-AAC: ViSQOL against measured bitrate
Inspect 12 data points
| Encoder | Nominal kbit/s | Actual kbit/s | ViSQOL v3 MOS-LQO |
|---|---|---|---|
| bAAC | 24 | 25.678 | 3.393 |
| bAAC | 32 | 34.393 | 3.684 |
| bAAC | 48 | 51.796 | 4.118 |
| bAAC | 64 | 69.330 | 4.272 |
| bAAC | 96 | 104.016 | 4.330 |
| FDK | 24 | 27.667 | 4.022 |
| FDK | 32 | 36.332 | 4.062 |
| FDK | 48 | 54.096 | 3.998 |
| FDK | 64 | 71.628 | 4.334 |
| FDK | 96 | 96.367 | 4.171 |
| libxaac | 64 | 64.304 | 4.307 |
| libxaac | 96 | 96.387 | 4.378 |
55 configurations selected from the quality summary CSV, checked against per-excerpt rows. VBR and experimental settings are outside these plots. Worst-item scores are not uncertainty bounds; no absolute-score confidence intervals are plotted.
Recorded throughput
Audio seconds per CPU second.
Higher is faster. Each bar divides input audio duration by CPU time (user plus system). Compare codecs within a profile and operation: encoding and decoding are separate workloads. Every bar starts at zero.
AAC-LCEncode and decode
TCDAudio14 music, 48 kHz, 16-bit stereo; 130.3173125 seconds of audio. Missing codec/profile combinations are unavailable, not zero. Decode input is a common FDK stream, or libxaac where FDK is unavailable.
AAC-LC: Encode throughput
Inspect 5 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 3.610 | 36.099 |
| FFmpeg | 130.3173125 | 3.700 | 35.221 |
| FDK | 130.3173125 | 1.570 | 83.005 |
| libxaac | 130.3173125 | 0.900 | 144.797 |
| Apple | 130.3173125 | 1.660 | 78.504 |
AAC-LC: Decode throughput
Inspect 5 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 0.210 | 620.559 |
| FFmpeg | 130.3173125 | 0.570 | 228.627 |
| FDK | 130.3173125 | 0.400 | 325.793 |
| libxaac | 130.3173125 | 0.390 | 334.147 |
| Apple | 130.3173125 | 0.310 | 420.378 |
HE-AAC v1Encode and decode
TCDAudio14 music, 48 kHz, 16-bit stereo; 130.3173125 seconds of audio. Missing codec/profile combinations are unavailable, not zero. Decode input is a common FDK stream, or libxaac where FDK is unavailable.
HE-AAC v1: Encode throughput
Inspect 4 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 2.560 | 50.905 |
| FDK | 130.3173125 | 1.680 | 77.570 |
| libxaac | 130.3173125 | 0.880 | 148.088 |
| Apple | 130.3173125 | 1.500 | 86.878 |
HE-AAC v1: Decode throughput
Inspect 5 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 0.420 | 310.279 |
| FFmpeg | 130.3173125 | 0.420 | 310.279 |
| FDK | 130.3173125 | 0.560 | 232.709 |
| libxaac | 130.3173125 | 1.080 | 120.664 |
| Apple | 130.3173125 | 0.400 | 325.793 |
HE-AAC v2Encode and decode
TCDAudio14 music, 48 kHz, 16-bit stereo; 130.3173125 seconds of audio. Missing codec/profile combinations are unavailable, not zero. Decode input is a common FDK stream, or libxaac where FDK is unavailable.
HE-AAC v2: Encode throughput
Inspect 3 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 1.430 | 91.131 |
| FDK | 130.3173125 | 1.060 | 122.941 |
| libxaac | 130.3173125 | 0.570 | 228.627 |
HE-AAC v2: Decode throughput
Inspect 5 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 0.360 | 361.993 |
| FFmpeg | 130.3173125 | 0.480 | 271.494 |
| FDK | 130.3173125 | 0.690 | 188.866 |
| libxaac | 130.3173125 | 0.870 | 149.790 |
| Apple | 130.3173125 | 0.380 | 342.940 |
xHE-AACEncode and decode
TCDAudio14 music, 48 kHz, 16-bit stereo; 130.3173125 seconds of audio. Missing codec/profile combinations are unavailable, not zero. Decode input is a common FDK stream, or libxaac where FDK is unavailable.
xHE-AAC: Encode throughput
Inspect 3 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 5.330 | 24.450 |
| FDK | 130.3173125 | 4.550 | 28.641 |
| libxaac | 130.3173125 | 2.210 | 58.967 |
xHE-AAC: Decode throughput
Inspect 3 observations
| Codec | Audio seconds | CPU seconds | Audio seconds / CPU second |
|---|---|---|---|
| bAAC | 130.3173125 | 0.770 | 169.243 |
| FDK | 130.3173125 | 1.010 | 129.027 |
| libxaac | 130.3173125 | 1.030 | 126.522 |
33 observations from speed.json. Four encoder experiments and the zero-audio-duration Wine baseline are excluded; no baseline time is subtracted.
Separate reference context
What lossless needs on this corpus.
ALAC and FLAC preserve the decoded samples exactly in these recorded checks. Their measured rates provide storage context for the same music corpus. They have no AAC quality score here, and this table does not imply a bAAC lossless mode.
| Reference | Measured kbit/s | Bit-exact check |
|---|---|---|
| FFmpeg ALAC | 697.016 | Passed |
| FLAC level 5 | 629.677 | Passed |
| FLAC level 8 | 615.062 | Passed |
| refalac ALAC | 690.250 | Passed |
Four reference configurations from lossless.json: FFmpeg ALAC, refalac 2.85 and FLAC 1.4.3 at levels 5 and 8.
Method and provenance
Read the conditions behind the curves.
The site renders recorded repository data. Source links identify the latest commit affecting the bAAC package in this checkout; the measurement revisions below identify the code that produced the results.
Measurement dates, revisions and timing
Quality was first measured on 30 October 2026 at 166dec8e5e32598cb0b9911755bfd4a417b9822b. bAAC was remeasured on 31 October at 129ce927775beee5548aa9418829fa0fe2639b1f; other encoders retain the first run's streams and scores. The tracked result revision is 9d05f8b1dcd6b04f61f046a9a42a453ef593a813.
The speed table is the second run of 31 October. bAAC used a Release build with GCC 13.3. The harness defaults to three timing repeats, selecting minimum CPU and wall time separately and maximum RSS. The actual repeat count is not stored in the raw results. Throughput here uses only the recorded CPU time. The raw files do not carry complete provenance metadata; these conditions come from the comparison document.
Reference versions
- FFmpeg 6.1.1: native AAC two-loop encoder and decoder.
- FDK: AOSP C++ tree
c41c3c7516ea8d0d78a53b96b30bed3a29745cc6, rather than FFmpeg's linkedlibfdk-aac2.0.3. - Ittiam libxaac v0.1.14, revision
2fbadd57bca46693b7a077bcf1513131106d960c. - Apple CoreAudioToolbox 7.10.9.0 from iTunes for Windows 12.13.9.1, through qaac 2.85 and Wine 9.0, quality setting 2.
These are measured references, not endorsements or runtime dependencies of bAAC.
Corpus, meters and alignment
The corpus contains ten TCDAudio14 music excerpts, each about seven to sixteen seconds, totalling 130.3173125 seconds. Setup pins the ViSQOL corpus repository to 38d0b0163e441047d4429bf07ad09e5b9031d02c and verifies file SHA-256 sums. That corpus pin does not identify the ViSQOL executable.
GstPEAQ is pinned to 7397e49f5ede2f2429fb78f6663784e548401fec. ViSQOL v3 uses audio mode and the default libsvm model; its exact executable revision was not recorded. PEAQ compresses severe impairments below about −3, and GstPEAQ reports conformance limitations. Scores are shown as observed, without clamping to a nominal scale.
The pipeline uses FFmpeg to decode LC/HE streams and libxaac for xHE, with normalization and limiter off. It aligns decoded audio by cross-correlation, then matches levels below 3 kHz. Low-rate corrections reach about 3.2 dB on individual excerpts. Actual rates are arithmetic means of file rates, not duration-weighted corpus rates.
The linked report's intervals are Student-t 95% half-widths of paired reference-minus-bAAC differences over ten items, using multiplier 2.262. They are not bootstrap intervals or confidence intervals for individual mean scores. Its equal-bitrate tables interpolate item curves; this page does not recompute or extrapolate them.
Interoperability and code provenance
The recorded compatibility dataset has 790 attempts: 780 succeed and ten fail. The failures are bAAC decoding libxaac raw xHE64 inputs that require an unsupported config/size-list input path. All 440 attempts involving bAAC-encoded streams succeed in this dataset. This coverage does not establish universal decoder compatibility.
Baander-authored code is Apache-2.0. The package's provenance disclosure identifies standards tables, consulted implementations and attributed data. Read it together with the capability limitations.