DrKLO/Telegram · error · IllegalArgumentException

Invalid sample rate or number of channels: {sampleRate}, {ch

Error message

Invalid sample rate or number of channels: {sampleRate}, {channelCount}

What it means

AacUtil throws IllegalArgumentException ('Invalid sample rate or number of channels') when, after parsing an AAC AudioSpecificConfig (or building one), the provided sampleRate or channelCount does not appear in the known MPEG-4 AAC tables (AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE for rates: 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350; and AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE for channel counts 0..7). AAC-LC only supports these enumerated rates/counts; anything else cannot be encoded as a standard sampling_frequency_index/channel_configuration and the config cannot be built.

Source

Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/audio/AacUtil.java:285

   * @param sampleRate The sample rate in Hz.
   * @param channelCount The channel count.
   * @return The AudioSpecificConfig.
   */
  public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int channelCount) {
    int sampleRateIndex = C.INDEX_UNSET;
    for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; ++i) {
      if (sampleRate == AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[i]) {
        sampleRateIndex = i;
      }
    }
    int channelConfig = C.INDEX_UNSET;
    for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) {
      if (channelCount == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) {
        channelConfig = i;
      }
    }
    if (sampleRate == C.INDEX_UNSET || channelConfig == C.INDEX_UNSET) {
      throw new IllegalArgumentException(
          "Invalid sample rate or number of channels: " + sampleRate + ", " + channelCount);
    }
    return buildAudioSpecificConfig(AUDIO_OBJECT_TYPE_AAC_LC, sampleRateIndex, channelConfig);
  }

  /**
   * Builds a simple AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
   *
   * @param audioObjectType The audio object type.
   * @param sampleRateIndex The sample rate index.
   * @param channelConfig The channel configuration.
   * @return The AudioSpecificConfig.
   */
  public static byte[] buildAudioSpecificConfig(
      int audioObjectType, int sampleRateIndex, int channelConfig) {
    byte[] specificConfig = new byte[2];
    specificConfig[0] = (byte) (((audioObjectType << 3) & 0xF8) | ((sampleRateIndex >> 1) & 0x07));
    specificConfig[1] = (byte) (((sampleRateIndex << 7) & 0x80) | ((channelConfig << 3) & 0x78));

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Restrict sample rate to one of the 13 AAC standard rates (96000..7350) and channel count to 1..7 (or 8 for the 7.1 entry if supported).
  2. Resample the input PCM to a supported rate before encoding (use SonicAudioProcessor or a resampler to land on 44100/48000).
  3. Down-mix or up-mix channels so the count is within the table (1, 2, ..., 7).
  4. If the input is genuinely unsupported, reject the format upstream and surface a clear 'unsupported AAC input' to the user instead of throwing.

Example fix

// before
byte[] cfg = AacUtil.buildAudioSpecificConfig(sampleRate, channelCount); // throws if non-standard
// after
int[] validRates = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350};
int rate = pickNearest(validRates, sampleRate); // resample input to `rate`
int ch  = Math.max(1, Math.min(channelCount, 7));
byte[] cfg = AacUtil.buildAudioSpecificConfig(rate, ch);
Defensive patterns

Strategy: validation

Validate before calling

static final int[] AAC_RATES = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350};
static boolean isAacSupported(int rate, int channels) {
  boolean rateOk = false;
  for (int r : AAC_RATES) if (r == rate) { rateOk = true; break; }
  return rateOk && channels >= 1 && channels <= 7;
}

Try / catch

try {
  cfg = AacUtil.buildAudioSpecificConfig(rate, ch);
} catch (IllegalArgumentException e) {
  // resample to nearest supported rate and retry
  rate = nearestSupported(AAC_RATES, rate);
  cfg = AacUtil.buildAudioSpecificConfig(rate, Math.min(ch, 7));
}

Prevention

When it happens

Trigger: Passing a non-standard sample rate (e.g. 44100 is fine, but 47250 is not) or channel count (e.g. 9 channels) into AacUtil.buildAudioSpecificConfig or a code path that derives the config from raw rate/count; mis-parsed media where the declared rate/channel fields are corrupted; user-selected encoding parameters outside the AAC table.

Common situations: Custom audio pipeline building an AAC config from arbitrary user input; transcoding audio whose source container declares an exotic rate; media with a malformed codec private data that decodes to an out-of-table value; testing with synthetic PCM at non-standard rates.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/3999abaf5f8968e8. Report an issue: GitHub.