ó
    óó�jú  ã                   ó’   • S r SSKrSSKrSSKrSSKrS rS r\R                   " S S5      5       r
SSSSSS	.S
 jrSS jrS rS rg)aº  
Lightweight soundfile-based audio I/O compatibility layer.

This module provides a minimal compatibility wrapper for audio I/O operations
using soundfile (pysoundfile) library, replacing torchaudio's load, save, and
info functions.

Example
-------
>>> from speechbrain.dataio import audio_io
>>> import torch
>>> # Save audio file
>>> waveform = torch.randn(1, 16000)
>>> tmpdir = getfixture("tmpdir")
>>> audio_io.save(tmpdir / "example.wav", waveform, 16000)
>>> # Load audio file
>>> audio, sr = audio_io.load(tmpdir / "example.wav")
>>> # Get audio metadata
>>> info = audio_io.info(tmpdir / "example.wav")
>>> info.duration
1.0

Authors
-------
 * Peter Plantinga, 2025
 * Adel Moumen, 2026
é    Nc                 óÂ  • U R                   S:X  a  U R                  [        R                  5      $ U R	                  5       nU R                  5       n[        R                  " [        R                  5      R                  U::  aQ  U[        R                  " [        R                  5      R
                  ::  a  U R                  [        R                  5      $ [        R                  " [        R                  5      R                  U::  aQ  U[        R                  " [        R                  5      R
                  ::  a  U R                  [        R                  5      $ [        S5      e)zÍConvert integer arrays to a soundfile-supported integer dtype.

Using float32 for integer waveforms changes libsndfile write semantics for
PCM subtypes, because float writes are normalized to [-1.0, 1.0].
r   zDInteger audio values must fit in int16 or int32 for soundfile.write.)	ÚsizeÚastypeÚnpÚint16ÚminÚmaxÚiinfoÚint32Ú
ValueError)Úaudio_npÚ	min_valueÚ	max_values      Ú©C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\speechbrain/dataio/audio_io.pyÚ_convert_integer_numpy_for_saver   $   sß   € ð ‡}�}˜ÓØ�‰œrŸx™xÓ(Ð(à—‘“€IØ—‘“€Iô 	�Š”—‘Ó×Ñ )Ó+ØœŸš¤"§(¡(Ó+×/Ñ/Ó/à�‰œrŸx™xÓ(Ð(ô 	�Š”—‘Ó×Ñ )Ó+ØœŸš¤"§(¡(Ó+×/Ñ/Ó/à�‰œrŸx™xÓ(Ð(ä
ØNóð ó    c                 ó�  • [        U [        R                  5      (       aÛ  U R                  5       R	                  5       n U R
                  [        R                  [        R                  [        R                  [        R                  4;   a  U R                  5       $ [        R                  " U 5      (       a-  U R                  [        R                  5      R                  5       $ [        U R                  5       5      $ [        R                  " U 5      nUR
                  [        R                  [        R                  [        R                  [        R                  4;   a  U$ [        R                   " UR
                  [        R"                  5      (       a  UR%                  [        R                  5      $ [        R                   " UR
                  [        R&                  5      (       d4  [        R                   " UR
                  [        R(                  5      (       a  [        U5      $ [        R                  " U [        R                  S9$ )z<Convert tensors/arrays to a soundfile-supported numpy dtype.)Údtype)Ú
isinstanceÚtorchÚTensorÚdetachÚcpur   Úfloat32Úfloat64r   r   ÚnumpyÚis_floating_pointÚtor   r   ÚasarrayÚ
issubdtypeÚfloatingr   ÚintegerÚbool_)Úsrcr   s     r   Ú_to_soundfile_write_arrayr%   B   s]  € ô �#”u—|‘|×$Ñ$Ø�j‰j‹l×ÑÓ ˆà�9‰9Ü�M‰MÜ�M‰MÜ�K‰KÜ�K‰Kð	
ó 
ð —9‘9“;Ðä×"Ò" 3×'Ñ'Ø—6‘6œ%Ÿ-™-Ó(×.Ñ.Ó0Ð0ä.¨s¯y©y«{Ó;Ð;ä�zŠz˜#‹€Hà‡~�~œ"Ÿ*™*¤b§j¡j´"·(±(¼B¿H¹HÐEÓEØˆä	‡}‚}�X—^‘^¤R§[¡[×1Ñ1Ø�‰œrŸz™zÓ*Ð*ä	‡}‚}�X—^‘^¤R§Z¡Z×0Ñ0´B·M²MØ�‰œŸ™÷5ñ 5ô /¨xÓ8Ð8ä�:Š:�c¤§¡Ñ,Ð,r   c                   ó|   • \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \S 5       r	\S	 5       r
\S
 5       rSrg)Ú	AudioInfoée   a}  Container for audio file metadata, compatible with torchaudio.info output.

Attributes
----------
sample_rate : int
    Sample rate of the audio file.
frames : int
    Total number of frames in the audio file.
channels : int
    Number of audio channels.
subtype : str
    Audio subtype/encoding (e.g., 'PCM_16', 'PCM_24').
format : str
    Container format (e.g., 'WAV', 'FLAC').
Úsample_rateÚframesÚchannelsÚsubtypeÚformatc                 ó   • U R                   $ )z#Alias for frames for compatibility.)r*   ©Úselfs    r   Ú
num_framesÚAudioInfo.num_frames}   s   € ð �{‰{Ðr   c                 ó   • U R                   $ )z%Alias for channels for compatibility.)r+   r/   s    r   Únum_channelsÚAudioInfo.num_channels‚   s   € ð �}‰}Ðr   c                 óX   • U R                   S:”  a  U R                  U R                   -  $ S$ )zCalculate duration in seconds.r   g        )r)   r*   r/   s    r   ÚdurationÚAudioInfo.duration‡   s+   € ð 26×1AÑ1AÀAÓ1Eˆt�{‰{˜T×-Ñ-Ñ-ÐNÈ3ÐNr   © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚintÚ__annotations__ÚstrÚpropertyr1   r4   r7   Ú__static_attributes__r9   r   r   r'   r'   e   s_   ‡ ñð  ÓØƒKØƒMØƒLØƒKàñó ðð ñó ðð ñOó óOr   r'   Téÿÿÿÿ)Úchannels_firstr   Ú	always_2dÚframe_offsetr1   c                óÖ  •  U=(       d    [         R                  " 5       n[        U5      R                  S5      u  pgU[        R
                  ;  a  Sn[        R                  " U UUUUS9u  p‰[         R                  " U5      R                  U5      n
U
R                  S:X  a  U(       a  U
R                  SS5      n
U
[        U	5      4$ ! [         a  n[        SU  SU 35      UeS	nAff = f)
aè  Load audio file using soundfile.

Arguments
---------
path : str
    Path to the audio file.
channels_first : bool
    If True, returns tensor with shape (channels, frames).
    If False, returns tensor with shape (frames, channels).
    Ignored if `always_2d` is False and input is mono.
    Default: True.
dtype : torch.dtype, optional
    Data type for the output tensor. Respects default torch type.
    If the dtype is not one of the available dtypes in soundfile, loads
    with float32 first and then converts to the requested dtype.
always_2d : bool
    If True, always return a 2D tensor even for mono audio.
    If False, mono audio returns a 1D tensor (frames,).
    Default: True.
frame_offset : int
    Number of frames to skip at the start of the file. Default: 0.
num_frames : int
    Number of frames to read. If -1, reads to the end of the file. Default: -1.

Returns
-------
tensor : torch.Tensor
    Audio waveform as a tensor.
sample_rate : int
    Sample rate of the audio file.
Ú.r   )Ústartr*   r   rF   é   r   é   zFailed to load audio from ú: N)r   Úget_default_dtyperA   ÚsplitÚsfÚ
_ffi_typesÚreadÚ
from_numpyr   ÚndimÚ	transposer?   Ú	ExceptionÚRuntimeError)ÚpathrE   r   rF   rG   r1   Ú_Údtype_stringr   r)   ÚaudioÚes               r   Úloadr]   �   sà   € ðPLà×2œ×0Ò0Ó2ˆÜ˜e›*×*Ñ*¨3Ó/‰ˆð œrŸ}™}Ó,Ø$ˆLô !#§¢ØØØØØñ!
Ñˆô × Ò  Ó*×-Ñ-¨eÓ4ˆð �:‰:˜‹?ž~Ø—O‘O A qÓ)ˆEà”c˜+Ó&Ð&Ð&øäó LÜÐ7¸°v¸RÀ¸sÐCÓDÈ!ÐKûðLús   ‚CC Ã
C(ÃC#Ã#C(c                 ó&  •  [        U5      nUR                  S:X  a  U(       a  UR                  nUR                  S;  a  [        SUR                   S35      e[
        R                  " XX$S9  g! [         a  n[        SU  SU 35      UeSnAff = f)	a  Save audio to file using soundfile.

Arguments
---------
path : str
    Path where to save the audio file.
src : torch.Tensor or numpy.ndarray
    Audio waveform. Can be:
    - 1D tensor/array: (frames,) - mono
    - 2D tensor/array:
        - (channels, frames) if channels_first=True
        - (frames, channels) if channels_first=False
sample_rate : int
    Sample rate for the audio file.
channels_first : bool
    If True, input is assumed to be (channels, frames)
    If False, input is assumed to be (frames, channels).
    Ignored if input is 1D tensor/array.
    Default: True.
subtype : str, optional
    Audio encoding subtype (e.g., 'PCM_16', 'PCM_24', 'PCM_32', 'FLOAT').
    If None, soundfile will choose an appropriate subtype based on the file format.
    Default: None.
rK   )rL   rK   zUnsupported audio shape: z/. Expected 1D frames or 2D channels and frames.)r,   zFailed to save audio to rM   N)	r%   rT   ÚTr   ÚshaperP   ÚwriterV   rW   )rX   r$   r)   rE   r,   r   r\   s          r   Úsaverb   Ô   s™   € ð2JÜ,¨SÓ1ˆð �=‰=˜AÓ¦.Ø—z‘zˆHà�=‰= Ó&ÜØ+¨H¯N©NÐ+;ð <@ð @óð ô
 	�Š� Ó>øäó JÜÐ5°d°V¸2¸a¸SÐAÓBÈÐIûðJús   ‚A,A/ Á/
BÁ9BÂBc                 óö   •  [         R                  " U 5      n[        UR                  UR                  UR
                  UR                  UR                  S9$ ! [         a  n[        SU  SU 35      UeSnAff = f)zåGet audio file metadata using soundfile.

Arguments
---------
path : str
    Path to the audio file.

Returns
-------
AudioInfo
    Object containing audio metadata (sample_rate, frames, channels,
    subtype, format, duration).
)r)   r*   r+   r,   r-   zFailed to get info for rM   N)
rP   Úinfor'   Ú
samplerater*   r+   r,   r-   rV   rW   )rX   Ú	file_infor\   s      r   rd   rd      s~   € ð
IÜ—G’G˜D“Mˆ	ÜØ!×,Ñ,Ø×#Ñ#Ø×'Ñ'Ø×%Ñ%Ø×#Ñ#ñ
ð 	
øô ó IÜÐ4°T°F¸"¸Q¸CÐ@ÓAÀqÐHûðIús   ‚AA Á
A8Á!A3Á3A8c                  ó   • S/$ )zList available audio backends.

Returns
-------
list of str
    List of available backend names. Currently only ['soundfile'].
Ú	soundfiler9   r9   r   r   Úlist_audio_backendsri     s   € ð ˆ=Ðr   )TN)r>   Údataclassesr   r   rh   rP   r   r   r%   Ú	dataclassr'   r]   rb   rd   ri   r9   r   r   Ú<module>rl      sq   ðñó8 ã Û Û òò< -ðF ×Ñ÷$Oð $Oó ð$OðT Ø
ØØØõDLôN)JòXIó6r   