Upsample Audio

This article explains how to upsample an audio clip from 44.1 Khz to 48 KHz.

Source Audio

For an audio source we use the kahvi011_kennybeltrey-hydrate.mp3 file from the Internet Archive. The original audio format is MPEG Audio Layer 3, 44.1 KHz, Joint Stereo, 136 Kbps, Variable Bit Rate

Sample Code

This code takes an MP3 file with 44.1 KHz audio, and converts it to an MP3 file with 48 KHz audio using polyphase resampling method. The input and output file paths are hardcoded in the source code, no command line parsing is used.

The snippets in this section are from the simple_audio_upsample Python sample.

Initialize AVBlocks

The first step in any AVBlocks application is to initialize the library. This must be done before using any other AVBlocks functionality. The Library.initialize() method sets up the internal state and loads necessary codecs. Always remember to call Library.shutdown() at the end of your program to properly clean up resources and release any allocated memory.

def main():
    # Hardcoded input and output file paths (no command line parsing)
    # Paths are relative to the working directory from which the sample is run
    input_path = "kahvi011_kennybeltrey-hydrate.mp3"
    output_path = "kahvi011_kennybeltrey-hydrate_48Khz.mp3"

    Library.initialize()

    # Set license information. To run AVBlocks in demo mode, comment the next line out
    # Library.set_license("<license-string>")

    result = upsample(input_path, output_path)

    Library.shutdown()

    return 0 if result else 1

Configure Transcoder and Upsample

We probe the input file with a MediaInfo object, and create an input socket from it. The output socket is created by cloning the input socket, so it starts out with an identical configuration, and then we set the output file path on it. The transcoder is the core component that performs the actual upsampling - it takes the 44.1 KHz audio from the input and resamples it to 48 KHz using polyphase resampling for the best upsampling quality.

Probe Input and Create Sockets

First, we probe the input file and create the input socket. Then we clone it to create the output socket and set the output file path.

# Create MediaInfo to probe the input file
with MediaInfo() as media_info:
    media_info.inputs[0].file = input_path

    if not media_info.open():
        print_error("Open MediaInfo", media_info.error)
        return False

    # Create input socket from probed media info
    input_socket = MediaSocket.from_media_info(media_info)

    # Clone the input socket to start with identical output configuration
    output_socket = input_socket.clone()
    output_socket.file = output_path

Change Sampling Rate

Next, we get the output audio pin and change the sampling rate from 44.1 KHz to 48 KHz.

# Get the output audio pin and set sample rate to 48 KHz
if len(output_socket.pins) > 0:
    out_audio_pin = output_socket.pins[0]
    out_audio_stream = out_audio_pin.stream_info
    if isinstance(out_audio_stream, AudioStreamInfo):
        out_audio_stream.sample_rate = 48000

Create Transcoder and Run

Finally, we create the transcoder, configure it with the input and output sockets, and run it.

# Create Transcoder and configure it
with Transcoder() as transcoder:
    transcoder.allow_demo_mode = True
    transcoder.inputs.add(input_socket)
    transcoder.outputs.add(output_socket)

    if not transcoder.open():
        print_error("Transcoder open", transcoder.error)
        return False

    if not transcoder.run():
        print_error("Transcoder run", transcoder.error)
        transcoder.close()
        return False

    transcoder.close()

Complete Code

Here’s the complete working example that demonstrates audio upsampling using AVBlocks for Python.

"""
Upsample an MP3 audio clip from 44.1 KHz to 48 KHz.

This sample demonstrates the basic AVBlocks audio upsampling workflow with
hardcoded input and output file paths (no command line parsing).
"""

import os
import sys

from avblocks import (
    Library, MediaInfo, MediaSocket, Transcoder,
    AudioStreamInfo, ErrorFacility
)


def print_error(action: str, error) -> None:
    """Print error information."""
    if action:
        print(f"{action}: ", end="")

    if error.facility == ErrorFacility.Success:
        print("Success")
        return

    print(f"{error.message or ''}, facility:{error.facility} code:{error.code} hint:{error.hint or ''}")


def upsample(input_path: str, output_path: str) -> bool:
    # Ensure output directory exists
    output_dir = os.path.dirname(output_path)
    if output_dir and not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # Delete output file if it exists (transcoder will fail otherwise)
    if os.path.exists(output_path):
        os.remove(output_path)

    # Create MediaInfo to probe the input file
    with MediaInfo() as media_info:
        media_info.inputs[0].file = input_path

        if not media_info.open():
            print_error("Open MediaInfo", media_info.error)
            return False

        # Create input socket from probed media info
        input_socket = MediaSocket.from_media_info(media_info)

        # Clone the input socket to start with identical output configuration
        output_socket = input_socket.clone()
        output_socket.file = output_path

        # Get the output audio pin and set sample rate to 48 KHz
        if len(output_socket.pins) > 0:
            out_audio_pin = output_socket.pins[0]
            out_audio_stream = out_audio_pin.stream_info
            if isinstance(out_audio_stream, AudioStreamInfo):
                out_audio_stream.sample_rate = 48000

        # Create Transcoder and configure it
        with Transcoder() as transcoder:
            transcoder.allow_demo_mode = True
            transcoder.inputs.add(input_socket)
            transcoder.outputs.add(output_socket)

            if not transcoder.open():
                print_error("Transcoder open", transcoder.error)
                return False

            if not transcoder.run():
                print_error("Transcoder run", transcoder.error)
                transcoder.close()
                return False

            transcoder.close()

    return True


def main():
    # Hardcoded input and output file paths (no command line parsing)
    # Paths are relative to the working directory from which the sample is run
    input_path = "kahvi011_kennybeltrey-hydrate.mp3"
    output_path = "kahvi011_kennybeltrey-hydrate_48Khz.mp3"

    Library.initialize()

    # Set license information. To run AVBlocks in demo mode, comment the next line out
    # Library.set_license("<license-string>")

    result = upsample(input_path, output_path)

    Library.shutdown()

    return 0 if result else 1


if __name__ == '__main__':
    sys.exit(main())

How to Run

See the simple_audio_upsample Python sample for details.

Command Line

This sample uses hardcoded input and output file paths — no command line parsing.

simple-audio-upsample

Examples

Install the package in development mode from the repository root (this installs the sample command):

source .venv/bin/activate
uv pip install --editable .

Download the sample audio, the kahvi011_kennybeltrey-hydrate.mp3 song from the Internet Archive (MPEG Audio Layer 3, 44.1 KHz, Joint Stereo):

cd samples/simple_audio_upsample
curl -L -o kahvi011_kennybeltrey-hydrate.mp3 \
    https://archive.org/download/kahvi011/kahvi011_kennybeltrey-hydrate.mp3

Run the sample (the input/output file paths are relative to the working directory):

simple-audio-upsample

The upsampled output file kahvi011_kennybeltrey-hydrate_48Khz.mp3 will be created in the samples/simple_audio_upsample directory.

Notes

  • The input file kahvi011_kennybeltrey-hydrate.mp3 and output file kahvi011_kennybeltrey-hydrate_48Khz.mp3 paths are hardcoded in simple_audio_upsample.py. They are relative to the working directory from which the sample is run.

  • If transcoder.open() fails, it may be because kahvi011_kennybeltrey-hydrate_48Khz.mp3 already exists in the directory. Delete the output file and try again.

  • The output audio stream is resampled from 44.1 KHz to 48 KHz using AVBlocks’ polyphase resampling method.