Skip to content

EncodedAudioStream ignores configured sample rates, always uses 44100 Hz #2165

@uros117

Description

@uros117

EncodedAudioStream ignores configured sample rates, always uses 44100 Hz

Description

When using EncodedAudioStream with encoders like Opus that require specific sample
rates, the configured sample rate is ignored and it always defaults to 44100 Hz,
causing encoder failures with message:

[E] CodecOpus.h : 277 - opus_encoder_create: invalid argument for sample_rate: 44100, channels:2

Steps to Reproduce

  1. Create an OpusOggEncoder and EncodedAudioStream
  2. Configure audio info with non-44100 Hz sample rate (e.g., 24000 Hz):
    AudioInfo info(24000, 2, 16);
    encoded_stream.setAudioInfo(info);
    encoded_stream.begin(info);
  3. Opus encoder fails with: opus_encoder_create: invalid argument for sample_rate:
    44100...

Expected Behavior

The encoder should receive the configured 24000 Hz sample rate.

Actual Behavior

The encoder always receives 44100 Hz regardless of configuration.

Root Cause Analysis

I found two potential issues:

  1. EncodedAudioStream::begin() line 362 calls audioInfo() instead of using configured
    values:
return enc_out.begin(audioInfo());  // Uses defaults, not configured values because audioInfo returns enc_out.audioInfo which is
                                    // never changed
  1. Missing setAudioInfo override in EncodedAudioStream - it doesn't propagate audio
    info to enc_out:
    // EncodedAudioStream should override setAudioInfo() to call:
    // enc_out.setAudioInfo(info);

Proposed Solutions

Option A: Fix the begin() method to use configured audio info

bool begin() override {
  // is_output_notify = false;
  setupReader();
  ReformatBaseStream::begin();
  return enc_out.begin(ReformatBaseStream::audioInfo());
}

Option B: Add proper setAudioInfo() override to propagate to enc_out

Impact

This affects anyone using:

  • Opus encoding (needs 8k, 12k, 16k, 24k, 48k Hz)
  • Any non-44100 Hz encoded audio streams

Environment

  • Arduino Audio Tools version: tag v1.1.3
  • Platform: ESP32
  • Codec: OpusOgg (but likely affects others)

What would be the preferred approach to fix this?

Device Description

ESP32-WROVER-E on the Lilygo T-SIM7600X board

Sketch

/**
 * @file      Test.cpp
 * @brief     Minimal reproduction of EncodedAudioStream sample rate bug
 * @author    Uros Filipovic
 * @date      2025-09-15
 *
 * Demonstrates that EncodedAudioStream ignores configured sample rates
 * and always uses 44100 Hz, causing Opus encoder to fail.
 */
#include "utilities.h"
#include "Arduino.h"
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecOpusOgg.h"

// Test configuration - using 24kHz which Opus supports
AudioInfo test_config(24000, 2, 16);

// Simple sine wave for test data
SineWaveGenerator<int16_t> sine_wave(16000);
GeneratedSoundStream<int16_t> sound_source(sine_wave);

// Output to Serial for testing
CsvOutput<int16_t> csv_out(Serial);

// Opus encoder and stream
OpusOggEncoder opus_encoder;
EncodedAudioStream encoded_stream(&csv_out, &opus_encoder);

StreamCopy copier(encoded_stream, sound_source);

void setup() {
  Serial.begin(115200);
  delay(1000);

  AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);

  Serial.println("=== EncodedAudioStream Sample Rate Bug Test ===");
  Serial.printf("Configured sample rate: %d Hz\n", test_config.sample_rate);

  // Configure output
  csv_out.begin(test_config);

  // Configure sine wave generator
  sine_wave.begin(test_config, N_C4);

  // Configure Opus encoder
  opus_encoder.config().application = OPUS_APPLICATION_AUDIO;

  // Test 1: setAudioInfo before begin
  Serial.println("\nTest 1: setAudioInfo() then begin()");
  encoded_stream.setAudioInfo(test_config);

  // Test 2: begin with AudioInfo parameter
  Serial.println("Test 2: begin(AudioInfo)");
  bool success = encoded_stream.begin(test_config);

  // Check results
  AudioInfo actual_info = encoded_stream.audioInfo();
  Serial.printf("Expected: %d Hz\n", test_config.sample_rate);
  Serial.printf("Actual: %d Hz\n", actual_info.sample_rate);

  if (success) {
    Serial.println("Opus encoder started successfully");
  } else {
    Serial.println("Opus encoder failed to start");
  }

  if (actual_info.sample_rate != test_config.sample_rate) {
    Serial.println("BUG: Sample rate mismatch detected");
  } else {
    Serial.println("Sample rate preserved correctly");
  }
}

void loop() {
  // Try to copy some data if encoder is working
  AudioInfo current_info = encoded_stream.audioInfo();
  if (current_info.sample_rate == test_config.sample_rate) {
    copier.copy();
  } else {
    delay(1000);
    Serial.println("Encoder not working due to sample rate bug");
  }
}

Other Steps to Reproduce

I cloned the repository with v1.1.3 tag because in the lib folder of the platformio project. The main branch won't compile with error "driver/i2s_pdm.h: No such file or directory".

The output of the test script is:

=== EncodedAudioStream Sample Rate Bug Test ===
Configured sample rate: 24000 Hz
[I] SoundGenerator.h : 167 - SineWaveGenerator::begin(channels=2, sample_rate=24000, frequency=261.63)
[I] SoundGenerator.h : 150 - bool audio_tools::SineWaveGenerator<T>::begin() [with T = short int]
[I] AudioTypes.h : 125 - SoundGenerator: sample_rate: 24000 / channels: 2 / bits_per_sample: 16
[I] Buffers.h : 415 - resize: 4
[I] SoundGenerator.h : 194 - setFrequency: 261.63
[I] SoundGenerator.h : 195 - active: true

Test 1: setAudioInfo() then begin()
[I] AudioTypes.h : 125 - in: sample_rate: 24000 / channels: 2 / bits_per_sample: 16
[I] AudioTypes.h : 125 - out: sample_rate: 44100 / channels: 2 / bits_per_sample: 16
Test 2: begin(AudioInfo)
[I] AudioTypes.h : 125 - out: sample_rate: 44100 / channels: 2 / bits_per_sample: 16
[I] CodecOpusOgg.h : 95 - writeHeader
[E] CodecOpus.h : 277 - opus_encoder_create: invalid argument for sample_rate: 44100, channels:2
Expected: 24000 Hz
Actual: 44100 Hz
Opus encoder failed to start
BUG: Sample rate mismatch detected
Encoder not working due to sample rate bug
Encoder not working due to sample rate bug
Encoder not working due to sample rate bug
Encoder not working due to sample rate bug
Encoder not working due to sample rate bug
...

What is your development environment (incl. core version info)

Platformio with these env versions:

[env]
platform = espressif32@6.11.0
framework = arduino

I have checked existing issues, discussions and online documentation (incl. the Wiki)

  • I confirm I have checked existing issues, discussions and online documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions