Skip to content

audio

__all__ = ['audio_async_render', 'WaveHeader'] module-attribute

Most if not everything in this file is stolen from this because I don't feel like waiting for setsu to add it to vapoursynth itself.

https://github.com/Ichunjo/vardautomation/blob/fae054956b3611e641276dc92f4a8c4060a3d8e2/vardautomation/render.py

WaveFormat

Bases: IntEnum

WAVE form wFormatTag IDs Complete list is in mmreg.h in Windows 10 SDK.

Source code in vsmuxtools/utils/audio.py
class WaveFormat(IntEnum):
    """
    WAVE form wFormatTag IDs
    Complete list is in mmreg.h in Windows 10 SDK.
    """

    PCM = 0x0001
    IEEE_FLOAT = 0x0003
    EXTENSIBLE = 0xFFFE

WaveHeader

Bases: IntEnum

Wave headers

Source code in vsmuxtools/utils/audio.py
class WaveHeader(IntEnum):
    """
    Wave headers
    """

    WAVE = 0
    WAVE64 = 1
    AUTO = 2

audio_async_render(audio, outfile, header=WaveHeader.AUTO, progress='Rendering audio...')

Render an audio by requesting frames asynchronously using audio.frames.

Implementation-like of VideoNode.output for an AudioNode that isn't in the Cython side yet.

Parameters:

Name Type Description Default
audio AudioNode

Audio to render.

required
outfile BinaryIO

Render output BinaryIO handle.

required
header WaveHeader

Kind of Wave header. WaveHeader.AUTO adds a Wave64 header if the audio * Has more than 2 channels * Has a bitdepth > 16 * Has more than 44100 samples

AUTO
progress Optional[str]

String to use for render progress display. If empty or None, no progress display.

'Rendering audio...'
Source code in vsmuxtools/utils/audio.py
def audio_async_render(
    audio: vs.AudioNode, outfile: BinaryIO, header: WaveHeader = WaveHeader.AUTO, progress: Optional[str] = "Rendering audio..."
) -> None:
    """
    Render an audio by requesting frames asynchronously using audio.frames.

    Implementation-like of VideoNode.output for an AudioNode that isn't in the Cython side yet.

    :param audio:       Audio to render.
    :param outfile:     Render output BinaryIO handle.
    :param header:      Kind of Wave header.
                        WaveHeader.AUTO adds a Wave64 header if the audio

                        * Has more than 2 channels
                        * Has a bitdepth > 16
                        * Has more than 44100 samples

    :param progress:    String to use for render progress display.
                        If empty or ``None``, no progress display.
    """
    if progress:
        p = get_render_progress()
        task = p.add_task(progress, total=audio.num_frames)
        p.start()

    bytes_per_output_sample = (audio.bits_per_sample + 7) // 8
    block_align = audio.num_channels * bytes_per_output_sample
    bytes_per_second = audio.sample_rate * block_align
    data_size = audio.num_samples * block_align

    if header == WaveHeader.AUTO:
        conditions = (audio.num_channels > 2, audio.bits_per_sample > 16, audio.num_samples > 44100)
        header_func, use_w64 = (_w64_header, WaveHeader.WAVE64) if any(conditions) else (_wav_header, WaveHeader.WAVE)
    else:
        use_w64 = header
        header_func = (_wav_header, _w64_header)[header]

    outfile.write(header_func(audio, bytes_per_second, block_align, data_size))

    for f in audio.frames(close=True):
        if progress:
            p.update(task, advance=1)
        _finish_frame_audio(f, outfile, audio.bits_per_sample == 24)
    size = outfile.tell()
    if use_w64:
        outfile.seek(16)
        outfile.write(struct.pack("<Q", size))
    else:
        outfile.seek(4)
        outfile.write(struct.pack("<I", size - 8))
    if progress:
        p.stop()