Skip to content

AudioVolumeConverter and AudioEchoConverter corrupt unsigned 8-bit PCM silence #2933

Description

@Garyouki

Describe the bug

AudioVolumeConverter and AudioEchoConverter perform amplitude arithmetic directly on unsigned 8-bit PCM values. In this format silence is encoded as 128, not 0. Scaling or summing the uncentered values introduces a DC offset, and echo creates a discontinuity at the delay boundary even for a completely silent input.

Both converters accept the WAV and return successfully. This is distinct from the non-finite parameter validation fixes in #2613 and #2566: all parameters and input samples here are valid and finite.

Steps/Code to Reproduce

Run from an environment with PyRIT installed:

import asyncio
import tempfile
from pathlib import Path

import numpy as np
from scipy.io import wavfile

from pyrit.converter import AudioEchoConverter, AudioVolumeConverter
from pyrit.memory import CentralMemory, SQLiteMemory


async def main_async():
    with tempfile.TemporaryDirectory() as directory:
        memory = SQLiteMemory(db_path=':memory:')
        memory.results_path = directory
        CentralMemory.set_memory_instance(memory)
        try:
            source = Path(directory) / 'unsigned.wav'
            samples = np.full(8, 128, dtype=np.uint8)
            wavfile.write(source, 8000, samples)
            for converter in (AudioVolumeConverter(volume_factor=0.5), AudioEchoConverter(delay=0.0005, decay=0.5)):
                result = await converter.convert_async(prompt=str(source))
                rate, output = wavfile.read(result.output_text)
                print(type(converter).__name__ + ':', output.dtype, output.tolist())
        finally:
            memory.dispose_engine()


asyncio.run(main_async())

Expected Results

All eight output samples remain uint8 value 128 (silence), for both volume scaling and echo. Amplitude processing must center unsigned PCM around its midpoint before applying the effect, then restore the midpoint and clip to the original range.

Actual Results

AudioVolumeConverter: uint8 [64, 64, 64, 64, 64, 64, 64, 64]
AudioEchoConverter: uint8 [128, 128, 128, 128, 192, 192, 192, 192]

The input is eight uint8 samples all equal to 128. Volume factor is 0.5; echo delay is four samples and decay is 0.5. Signed PCM should retain its existing behavior.

Versions

Linux, Python 3.12.3, PyRIT 1.2.0.dev0 at 8934a3c4, NumPy 2.5.3, SciPy 1.18.1. Reproduced locally through the public convert_async methods with real WAV files; no model or external service is used.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions