diff --git a/.github/workflows/native-release.yml b/.github/workflows/native-release.yml index b0df8bc..3e18fb0 100644 --- a/.github/workflows/native-release.yml +++ b/.github/workflows/native-release.yml @@ -1,99 +1,99 @@ -name: Native builds - -on: - workflow_dispatch: - push: - branches: - - main - tags: - - "v*" - -permissions: - contents: read - -jobs: - build: - name: ${{ matrix.asset }} - runs-on: ${{ matrix.runner }} - - strategy: - fail-fast: false - matrix: - include: - - runner: windows-2022 - asset: windows-x64 - cmake_args: -A x64 - - - runner: ubuntu-22.04 - asset: linux-x64 - cmake_args: "" - - - runner: macos-15-intel - asset: macos-x64 - cmake_args: -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 - - - runner: macos-15 - asset: macos-arm64 - cmake_args: -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Configure - run: > - cmake - -S native - -B build/native - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/stage" - ${{ matrix.cmake_args }} - - - name: Build - run: cmake --build build/native --config Release --parallel - - - name: Install - run: cmake --install build/native --config Release - - - name: Package - working-directory: stage - run: > - cmake -E tar - cf "../JustOneCacophony-native-${{ matrix.asset }}.zip" - --format=zip - -- . - - - name: Upload workflow artifact - uses: actions/upload-artifact@v4 - with: - name: JustOneCacophony-native-${{ matrix.asset }} - path: JustOneCacophony-native-${{ matrix.asset }}.zip - if-no-files-found: error - retention-days: 14 - - release: - name: Publish GitHub Release - if: startsWith(github.ref, 'refs/tags/v') - needs: build - runs-on: ubuntu-24.04 - - permissions: - contents: write - - steps: - - name: Download native packages - uses: actions/download-artifact@v5 - with: - pattern: JustOneCacophony-native-* - path: dist - merge-multiple: true - - - name: Create release - run: > - gh release create "$GITHUB_REF_NAME" - dist/*.zip - --verify-tag - --generate-notes - env: - GH_TOKEN: ${{ github.token }} - GH_REPO: ${{ github.repository }} +name: Native builds + +on: + workflow_dispatch: + push: + branches: + - main + tags: + - "v*" + +permissions: + contents: read + +jobs: + build: + name: ${{ matrix.asset }} + runs-on: ${{ matrix.runner }} + + strategy: + fail-fast: false + matrix: + include: + - runner: windows-2022 + asset: windows-x64 + cmake_args: -A x64 + + - runner: ubuntu-22.04 + asset: linux-x64 + cmake_args: "" + + - runner: macos-15-intel + asset: macos-x64 + cmake_args: -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 + + - runner: macos-15 + asset: macos-arm64 + cmake_args: -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Configure + run: > + cmake + -S native + -B build/native + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/stage" + ${{ matrix.cmake_args }} + + - name: Build + run: cmake --build build/native --config Release --parallel + + - name: Install + run: cmake --install build/native --config Release + + - name: Package + working-directory: stage + run: > + cmake -E tar + cf "../JustOneCacophony-native-${{ matrix.asset }}.zip" + --format=zip + -- . + + - name: Upload workflow artifact + uses: actions/upload-artifact@v4 + with: + name: JustOneCacophony-native-${{ matrix.asset }} + path: JustOneCacophony-native-${{ matrix.asset }}.zip + if-no-files-found: error + retention-days: 14 + + release: + name: Publish GitHub Release + if: startsWith(github.ref, 'refs/tags/v') + needs: build + runs-on: ubuntu-24.04 + + permissions: + contents: write + + steps: + - name: Download native packages + uses: actions/download-artifact@v5 + with: + pattern: JustOneCacophony-native-* + path: dist + merge-multiple: true + + - name: Create release + run: > + gh release create "$GITHUB_REF_NAME" + dist/*.zip + --verify-tag + --generate-notes + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 948e164..622a656 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -7,7 +7,8 @@ 64-QMF → 77-hybrid 结构与 13-tap 低带 prototype 定义于 [3GPP TS 26.405 / ETSI TS 126 405](https://www.etsi.org/deliver/etsi_ts/126400_126499/126405/06.00.00_60/ts_126405v060000p.pdf) -第 5.2.2 节(Table 1 的 $Q=8$/$Q=4$ 系数,delay 6): +第 5.2.2 节(Table 1 的 $Q=8$/ +$Q=4$ 系数,delay 6): $$G_q^p[n] = g^p[n]\cdot\exp\!\Bigl(j\,\frac{2\pi}{Q^p}\bigl(q+\tfrac12\bigr)(n-6)\Bigr)$$ @@ -18,14 +19,15 @@ AAC/SBR 64 complex QMF bank;打包的 $64\times10$ 表是公开 640-tap protot $$A_{r,t} = \frac{(-1)^t}{128}\,c_{63-r+64t}$$ QMF synthesis 表为 analysis 多相矩阵 $\mathbf{A}$ 的因果左逆 -$\mathbf{A}\,\mathbf{W}=\mathbf{P}$($\mathbf{P}$ 为 577-sample 延迟置换; +$\mathbf{A}\,\mathbf{W}=\mathbf{P}$( +$\mathbf{P}$ 为 577-sample 延迟置换; 全链 $961 = 577 + 6\times64$),rank-4 分解存储: $$W_{b,l} = \sum_{r=1}^{4} t_{b,l,r}\,\mathbf{b}_{b,r}^{\top}$$ hybrid synthesis 表为 77→64 重组:高频带恒等 $Y_{3+b}=X_{16+b}$,低频带: -$$Y_p = \sum_{q\in C_p}\Bigl(\operatorname{Re}X_q + j\,s_q\,\operatorname{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ +$$Y_p = \sum_{q\in C_p}\Bigl(\mathrm{Re}X_q + j\,s_q\,\mathrm{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ 相同数值可在 FFmpeg(`aacps_tablegen.h`、`aacsbrdata.h`)等公开实现中查到。 diff --git a/docs/binaural.en.md b/docs/binaural.en.md index 20f9864..77063b8 100644 --- a/docs/binaural.en.md +++ b/docs/binaural.en.md @@ -109,8 +109,12 @@ The strict importer currently accepts: - an explicitly free-field/anechoic `RoomType`. Receiver order comes from geometry, never from the receiver array index. SOFA -listener coordinates are $+X$ front, $+Y$ left, $+Z$ up; ADM coordinates are -$+X$ right, $+Y$ front, $+Z$ up: +listener coordinates are $+X$ front, +$+Y$ left, +$+Z$ up; ADM coordinates are +$+X$ right, +$+Y$ front, +$+Z$ up: $$\bigl(x_{\mathrm{SOFA}},\ y_{\mathrm{SOFA}},\ z_{\mathrm{SOFA}}\bigr) = \bigl(y_{\mathrm{ADM}},\ -x_{\mathrm{ADM}},\ z_{\mathrm{ADM}}\bigr)$$ @@ -159,7 +163,8 @@ The fixed resource is `data/rosella_kernels.npz`, which implements publicly standardized filter banks, computable from the following formulas. The hybrid analysis kernels are defined in [3GPP TS 26.405 / ETSI TS 126 405](https://www.etsi.org/deliver/etsi_ts/126400_126499/126405/06.00.00_60/ts_126405v060000p.pdf), -Section 5.2.2 (Table 1 $Q=8$/$Q=4$ coefficients, delay 6): +Section 5.2.2 (Table 1 $Q=8$/ +$Q=4$ coefficients, delay 6): $$G_q^p[n] = g^p[n]\cdot\exp\!\Bigl(j\,\frac{2\pi}{Q^p}\bigl(q+\tfrac12\bigr)(n-6)\Bigr),\qquad n=0,\dots,12$$ @@ -170,17 +175,19 @@ reordering of the public 640-tap prototype $c_0,\dots,c_{639}$: $$A_{r,t} = \frac{(-1)^t}{128}\,c_{63-r+64t},\qquad r=0,\dots,63,\ t=0,\dots,9$$ The QMF synthesis table is the causal left inverse of the analysis polyphase -matrix $\mathbf{A}$, i.e. the solution of $\mathbf{A}\,\mathbf{W}=\mathbf{P}$ +matrix $\mathbf{A}$, i.e. the solution of +$\mathbf{A}\,\mathbf{W}=\mathbf{P}$ ($\mathbf{P}$ is the 577-sample delay permutation; total latency $961 = 577 + 6\times64$), stored as a rank-4 factorization: $$W_{b,l} = \sum_{r=1}^{4} t_{b,l,r}\,\mathbf{b}_{b,r}^{\top}$$ The hybrid synthesis table is the 77→64 recombination: identity for the high -bands, $Y_{3+b}=X_{16+b}$, and for the low bands ($C_p$ is the $8+4+4$ child -partition): +bands, $Y_{3+b}=X_{16+b}$, and for the low bands( +$C_p$ is the +$8+4+4$ child partition): -$$Y_p = \sum_{q\in C_p}\Bigl(\operatorname{Re}X_q + j\,s_q\,\operatorname{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ +$$Y_p = \sum_{q\in C_p}\Bigl(\mathrm{Re}X_q + j\,s_q\,\mathrm{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ The loader verifies the archive and every array by SHA-256; the table version, all array hashes, and the 77 reference band-center values are part of the cache diff --git a/docs/binaural.md b/docs/binaural.md index 8d12e5c..ad0d924 100644 --- a/docs/binaural.md +++ b/docs/binaural.md @@ -99,7 +99,11 @@ cached = SofaBinauralBackend.from_compiled_cache( - 明确的 free-field/anechoic `RoomType`。 receiver 左右顺序由几何决定,不能假定 `Data.IR` 的 receiver index。SOFA listener -坐标为 $+X$ front、$+Y$ left、$+Z$ up;ADM 坐标为 $+X$ right、$+Y$ front、 +坐标为 $+X$ front、 +$+Y$ left、 +$+Z$ up;ADM 坐标为 +$+X$ right、 +$+Y$ front、 $+Z$ up,转换为: $$\bigl(x_{\mathrm{SOFA}},\ y_{\mathrm{SOFA}},\ z_{\mathrm{SOFA}}\bigr) = \bigl(y_{\mathrm{ADM}},\ -x_{\mathrm{ADM}},\ z_{\mathrm{ADM}}\bigr)$$ @@ -144,7 +148,8 @@ ridge 为 `1e-3`,SH ridge 为 `1e-5`。同方向 measurement 先合并,再 公式计算。 hybrid 分析核定义于 [3GPP TS 26.405 / ETSI TS 126 405](https://www.etsi.org/deliver/etsi_ts/126400_126499/126405/06.00.00_60/ts_126405v060000p.pdf) -第 5.2.2 节(Table 1 的 $Q=8$/$Q=4$ 系数,delay 6): +第 5.2.2 节(Table 1 的 $Q=8$/ +$Q=4$ 系数,delay 6): $$G_q^p[n] = g^p[n]\cdot\exp\!\Bigl(j\,\frac{2\pi}{Q^p}\bigl(q+\tfrac12\bigr)(n-6)\Bigr),\qquad n=0,\dots,12$$ @@ -155,15 +160,17 @@ $c_0,\dots,c_{639}$ 的多相重排: $$A_{r,t} = \frac{(-1)^t}{128}\,c_{63-r+64t},\qquad r=0,\dots,63,\ t=0,\dots,9$$ QMF synthesis 表为上述 analysis 多相矩阵 $\mathbf{A}$ 的因果左逆,即求解 -$\mathbf{A}\,\mathbf{W}=\mathbf{P}$($\mathbf{P}$ 为 577-sample 延迟置换; +$\mathbf{A}\,\mathbf{W}=\mathbf{P}$( +$\mathbf{P}$ 为 577-sample 延迟置换; 全链 $961 = 577 + 6\times64$),以 rank-4 分解形式存储: $$W_{b,l} = \sum_{r=1}^{4} t_{b,l,r}\,\mathbf{b}_{b,r}^{\top}$$ -hybrid synthesis 表为 77→64 重组:高频带恒等 $Y_{3+b}=X_{16+b}$;低频带 -($C_p$ 为 $8+4+4$ 子带划分): +hybrid synthesis 表为 77→64 重组:高频带恒等 $Y_{3+b}=X_{16+b}$;低频带( +$C_p$ 为 +$8+4+4$ 子带划分): -$$Y_p = \sum_{q\in C_p}\Bigl(\operatorname{Re}X_q + j\,s_q\,\operatorname{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ +$$Y_p = \sum_{q\in C_p}\Bigl(\mathrm{Re}X_q + j\,s_q\,\mathrm{Im}X_q\Bigr),\qquad s_q\in\{\pm1\}$$ loader 校验 archive 和每个数组的 SHA-256;table version、所有数组 hash 与 77 个 band-center 参考值都属于 cache key。标准可公开获取不等于获准实施相关 diff --git a/docs/math.en.md b/docs/math.en.md index bd5e1d0..4c3e0a4 100644 --- a/docs/math.en.md +++ b/docs/math.en.md @@ -230,10 +230,10 @@ Write the 64 complex subbands as 128 interleaved real values in `src`. For $k=0\ $$ \begin{aligned} -\operatorname{zone}[2k] &= \operatorname{src}[4k],\\ -\operatorname{zone}[2k+1] &= -\operatorname{src}[4k+1],\\ -\operatorname{zone}[126-2k] &= \operatorname{src}[4k+2],\\ -\operatorname{zone}[127-2k] &= \operatorname{src}[4k+3]. +\mathrm{zone}[2k] &= \mathrm{src}[4k],\\ +\mathrm{zone}[2k+1] &= -\mathrm{src}[4k+1],\\ +\mathrm{zone}[126-2k] &= \mathrm{src}[4k+2],\\ +\mathrm{zone}[127-2k] &= \mathrm{src}[4k+3]. \end{aligned} $$ @@ -242,7 +242,7 @@ Treat `zone` as 64 complex values and apply an unnormalized 64-point FFT: $$ F_k= \sum_{n=0}^{63} -\operatorname{zone}_n +\mathrm{zone}_n \exp\!\left(-j\frac{2\pi kn}{64}\right). $$ @@ -277,7 +277,7 @@ Object output is $$ y_o[64t+r]= -\operatorname{clip}\!\left( +\mathrm{clip}\!\left( 16\,\mathbf y_{o,t}[r],-1,1 \right)G_{\mathrm{clip}}, $$ @@ -290,7 +290,7 @@ LFE bypasses the object matrix and inverse QMF and uses a 1217-sample delay. Aft $$ y_{\mathrm{LFE}}[n]= -\operatorname{clip}\!\left( +\mathrm{clip}\!\left( x_{\mathrm{LFE,core}}[n-1217],-1,1 \right). $$ @@ -322,11 +322,11 @@ Their maximum runtime value is $32767/32768$, not exactly 1. For conversion to the ADM grid: $$ -k_1=\operatorname{round}\!\left(\frac{62q_1}{32767}\right), +k_1=\mathrm{round}\!\left(\frac{62q_1}{32767}\right), \quad -k_2=\operatorname{round}\!\left(\frac{62q_2}{32767}\right), +k_2=\mathrm{round}\!\left(\frac{62q_2}{32767}\right), \quad -k_3=\operatorname{round}\!\left(\frac{15q_3}{32767}\right), +k_3=\mathrm{round}\!\left(\frac{15q_3}{32767}\right), $$ $$ @@ -398,7 +398,7 @@ For 5.1-family layouts with one horizontal surround pair rather than separate si $$ v_{\mathrm{floor}}= -\operatorname{clamp}(2v,0,1). +\mathrm{clamp}(2v,0,1). $$ Other layouts use $v_{\mathrm{floor}}=v$. @@ -441,15 +441,15 @@ $$ Longitudinal and height weights are $$ -p_v=\operatorname{clamp}\left(\frac v{0.6},0,1\right), +p_v=\mathrm{clamp}\left(\frac v{0.6},0,1\right), $$ $$ -p_w=\operatorname{clamp}\left(\frac{w-0.2}{0.8},0,1\right), +p_w=\mathrm{clamp}\left(\frac{w-0.2}{0.8},0,1\right), $$ $$ -p=\operatorname{clamp}(p_v+p_w,0,1). +p=\mathrm{clamp}(p_v+p_w,0,1). $$ The linear compensation gain is @@ -550,8 +550,8 @@ For PCM24 output, quantization is $$ y_{24}[n]= -\operatorname{trunc}\left( -8388607\,\operatorname{clip}(y[n],-1,1) +\mathrm{trunc}\left( +8388607\,\mathrm{clip}(y[n],-1,1) \right). $$ diff --git a/docs/math.md b/docs/math.md index db37f39..59c314c 100644 --- a/docs/math.md +++ b/docs/math.md @@ -230,10 +230,10 @@ analysis 输入的 $1/16$ 缩放会在 inverse QMF 输出端由 $\times16$ 抵 $$ \begin{aligned} -\operatorname{zone}[2k] &= \operatorname{src}[4k],\\ -\operatorname{zone}[2k+1] &= -\operatorname{src}[4k+1],\\ -\operatorname{zone}[126-2k] &= \operatorname{src}[4k+2],\\ -\operatorname{zone}[127-2k] &= \operatorname{src}[4k+3]. +\mathrm{zone}[2k] &= \mathrm{src}[4k],\\ +\mathrm{zone}[2k+1] &= -\mathrm{src}[4k+1],\\ +\mathrm{zone}[126-2k] &= \mathrm{src}[4k+2],\\ +\mathrm{zone}[127-2k] &= \mathrm{src}[4k+3]. \end{aligned} $$ @@ -242,7 +242,7 @@ $$ $$ F_k= \sum_{n=0}^{63} -\operatorname{zone}_n +\mathrm{zone}_n \exp\!\left(-j\frac{2\pi kn}{64}\right). $$ @@ -277,7 +277,7 @@ $$ $$ y_o[64t+r]= -\operatorname{clip}\!\left( +\mathrm{clip}\!\left( 16\,\mathbf y_{o,t}[r],-1,1 \right)G_{\mathrm{clip}}, $$ @@ -290,7 +290,7 @@ LFE 不经过对象矩阵或 inverse QMF,而是使用 1217-sample 延迟。输 $$ y_{\mathrm{LFE}}[n]= -\operatorname{clip}\!\left( +\mathrm{clip}\!\left( x_{\mathrm{LFE,core}}[n-1217],-1,1 \right). $$ @@ -322,11 +322,11 @@ $$ 转换为 ADM 网格时: $$ -k_1=\operatorname{round}\!\left(\frac{62q_1}{32767}\right), +k_1=\mathrm{round}\!\left(\frac{62q_1}{32767}\right), \quad -k_2=\operatorname{round}\!\left(\frac{62q_2}{32767}\right), +k_2=\mathrm{round}\!\left(\frac{62q_2}{32767}\right), \quad -k_3=\operatorname{round}\!\left(\frac{15q_3}{32767}\right), +k_3=\mathrm{round}\!\left(\frac{15q_3}{32767}\right), $$ $$ @@ -398,7 +398,7 @@ $$ $$ v_{\mathrm{floor}}= -\operatorname{clamp}(2v,0,1). +\mathrm{clamp}(2v,0,1). $$ 其他布局使用 $v_{\mathrm{floor}}=v$。 @@ -441,15 +441,15 @@ $$ 前后与高度位置权重为 $$ -p_v=\operatorname{clamp}\left(\frac v{0.6},0,1\right), +p_v=\mathrm{clamp}\left(\frac v{0.6},0,1\right), $$ $$ -p_w=\operatorname{clamp}\left(\frac{w-0.2}{0.8},0,1\right), +p_w=\mathrm{clamp}\left(\frac{w-0.2}{0.8},0,1\right), $$ $$ -p=\operatorname{clamp}(p_v+p_w,0,1). +p=\mathrm{clamp}(p_v+p_w,0,1). $$ 线性补偿增益为 @@ -550,8 +550,8 @@ $$ $$ y_{24}[n]= -\operatorname{trunc}\left( -8388607\,\operatorname{clip}(y[n],-1,1) +\mathrm{trunc}\left( +8388607\,\mathrm{clip}(y[n],-1,1) \right). $$