spaudiopy

repository·master·Indexed 41 days ago

https://github.com/chris-hld/spaudiopy

A Python package for spatial audio encoders and decoders, providing tools for spherical harmonics processing and loudspeaker decoders, including VBAP and AllRAD for binaural rendering. It supports sector analysis and synthesis, modal weight functions (cardioid, hypercardioid, Max-RE), and spherical T-design generation.

Tokens
5.6K
Snippets
24
Records
25
Agent score
46%

What's inside spaudiopy

  1. Use multiprocessing with jobs_count

    master

    Many functions in spaudiopy accept a jobs_count argument. When provided, the implementation will attempt to launch multiple processing jobs to parallelize the workload.

    Note: Increasing jobs_count introduces computational overhead; more jobs do not always result in faster execution. Performance gains depend on the specific task and available system resources.

    # Example usage pattern
    # Assuming a function that supports jobs_count
    result = some_spaudiopy_function(..., jobs_count=4)
  2. Install spaudiopy using Conda

    master

    For a managed environment, you can use Conda. It is recommended to use a Python distribution like Anaconda. This method ensures that system-level dependencies like portaudio are installed alongside Python.

    # Create a conda environment with Python 3.8, anaconda, and portaudio
    conda create --name spaudio python=3.8 anaconda portaudio
    
    # Activate the environment
    conda activate spaudio
  3. Install spaudiopy from source using Conda

    master

    If you need to install from source or want a controlled environment, follow these steps to set up a Conda environment with the necessary dependencies (including portaudio):

    1. Create a new environment named spaudio with Python 3.8 and portaudio: conda create --name spaudio python=3.8 anaconda portaudio
    2. Activate the environment: conda activate spaudio
    3. Clone the repository and install in editable mode: git clone https://github.com/chris-hld/spaudiopy.git && cd spaudiopy pip install -e .
    conda create --name spaudio python=3.8 anaconda portaudio
    conda activate spaudio
    git clone https://github.com/chris-hld/spaudiopy.git && cd spaudiopy
    pip install -e .
  4. Install spaudiopy in editable mode from source

    master

    If you want to install the package from the GitHub source code in editable mode (useful for development), clone the repository and run pip install -e .. This will automatically resolve and install any remaining dependencies not provided by your conda environment.

    # Navigate to the cloned spaudiopy directory
    pip install -e .
  5. Protect main() for multiprocessing on Windows

    master

    When using functions that utilize multiprocessing (via the jobs_count argument), you must protect your entry point on Windows to prevent recursive process spawning. Wrap your execution logic within an if __name__ == '__main__': block.

    if __name__ == '__main__':
        # Put your code here
        # e.g., calling spaudiopy functions with jobs_count
  6. Perform amplitude and energy reconstruction with beta factors

    master

    When summing sectorized signals, a compensation factor $\beta$ is required to ensure the reconstructed signal preserves either the total amplitude or the total energy.

    Amplitude Reconstruction

    To preserve amplitude, use $\beta_a$. The reconstructed signal is obtained by performing an Inverse Spherical Harmonic Transform (iSHT) on the sum of the sectorized signals multiplied by $\beta_a$.

    Energy Reconstruction

    To preserve energy, use $\beta_e$. The reconstructed signal is obtained by performing an SHT on the sum of the squared magnitudes of the sectorized signals multiplied by $\beta_e$.

    Workflow:

    1. Transform SH coefficients to the discrete domain using spa.sph.inverse_sht.
    2. Sum the discrete sector signals.
    3. Apply the appropriate $\beta$ factor.
    4. Transform back to the SH domain using spa.sph.sht.
    # 1. iSHT to discrete domain
    trans_azi, trans_zen, _ = spa.utils.cart2sph(*spa.grids.load_t_design(2*N_sph_sec).T)
    secs = spa.sph.inverse_sht(w_sec_nm.T, trans_azi, trans_zen, 'real')
    
    # 2. Amplitude Reconstruction
    # beta_a calculation (example logic)
    beta_a = np.sqrt(4*np.pi) / (w_sec_nm[0, 0] * len(secs))
    
    w0_a = spa.sph.sht(np.sum(beta_a * secs, axis=1), 
                       N_sph_sec, trans_azi, trans_zen, 'real')
    
    # 3. Energy Reconstruction
    # beta_e calculation (example logic)
    beta_e = 1 / (w_sec_nm[0, :].conj() @ w_sec_nm[0, :] / np.sqrt(4*np.pi) * len(secs)/np.sqrt(4*np.pi))
    
    w0_e = spa.sph.sht(beta_e * np.sum(np.abs(secs)**2, axis=1), 
                       N_sph_sec, trans_azi, trans_zen, 'real')
  7. Generate spherical sector patterns

    master

    To create spatial filter sectors, you first define the sector order (N_sph_sec) and then load a spherical design (e.g., T-design) to determine the sector directions. You can then generate modal weights for different pattern types like cardioid, hypercardioid, or maxRE. Finally, use the Spherical Harmonic (SH) matrix to convert these weights into the SH domain.

    Common pattern types:

    • cardioid: Standard cardioid patterns.
    • hypercardioid: Hypercardioid patterns.
    • maxRE: Maximum energy/amplitude reconstruction patterns (use spa.sph.maxre_modal_weights(N_sph_sec, True) for amplitude compensation).
    import spaudiopy as spa
    import numpy as np
    
    # Configuration
    N_sph_sec = 2
    pattern = "maxRE"
    
    # 1. Load sector directions using a T-design
    # Use 2*N if doing energy reconstruction, else N+1
    sec_vecs = spa.grids.load_t_design(2*N_sph_sec)
    sec_azi, sec_zen, _ = spa.utils.cart2sph(*sec_vecs.T)
    
    # 2. Generate modal weights based on pattern type
    if pattern.lower() == "maxre":
        c_n = spa.sph.maxre_modal_weights(N_sph_sec, True)
    elif pattern.lower() == "cardioid":
        c_n = spa.sph.cardioid_modal_weights(N_sph_sec)
    
    # 3. Create the SH coefficients for the sectors
    w_sec_nm = spa.sph.repeat_per_order(c_n) * spa.sph.sh_matrix(N_sph_sec, sec_azi, sec_zen, 'real')
  8. Generate pulsed noise with spaudiopy.process

    master

    You can generate pulsed noise using spa.process.pulsed_noise. This function requires the duration of the pulse, the duration of the silence/gap, the sampling frequency, and an optional reps parameter to specify the number of repetitions.

    import spaudiopy as spa
    
    fs = 48000
    l = 0.5
    # sig_in is a mono input signal
    sig_in = spa.process.pulsed_noise(l, l, fs, reps=3)
  9. Construct a sector analysis matrix with specific patterns

    master

    A sector analysis matrix A_sec is composed of stacked beamformers. You can choose different spatial patterns for the sectors using spa.sph modal weight functions:

    • spa.sph.cardioid_modal_weights(N_sph): Creates cardioid patterns.
    • spa.sph.hypercardioid_modal_weights(N_sph): Creates hyper-cardioid patterns.
    • spa.sph.maxre_modal_weights(N_sph, compensation): Creates Max-RE patterns (supports amplitude compensation).

    The matrix is constructed by multiplying the repeated modal weights by the Spherical Harmonic (SH) matrix generated via spa.sph.sh_matrix.

    # Example using Max-RE pattern
    c_n = spa.sph.maxre_modal_weights(N_sph_sec, True)
    # Construct A_sec: repeat weights per order * SH matrix
    A_sec = spa.sph.repeat_per_order(c_n) * \
            spa.sph.sh_matrix(N_sph_sec, sec_azi, sec_zen, shtype)