Skip to content

A high-performance audio element for ESP-ADF that provides real-time volume level monitoring with customizable callbacks. Perfect for creating volume indicators, audio level visualizations or silence detection in your ESP32 audio projects

License

Notifications You must be signed in to change notification settings

MacWyznawca/vmeter-lib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ESP-ADF Volume Meter Element

ESP-ADF Version

A high-performance audio element for ESP-ADF that provides real-time volume level monitoring with customizable callbacks. Perfect for creating volume indicators, VU meters, or audio level visualizations in your ESP32 audio projects.

Features

  • Real-time volume monitoring - Calculates RMS values for both stereo channels
  • Configurable update rates - 1-100 Hz (recommended 10-30 Hz) callback frequency
  • Logarithmic scaling - Provides perceptually accurate 0-100% volume levels
  • Low CPU overhead - Optimized fast square root and efficient RMS calculations
  • Stereo & Mono support - Works with both mono and stereo audio streams
  • Easy integration - Simple callback-based API for UI updates
  • Multiple sample rates - Supports 8kHz to 192kHz sample rates
  • Memory efficient - Minimal memory footprint with no dynamic allocations during processing

Compatibility

  • ESP-ADF: v2.7 or newer
  • ESP-IDF: Compatible with ESP-ADF supported versions
  • Audio formats: 16-bit PCM (8, 24, 32-bit support in header but currently only 16-bit implemented)
  • Sample rates: 8kHz - 192kHz
  • Channels: Mono and Stereo

Installation

  1. Copy volume_meter.c and volume_meter.h to your ESP-ADF project
  2. Add the source file to your CMakeLists.txt or component configuration
  3. Include the header in your main application file

Quick Start

Basic Usage

#include "volume_meter.h"

// Callback function to handle volume updates
void my_volume_callback(int left_volume, int right_volume) {
    printf("Volume: L=%d%% R=%d%%\n", left_volume, right_volume);
    // Update your volume bars, LEDs, or display here
}

// Create volume meter with default settings
audio_element_handle_t volume_meter = create_volume_meter(44100, 15, my_volume_callback);

// Add to your audio pipeline
audio_pipeline_register(pipeline, volume_meter, "volume_meter");

Advanced Configuration

// Custom configuration
volume_meter_cfg_t config = {
    .sample_rate = 44100,
    .channels = 2,
    .bits_per_sample = 16,
    .frame_size = 1024,
    .update_rate_hz = 20,
    .volume_callback = my_volume_callback
};

audio_element_handle_t volume_meter = volume_meter_init(&config);

Using with Default Configuration Macro

volume_meter_cfg_t config = V_METER_CFG_DEFAULT();
config.update_rate_hz = 25;
config.volume_callback = my_volume_callback;

audio_element_handle_t volume_meter = volume_meter_init(&config);

API Reference

Configuration Structure

typedef struct {
    int sample_rate;           // Sample rate (e.g. 44100)
    int channels;              // Number of channels (1=mono, 2=stereo)
    int bits_per_sample;       // Bits per sample (currently only 16-bit supported)
    int frame_size;            // Buffer size in bytes
    int update_rate_hz;        // Update frequency (1-100 Hz)
    void (*volume_callback)(int left_volume, int right_volume); // Callback function
} volume_meter_cfg_t;

Functions

volume_meter_init(volume_meter_cfg_t *config)

Initializes the volume meter element with custom configuration.

Parameters:

  • config: Pointer to configuration structure

Returns: audio_element_handle_t or NULL on error

create_volume_meter(int sample_rate, int update_rate, void (*callback)(int, int))

Creates a volume meter with default settings and specified parameters.

Parameters:

  • sample_rate: Audio sample rate (8000-192000 Hz)
  • update_rate: Callback frequency (1-100 Hz)
  • callback: Volume update callback function

Returns: audio_element_handle_t or NULL on error

volume_meter_update_format(audio_element_handle_t self, int sample_rate, int channels, int bits_per_sample)

Updates audio format parameters during runtime.

Parameters:

  • self: Volume meter element handle
  • sample_rate: New sample rate
  • channels: New channel count (1-2)
  • bits_per_sample: New bit depth (8, 16, 24, 32)

Returns: ESP_OK on success, error code on failure

volume_meter_set_update_rate(audio_element_handle_t self, int update_rate_hz)

Changes the callback update frequency.

Parameters:

  • self: Volume meter element handle
  • update_rate_hz: New update rate (1-100 Hz)

Returns: ESP_OK on success, error code on failure

Implementation Example

Here's a complete example showing integration with LVGL for a visual volume meter:

#include "volume_meter.h"
#include "lvgl.h"

lv_obj_t *volume_bar_left;
lv_obj_t *volume_bar_right;

void ui_volume_callback(int left_volume, int right_volume) {
    // Update LVGL volume bars
    lv_bar_set_value(volume_bar_left, left_volume, LV_ANIM_OFF);
    lv_bar_set_value(volume_bar_right, right_volume, LV_ANIM_OFF);
}

void setup_audio_pipeline() {
    // Create pipeline
    audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
    audio_pipeline_handle_t pipeline = audio_pipeline_init(&pipeline_cfg);
    
    // Create volume meter
    audio_element_handle_t volume_meter = create_volume_meter(44100, 20, ui_volume_callback);
    
    // Create other audio elements (decoder, etc.)
    // ...
    
    // Register elements
    audio_pipeline_register(pipeline, volume_meter, "volume_meter");
    
    // Link pipeline: [decoder] -> [volume_meter] -> [output]
    const char *link_tag[3] = {"decoder", "volume_meter", "output"};
    audio_pipeline_link(pipeline, &link_tag[0], 3);
    
    // Start pipeline
    audio_pipeline_run(pipeline);
}

Technical Details

Volume Calculation

  • Uses RMS (Root Mean Square) calculation for accurate volume measurement
  • Logarithmic scaling approximation using lookup tables for perceptually correct levels
  • Fast square root implementation optimized for ESP32
  • Configurable silence threshold and maximum volume limits

Performance Characteristics

  • CPU Usage: ~1-2% at 44.1kHz, 15Hz update rate
  • Memory: ~3-5KB RAM usage (including task stack)
  • Latency: Minimal processing delay (pass-through design)
  • Accuracy: ±1% volume level accuracy

Scaling Algorithm

The element uses a logarithmic approximation with 16 threshold points to convert RMS values to perceptually accurate 0-100% levels. Linear interpolation between thresholds ensures smooth level transitions.

Use Cases

  • Audio Visualizers: Create spectrum analyzers and VU meters
  • Recording Applications: Monitor input levels during recording
  • Voice Applications: Voice activity detection and level monitoring
  • Music Players: Real-time volume display and peak detection
  • Audio Processing: Dynamic range compression and automatic gain control

Contributing

Contributions are welcome! Please feel free to submit pull requests, bug reports, or feature requests.

License

This project is licensed under the MIT License - see the LICENSE file for details. License: MIT

Author

Jaromir Kopp - 2025


This element is designed for ESP-ADF v2.7+ and has been tested with various audio formats and sample rates. For questions or support, please open an issue on GitHub.

About

A high-performance audio element for ESP-ADF that provides real-time volume level monitoring with customizable callbacks. Perfect for creating volume indicators, audio level visualizations or silence detection in your ESP32 audio projects

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages