diff --git a/.github/workflows/llext.yml b/.github/workflows/llext.yml index 21b812b47600..a2888b75f2f4 100644 --- a/.github/workflows/llext.yml +++ b/.github/workflows/llext.yml @@ -7,9 +7,15 @@ name: Zephyr LLEXT # yamllint disable-line rule:truthy on: [pull_request, workflow_dispatch] +defaults: + run: + shell: bash + jobs: build: runs-on: ubuntu-22.04 + container: + image: thesofproject/zephyr-lite:v0.28.4 strategy: fail-fast: false @@ -17,33 +23,30 @@ jobs: platform: [mtl, lnl] steps: - - name: free space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - - - name: git clone sof + - name: checkout uses: actions/checkout@v4 with: - path: ./workspace/sof + path: sof fetch-depth: 0 # fix git describe filter: 'tree:0' - - name: west clones - run: pip3 install west && cd workspace/sof/ && west init -l && - west update --narrow --fetch-opt=--depth=5 + - name: west update + working-directory: sof + run: | + west init -l + west update --narrow --fetch-opt=--depth=5 - - name: Download docker image && ls /opt/toolchains/ - run: cd workspace && ./sof/zephyr/docker-run.sh ls -l /opt/toolchains/ + - name: print all available sdks in /opt/toolchains/ + run: | + ls -l /opt/toolchains/ - name: llext build run: | - cd workspace && ./sof/zephyr/docker-run.sh /bin/sh -c \ - "ln -s /opt/toolchains/zephyr-sdk-* ~/; - python sof/scripts/xtensa-build-zephyr.py \ - --cmake-args=-DEXTRA_CFLAGS=-Werror \ - --cmake-args=-DEXTRA_CXXFLAGS=-Werror \ - --cmake-args=-DEXTRA_AFLAGS='-Werror -Wa,--fatal-warnings' \ - --cmake-args=--warn-uninitialized \ - --overlay=sof/app/configs/${{ matrix.platform }}/modules.conf \ - ${{ matrix.platform }}" + ln -s /opt/toolchains/zephyr-sdk-* ~/ + python sof/scripts/xtensa-build-zephyr.py \ + --cmake-args=-DEXTRA_CFLAGS=-Werror \ + --cmake-args=-DEXTRA_CXXFLAGS=-Werror \ + --cmake-args=-DEXTRA_AFLAGS='-Werror -Wa,--fatal-warnings' \ + --cmake-args=--warn-uninitialized \ + --overlay=sof/app/configs/${{ matrix.platform }}/modules.conf \ + ${{ matrix.platform }} diff --git a/.github/workflows/sof-docs.yml b/.github/workflows/sof-docs.yml index 5b647816b93c..5920c51aaad5 100644 --- a/.github/workflows/sof-docs.yml +++ b/.github/workflows/sof-docs.yml @@ -56,4 +56,4 @@ jobs: run: pip install -r sof-docs/scripts/requirements.txt - name: build sof-docs - run: make -C sof-docs/ html SOF_DOC_BUILD="$(pwd)"/doxybuild/ + run: LAX=1 make -C sof-docs/ html SOF_DOC_BUILD="$(pwd)"/doxybuild/ diff --git a/.github/workflows/sparse-zephyr.yml b/.github/workflows/sparse-zephyr.yml index edb484c42a50..e66856691dcb 100644 --- a/.github/workflows/sparse-zephyr.yml +++ b/.github/workflows/sparse-zephyr.yml @@ -7,6 +7,10 @@ name: Sparse Zephyr # yamllint disable-line rule:truthy on: [push, pull_request, workflow_dispatch, workflow_call] +defaults: + run: + shell: bash + jobs: # As of sparse commit ce1a6720f69e / Sept 2022, the exit status of # sparse.c is an unusable mess and always zero in practice. Moreover @@ -14,10 +18,15 @@ jobs: # small subset of specific warnings defined in # sof/scripts/parse_sparse_output.sh warnings-subset: + # disable until https://github.com/zephyrproject-rtos/zephyr/issues/93444 + # is fixed + if: false # We're sharing the sparse binary with the zephyr-build container so keep # this in sync with it. runs-on: ubuntu-24.04 + container: + image: thesofproject/zephyr-lite:v0.28.4 strategy: fail-fast: false @@ -25,43 +34,39 @@ jobs: platform: [tgl, mtl, lnl] steps: - - name: free space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - - name: git clone sparse analyzer uses: actions/checkout@v4 with: repository: thesofproject/sparse fetch-depth: 0 filter: 'tree:0' - path: workspace/sparse + path: sparse # As of its 2023 commit 98b203419679, sparse-llvm.c uses symbols # (LLVMConstGEP, LLVMBuildLoad, LLVMBuildCall,...) which are: # - -Wdeprecated in LLVM v14 # - Removed in LLVM v16 - name: build sparse analyzer - run: cd workspace/sparse && make -j4 # HAVE_LLVM=no + working-directory: sparse + run: | + make -j4 # HAVE_LLVM=no - name: git clone sof uses: actions/checkout@v4 with: - path: ./workspace/sof + path: sof fetch-depth: 0 # fix git describe filter: 'tree:0' - - name: west clones - run: pip3 install west && cd workspace/sof/ && west init -l && - west update --narrow --fetch-opt=--depth=5 + - name: west update + working-directory: sof + run: | + west init -l + west update --narrow --fetch-opt=--depth=5 - # Not strictly necessary but saves a lot of scrolling in the next step - # Caching a 12G image is unfortunately not possible: - # https://github.com/ScribeMD/docker-cache/issues/304 - # For faster builds we would have to pay for some persistent runners. - - name: Download docker image && ls /opt/toolchains/ - run: cd workspace && ./sof/zephyr/docker-run.sh ls -l /opt/toolchains/ + - name: print all available sdks in /opt/toolchains/ + run: | + ls -l /opt/toolchains/ # --pristine is important to reproduce _warnings_. It makes no # difference for github but it's useful for anyone trying to @@ -69,13 +74,11 @@ jobs: # "sparse" is currently incompatible with PICOLIBC (the new Zephyr default), # see https://github.com/zephyrproject-rtos/zephyr/issues/63003 - name: analyze zephyr - working-directory: ./workspace run: | - ./sof/zephyr/docker-run.sh \ - ./sof/zephyr/docker-build.sh ${{ matrix.platform }} \ - --cmake-args=-DZEPHYR_SCA_VARIANT=sparse --cmake-args=-DCONFIG_LOG_USE_VLA=n \ - --cmake-args=-DCONFIG_MINIMAL_LIBC=y \ - --pristine 2>&1 | tee _.log + ./sof/zephyr/docker-build.sh ${{ matrix.platform }} \ + --cmake-args=-DZEPHYR_SCA_VARIANT=sparse --cmake-args=-DCONFIG_LOG_USE_VLA=n \ + --cmake-args=-DCONFIG_MINIMAL_LIBC=y \ + --pristine 2>&1 | tee _.log - printf '\n\n\t\t\t ---- Messages below are treated as sparse errors --- \n\n\n' - (set -x; ./sof/scripts/parse_sparse_output.sh ${{ matrix.platforms.platform }} <_.log) + printf '\n\n\t\t\t ---- Messages below are treated as sparse errors --- \n\n\n' + (set -x; ./sof/scripts/parse_sparse_output.sh ${{ matrix.platforms.platform }} <_.log) diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml index d02d67861560..06b6cc3d7ee9 100644 --- a/.github/workflows/zephyr.yml +++ b/.github/workflows/zephyr.yml @@ -15,18 +15,22 @@ concurrency: cancel-in-progress: true jobs: - manifest-check: runs-on: ubuntu-latest + defaults: + run: + shell: bash + container: + image: thesofproject/zephyr-lite:v0.28.4 steps: - uses: actions/checkout@v4 with: - path: ./workspace/sof + path: sof filter: 'tree:0' - name: plain west update + working-directory: sof run: | - : This plain 'west update' does not provide 100% certainty that : all the manifest revisions make sense but it is quick and : will catch many revision problems. Other jobs typically @@ -35,8 +39,6 @@ jobs: : is useful for testing unmerged Zephyr commits but risks : accepting "invalid" ones, this will not. - pip3 install west - cd workspace/sof/ west init -l west update --fetch-opt=--filter=tree:0 @@ -45,9 +47,8 @@ jobs: # XTOS submodules and... temporarily break every CI, which is why # it hasn't been done yet. - name: git submodules consistency + working-directory: sof run: | - - cd workspace/sof git submodule update --init --recursive west update @@ -66,40 +67,42 @@ jobs: # job will be disappear, folded back in the regular build-* jobs below. LP64-WIP: runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + container: + image: thesofproject/zephyr-lite:v0.28.4 steps: - uses: actions/checkout@v4 with: - path: ./workspace/sof + path: sof filter: 'tree:0' - - name: free space + - name: west update + working-directory: sof run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - - - name: west clones - run: pip3 install west && cd workspace/sof/ && west init -l && - west update --narrow --fetch-opt=--filter=tree:0 + west init -l + west update --narrow --fetch-opt=--filter=tree:0 - # Not strictly necessary but saves a lot of scrolling in the next step - # Caching a 12G image is unfortunately not possible: - # https://github.com/ScribeMD/docker-cache/issues/304 - # For faster builds we would have to pay for some persistent runners. - - name: Download docker image && ls /opt/toolchains/ - run: cd workspace && ./sof/zephyr/docker-run.sh ls -l /opt/toolchains/ + - name: print all available sdks in /opt/toolchains/ + run: | + ls -l /opt/toolchains/ - name: 64 bits build run: | - cd workspace && ./sof/zephyr/docker-run.sh /bin/sh -c \ - 'ln -s /opt/toolchains/zephyr-sdk-* ~/; - west build --board imx93_evk/mimx9352/a55 sof/app \ - -- -DEXTRA_CFLAGS=-Werror -DEXTRA_CXXFLAGS=-Werror \ - -DEXTRA_AFLAGS=-Werror' - + ln -s /opt/toolchains/zephyr-sdk-* ~/ + west build --board imx93_evk/mimx9352/a55 sof/app \ + -- -DEXTRA_CFLAGS=-Werror -DEXTRA_CXXFLAGS=-Werror \ + -DEXTRA_AFLAGS=-Werror build-linux: runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + container: + image: thesofproject/zephyr-lite:v0.28.4 strategy: fail-fast: false matrix: @@ -113,13 +116,16 @@ jobs: # many lines. Pay attention to COMMAS. IPC_platforms: [ # - IPC3 default - imx8 imx8x imx8m imx8ulp, + imx8 imx8x, + imx8m imx8ulp, # - IPC4 default, released - mtl lnl, + mtl, + lnl, # active development ptl, # Temporary testbed for Zephyr development. - tgl tgl-h, + tgl, + tgl-h ] build_opts: [""] # Sparse matrices are complicated, you must read this page slowly: @@ -130,10 +136,12 @@ jobs: zephyr_revision: mnfst IPC_platforms: lnl - # This is "duplication of effort" but it makes sure no one - # breaks --all, see for instance #9262 and previous commit. + # Due to GitHub size limitations we can't afford to run --all and + # duplicate builds already built in previous steps. + # This will now build any platform that would've run with --all that + # isn't already built above. - zephyr_revision: mnfst - IPC_platforms: --all + IPC_platforms: wcl imx95 steps: - uses: actions/checkout@v4 @@ -143,20 +151,15 @@ jobs: with: fetch-depth: 0 filter: 'tree:0' - path: ./workspace/sof + path: sof - - name: free space + - name: west update + working-directory: sof run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - - - name: west clones - - run: pip3 install west && cd workspace/sof/ && west init -l && - time west update --narrow --fetch-opt=--filter=tree:0 + west init -l + west update --narrow --fetch-opt=--filter=tree:0 - name: select zephyr revision - working-directory: ${{ github.workspace }}/workspace run: | if [ 'mnfst' = '${{ matrix.zephyr_revision }}' ]; then rem_rev=$(git -C zephyr rev-parse HEAD) @@ -175,7 +178,7 @@ jobs: # Get some tags to fix `git describe` hence BUILD_VERSION, etc. # Keep in sync with build-windows below - name: Fetch tags for git describe - working-directory: ${{ github.workspace }}/workspace/zephyr + working-directory: zephyr run: | # Because we used git tricks to speed things up, we now have two git # problems: @@ -205,25 +208,19 @@ jobs: git describe --long --always --dirty git describe --long --always --dirty --tags - # Not strictly necessary but saves a lot of scrolling in the next step - # Caching a 12G image is unfortunately not possible: - # https://github.com/ScribeMD/docker-cache/issues/304 - # For faster builds we would have to pay for some persistent runners. - - name: Download docker image && ls /opt/toolchains/ - run: cd workspace && ./sof/zephyr/docker-run.sh ls -l /opt/toolchains/ + - name: print all available sdks in /opt/toolchains/ + run: | + ls -l /opt/toolchains/ - # https://github.com/zephyrproject-rtos/docker-image - # Note: env variables can be passed to the container with - # -e https_proxy=... - name: build - run: cd workspace && ./sof/zephyr/docker-run.sh - ./sof/zephyr/docker-build.sh --cmake-args=-DEXTRA_CFLAGS=-Werror - --cmake-args=-DEXTRA_CXXFLAGS=-Werror - --cmake-args=-DEXTRA_AFLAGS='-Werror -Wa,--fatal-warnings' - --cmake-args=--warn-uninitialized - --overlay=sof/app/configs/repro-build.conf - --no-tarball - ${{ matrix.build_opts }} ${{ matrix.IPC_platforms }} + run: | + ./sof/zephyr/docker-build.sh --cmake-args=-DEXTRA_CFLAGS=-Werror \ + --cmake-args=-DEXTRA_CXXFLAGS=-Werror \ + --cmake-args=-DEXTRA_AFLAGS='-Werror -Wa,--fatal-warnings' \ + --cmake-args=--warn-uninitialized \ + --overlay=sof/app/configs/repro-build.conf \ + --no-tarball \ + ${{ matrix.build_opts }} ${{ matrix.IPC_platforms }} - name: Upload build artifacts uses: actions/upload-artifact@v4 @@ -232,8 +229,8 @@ jobs: name: linux-build ${{ matrix.build_opts }} ${{ matrix.IPC_platforms }} if-no-files-found: error path: | - ${{ github.workspace }}/workspace/build-sof-staging - ${{ github.workspace }}/workspace/**/compile_commands.json + build-sof-staging + ./**/compile_commands.json build-windows: runs-on: windows-latest @@ -244,13 +241,16 @@ jobs: # many lines. Pay attention to COMMAS. platforms: [ # - IPC3 default - imx8 imx8x imx8m imx8ulp, + imx8 imx8x, + imx8m imx8ulp, # - IPC4 default, released - mtl lnl, + mtl, + lnl, # active development ptl, # legacy - tgl tgl-h, + tgl, + tgl-h ] build_opts: [""] # Sparse matrices are complicated, see comments on Linux matrix above. @@ -285,12 +285,12 @@ jobs: # Keep this SDK version identical to the one in # sof/zephyr/docker-run.sh - - name: Cache Zephyr SDK 0.17.0 + - name: Cache Zephyr SDK 0.17.4 id: cache-zephyr-sdk uses: actions/cache@v4 with: - path: zephyr-sdk-0.17.0_windows-x86_64.7z - key: ${{ runner.os }}-cache-zephyr-sdk-0-17-0 + path: zephyr-sdk-0.17.4_windows-x86_64.7z + key: ${{ runner.os }}-cache-zephyr-sdk-0-17-4 # Wget is needed by Zephyr SDK setup.cmd installation script - name: Download wget @@ -298,11 +298,11 @@ jobs: run: | curl -L -O http://downloads.sourceforge.net/gnuwin32/wget-1.11.4-1-bin.zip - - name: Download Zephyr SDK 0.17.0 + - name: Download Zephyr SDK 0.17.4 if: ${{ steps.cache-zephyr-sdk.outputs.cache-hit != 'true' }} run: | # yamllint disable-line rule:line-length curl -L -O ` - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.17.0/zephyr-sdk-0.17.0_windows-x86_64.7z + https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.17.4/zephyr-sdk-0.17.4_windows-x86_64.7z # Unzips every .zip package to directory matching its name without extension - name: Unzip downloaded packages @@ -325,7 +325,7 @@ jobs: # setup.cmd may not be called in from msys shell as it does not parse # forward slash script input arguments correctly. - name: Install Zephyr SDK - run: zephyr-sdk-0.17.0_windows-x86_64/zephyr-sdk-0.17.0/setup.cmd /t all /h /c + run: zephyr-sdk-0.17.4_windows-x86_64/zephyr-sdk-0.17.4/setup.cmd /t all /h /c - name: Setup Python uses: actions/setup-python@v5 @@ -382,6 +382,12 @@ jobs: choco install ninja ninja.exe --version + # Install GPERF for Windows + - name: Install gperf + run: | + choco install gperf + gperf --version + # MSYS2 provides gcc x64_86 toolchain & openssl # Installs in D:/a/_temp/msys64 # @@ -462,7 +468,8 @@ jobs: for regdir in 'linux-build *-d *.*' \ 'linux-build *.*lnl.*' \ 'windows-build *.*mtl.*' \ - 'windows-build *tgl tgl-h'; do + 'windows-build *tgl-h' \ + 'windows-build *tgl'; do find . -maxdepth 1 | grep -q "\./${regdir}\$" || { >&2 printf 'Missing %s\n' "${regdir}"; exit 1; } done diff --git a/app/Kconfig b/app/Kconfig index e1f5bd67295d..56ada456367e 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -4,6 +4,11 @@ config SCHED_CPU_MASK_PIN_ONLY config SMP_BOOT_DELAY default y if SMP +# Allow compiler to determine whether to generate FLIX instructions. +choice COMPILER_CODEGEN_VLIW + default COMPILER_CODEGEN_VLIW_AUTO if "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "xt-clang" +endchoice + source "Kconfig.zephyr" if SOC_FAMILY_INTEL_ADSP diff --git a/app/boards/intel_adsp/Kconfig.defconfig b/app/boards/intel_adsp/Kconfig.defconfig index a2ba2db15db6..9635b4395011 100644 --- a/app/boards/intel_adsp/Kconfig.defconfig +++ b/app/boards/intel_adsp/Kconfig.defconfig @@ -164,3 +164,16 @@ config LOG_FUNC_NAME_PREFIX_DBG config LOG_TIMESTAMP_64BIT default y + +# Zephyr / debugging +# ---------------------------------------- + +config ZTEST + default SOF_BOOT_TEST_SUPPORTED && SOF_BOOT_TEST_ALLOWED + +# Zephyr / debug slot manager +# ---------------------------------------- + +config INTEL_ADSP_DEBUG_SLOT_MANAGER + default y + diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 4ebf4498375d..e95b18d97169 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -15,6 +15,7 @@ CONFIG_COMP_MFCC=y CONFIG_COMP_MULTIBAND_DRC=y CONFIG_FORMAT_CONVERT_HIFI3=n CONFIG_SAMPLE_KEYPHRASE=y +CONFIG_COMP_STFT_PROCESS=y # SOF / audio modules / mocks # This mock is part of official sof-bin releases because the CI that @@ -34,6 +35,7 @@ CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y CONFIG_ZEPHYR_TWB_SCHEDULER=y CONFIG_COLD_STORE_EXECUTE_DRAM=y +CONFIG_SOF_BOOT_TEST_SUPPORTED=n # SOF / loadable modules CONFIG_INTEL_MODULES=y @@ -77,10 +79,10 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 CONFIG_ADSP_IDLE_CLOCK_GATING=y CONFIG_ADSP_IMR_CONTEXT_SAVE=n CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_BACKEND_SOF_PROBE=n -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_WINSTREAM_CONSOLE=n CONFIG_LOG_FLUSH_SLEEP_US=5000 diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index bc716dbf293d..beb441d6e6c6 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -11,6 +11,7 @@ CONFIG_COMP_TESTER=m CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y CONFIG_FORMAT_CONVERT_HIFI3=n CONFIG_SAMPLE_KEYPHRASE=y +CONFIG_COMP_STFT_PROCESS=y # SOF / infrastructure CONFIG_AMS=y @@ -56,9 +57,9 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 CONFIG_ADSP_IDLE_CLOCK_GATING=y CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_WINSTREAM_CONSOLE=n CONFIG_LOG_FLUSH_SLEEP_US=5000 diff --git a/app/boards/intel_adsp_ace30_ptl.conf b/app/boards/intel_adsp_ace30_ptl.conf index c8305fa33b35..12aa78162c06 100644 --- a/app/boards/intel_adsp_ace30_ptl.conf +++ b/app/boards/intel_adsp_ace30_ptl.conf @@ -14,6 +14,7 @@ CONFIG_FORMAT_CONVERT_HIFI3=n # tests it can't use extra CONFIGs. See #9410, #8722 and #9386 CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=m CONFIG_GOOGLE_RTC_AUDIO_PROCESSING_MOCK=y +CONFIG_COMP_STFT_PROCESS=y # SOF / infrastructure CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n @@ -53,14 +54,24 @@ CONFIG_DMA_DW_LLI_POOL_SIZE=50 CONFIG_MEMORY_WIN_2_SIZE=12288 CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT=2 +CONFIG_XTENSA_MMU_NUM_L2_TABLES=128 CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 # Zephyr / power settings CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_FLUSH_SLEEP_US=5000 -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_WINSTREAM_CONSOLE=n + +# Userspace options +CONFIG_USERSPACE=y +CONFIG_DYNAMIC_THREAD=y +CONFIG_DYNAMIC_THREAD_ALLOC=y +CONFIG_DYNAMIC_THREAD_PREFER_ALLOC=y +CONFIG_SOF_STACK_SIZE=8192 +CONFIG_SOF_USERSPACE_PROXY=y +CONFIG_MAX_THREAD_BYTES=3 diff --git a/app/boards/intel_adsp_ace30_wcl.conf b/app/boards/intel_adsp_ace30_wcl.conf index faa20dd97a9b..621eb719de9f 100644 --- a/app/boards/intel_adsp_ace30_wcl.conf +++ b/app/boards/intel_adsp_ace30_wcl.conf @@ -9,10 +9,20 @@ CONFIG_COMP_TESTER=m CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y CONFIG_FORMAT_CONVERT_HIFI3=n +# SOF / audio modules / mocks +# This mock is part of official sof-bin releases because the CI that +# tests it can't use extra CONFIGs. See #9410, #8722 and #9386 +CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=m +CONFIG_GOOGLE_RTC_AUDIO_PROCESSING_MOCK=y +CONFIG_COMP_STFT_PROCESS=y + # SOF / infrastructure CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n CONFIG_PROBE=y CONFIG_PROBE_DMA_MAX=2 +CONFIG_SOF_TELEMETRY=y +CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y +CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y CONFIG_COLD_STORE_EXECUTE_DRAM=y # SOF / loadable modules @@ -38,6 +48,7 @@ CONFIG_DAI_DMIC_HW_IOCLK=38400000 CONFIG_DAI_DMIC_HAS_OWNERSHIP=n CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC=y CONFIG_DMA_INTEL_ADSP_GPDMA=n +CONFIG_MEMORY_WIN_2_SIZE=12288 CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT=2 CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 @@ -45,9 +56,9 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 # Zephyr / power settings CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_FLUSH_SLEEP_US=5000 -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_WINSTREAM_CONSOLE=n diff --git a/app/boards/intel_adsp_ace40_nvl.conf b/app/boards/intel_adsp_ace40_nvl.conf index 55a6628959e1..75652f508d53 100644 --- a/app/boards/intel_adsp_ace40_nvl.conf +++ b/app/boards/intel_adsp_ace40_nvl.conf @@ -15,10 +15,14 @@ CONFIG_FORMAT_CONVERT_HIFI3=n # SOF / infrastructure CONFIG_PROBE=y CONFIG_PROBE_DMA_MAX=2 +CONFIG_COLD_STORE_EXECUTE_DRAM=y # SOF / loadable modules CONFIG_INTEL_MODULES=y CONFIG_LIBRARY_MANAGER=y +CONFIG_LIBRARY_BASE_ADDRESS=0xa0688000 +CONFIG_LIBRARY_BUILD_LIB=y +CONFIG_LIBRARY_DEFAULT_MODULAR=y # SOF / logging CONFIG_TRACE=n @@ -26,6 +30,10 @@ CONFIG_SOF_LOG_LEVEL_INF=y # Zephyr / OS features CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_LLEXT=y +CONFIG_LLEXT_STORAGE_WRITABLE=y +CONFIG_LLEXT_EXPERIMENTAL=y +CONFIG_MODULES=y # Zephyr / device drivers CONFIG_DAI_INIT_PRIORITY=70 @@ -34,6 +42,7 @@ CONFIG_DAI_DMIC_HAS_OWNERSHIP=n CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC=y CONFIG_DMA_INTEL_ADSP_GPDMA=n CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y +CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT=2 CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 # Zephyr / power settings @@ -41,7 +50,11 @@ CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_PM_POLICY_CUSTOM=y CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y CONFIG_SRAM_RETENTION_MODE=n +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_WINSTREAM_CONSOLE=n + +# Zephyr / debug: temporary, until fixed +CONFIG_GDBSTUB=n diff --git a/app/boards/intel_adsp_ace40_nvls.conf b/app/boards/intel_adsp_ace40_nvls.conf index 55a6628959e1..75652f508d53 100644 --- a/app/boards/intel_adsp_ace40_nvls.conf +++ b/app/boards/intel_adsp_ace40_nvls.conf @@ -15,10 +15,14 @@ CONFIG_FORMAT_CONVERT_HIFI3=n # SOF / infrastructure CONFIG_PROBE=y CONFIG_PROBE_DMA_MAX=2 +CONFIG_COLD_STORE_EXECUTE_DRAM=y # SOF / loadable modules CONFIG_INTEL_MODULES=y CONFIG_LIBRARY_MANAGER=y +CONFIG_LIBRARY_BASE_ADDRESS=0xa0688000 +CONFIG_LIBRARY_BUILD_LIB=y +CONFIG_LIBRARY_DEFAULT_MODULAR=y # SOF / logging CONFIG_TRACE=n @@ -26,6 +30,10 @@ CONFIG_SOF_LOG_LEVEL_INF=y # Zephyr / OS features CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_LLEXT=y +CONFIG_LLEXT_STORAGE_WRITABLE=y +CONFIG_LLEXT_EXPERIMENTAL=y +CONFIG_MODULES=y # Zephyr / device drivers CONFIG_DAI_INIT_PRIORITY=70 @@ -34,6 +42,7 @@ CONFIG_DAI_DMIC_HAS_OWNERSHIP=n CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC=y CONFIG_DMA_INTEL_ADSP_GPDMA=n CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y +CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT=2 CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 # Zephyr / power settings @@ -41,7 +50,11 @@ CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_PM_POLICY_CUSTOM=y CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y CONFIG_SRAM_RETENTION_MODE=n +CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_WINSTREAM_CONSOLE=n + +# Zephyr / debug: temporary, until fixed +CONFIG_GDBSTUB=n diff --git a/app/boards/intel_adsp_cavs25.conf b/app/boards/intel_adsp_cavs25.conf index 0d39b072324c..7cd938ec7ff8 100644 --- a/app/boards/intel_adsp_cavs25.conf +++ b/app/boards/intel_adsp_cavs25.conf @@ -53,6 +53,5 @@ CONFIG_LOG_FUNC_NAME_PREFIX_ERR=y CONFIG_LOG_FUNC_NAME_PREFIX_WRN=y CONFIG_LOG_FUNC_NAME_PREFIX_INF=y CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_LOG_TIMESTAMP_64BIT=y CONFIG_WINSTREAM_CONSOLE=n diff --git a/app/boards/intel_adsp_cavs25_tgph.conf b/app/boards/intel_adsp_cavs25_tgph.conf index 2d6ac891cbd0..0c1d1dab1ad6 100644 --- a/app/boards/intel_adsp_cavs25_tgph.conf +++ b/app/boards/intel_adsp_cavs25_tgph.conf @@ -55,6 +55,5 @@ CONFIG_LOG_FUNC_NAME_PREFIX_ERR=y CONFIG_LOG_FUNC_NAME_PREFIX_WRN=y CONFIG_LOG_FUNC_NAME_PREFIX_INF=y CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y -CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y CONFIG_LOG_TIMESTAMP_64BIT=y CONFIG_WINSTREAM_CONSOLE=n diff --git a/app/boards/mt8365_mt8365_adsp.conf b/app/boards/mt8365_mt8365_adsp.conf new file mode 100644 index 000000000000..7c9d3647e8cc --- /dev/null +++ b/app/boards/mt8365_mt8365_adsp.conf @@ -0,0 +1,10 @@ +# Boilerplate. Because the "Platform" is a kconfig "choice" (of which +# "MTK" is an member), it can't be selected automatically from other +# kconfigs, nor expressed as a default. Don't put anything else here. +# Board-level config goes in Zephyr (and ideally in DTS). App-level +# config goes in prj.conf. +CONFIG_MTK=y + +# Override project default setting so 1 millisecond is exactly +# represented by an integral number of ticks. +CONFIG_SYS_CLOCK_TICKS_PER_SEC=13000 \ No newline at end of file diff --git a/app/compr/README.txt b/app/compr/README.txt new file mode 100644 index 000000000000..a9c28957edbb --- /dev/null +++ b/app/compr/README.txt @@ -0,0 +1,37 @@ +Cadence Codec Configuration Overlays +===================================== + +This directory contains Kconfig overlay files for enabling Cadence codec support +in SOF firmware builds. + +Prerequisites +------------- +The Cadence codec libraries must be placed in the cadence_libs directory, one level +up from the SOF project directory: + sof/../cadence_libs/ + +Available Overlay Files +----------------------- +cadence.conf - Base Cadence codec module only (no individual codecs) +mp3.conf - MP3 decoder and encoder +aac.conf - AAC decoder +vorbis.conf - Vorbis decoder +all_codecs.conf - All supported codecs (MP3, AAC, Vorbis) + +Usage Examples +-------------- +Use with scripts/xtensa-build-zephyr.py via -o parameter: + +# Base module only (e.g., for Tiger Lake) +scripts/xtensa-build-zephyr.py tgl -o app/compr/cadence.conf + +# Single codec +scripts/xtensa-build-zephyr.py mtl -o app/compr/mp3.conf + +# Multiple codecs (use separate -o for each) +scripts/xtensa-build-zephyr.py mtl -o app/compr/mp3.conf -o app/compr/aac.conf + +# All codecs +scripts/xtensa-build-zephyr.py mtl -o app/compr/all_codecs.conf + +For more information about Cadence codecs, see the SOF documentation. diff --git a/app/compr/aac.conf b/app/compr/aac.conf new file mode 100644 index 000000000000..2adf1db86007 --- /dev/null +++ b/app/compr/aac.conf @@ -0,0 +1,4 @@ +# Cadence AAC decoder +CONFIG_CADENCE_CODEC=y +CONFIG_CADENCE_CODEC_AAC_DEC=y +CONFIG_CADENCE_CODEC_AAC_DEC_LIB="../cadence_libs/xa_aac_dec.a" diff --git a/app/compr/all_codecs.conf b/app/compr/all_codecs.conf new file mode 100644 index 000000000000..26b507f7f452 --- /dev/null +++ b/app/compr/all_codecs.conf @@ -0,0 +1,11 @@ +# All Cadence codecs (MP3, AAC, Vorbis) +CONFIG_CADENCE_CODEC=y +CONFIG_CADENCE_CODEC_MP3_DEC=y +CONFIG_CADENCE_CODEC_MP3_DEC_LIB="../cadence_libs/xa_mp3_dec.a" +CONFIG_CADENCE_CODEC_MP3_ENC=y +CONFIG_CADENCE_CODEC_MP3_ENC_LIB="../cadence_libs/xa_mp3_enc.a" +CONFIG_CADENCE_CODEC_AAC_DEC=y +CONFIG_CADENCE_CODEC_AAC_DEC_LIB="../cadence_libs/xa_aac_dec.a" +CONFIG_CADENCE_CODEC_VORBIS_DEC=y +CONFIG_CADENCE_CODEC_VORBIS_DEC_LIB="../cadence_libs/xa_vorbis_dec.a" + diff --git a/app/compr/cadence.conf b/app/compr/cadence.conf new file mode 100644 index 000000000000..9223140cab73 --- /dev/null +++ b/app/compr/cadence.conf @@ -0,0 +1,2 @@ +# Cadence codec module base support +CONFIG_CADENCE_CODEC=y diff --git a/app/compr/mp3.conf b/app/compr/mp3.conf new file mode 100644 index 000000000000..968f97295f57 --- /dev/null +++ b/app/compr/mp3.conf @@ -0,0 +1,6 @@ +# Cadence MP3 decoder and encoder +CONFIG_CADENCE_CODEC=y +CONFIG_CADENCE_CODEC_MP3_DEC=y +CONFIG_CADENCE_CODEC_MP3_DEC_LIB="../cadence_libs/xa_mp3_dec.a" +CONFIG_CADENCE_CODEC_MP3_ENC=y +CONFIG_CADENCE_CODEC_MP3_ENC_LIB="../cadence_libs/xa_mp3_enc.a" diff --git a/app/compr/vorbis.conf b/app/compr/vorbis.conf new file mode 100644 index 000000000000..064ac71b6616 --- /dev/null +++ b/app/compr/vorbis.conf @@ -0,0 +1,4 @@ +# Cadence Vorbis decoder +CONFIG_CADENCE_CODEC=y +CONFIG_CADENCE_CODEC_VORBIS_DEC=y +CONFIG_CADENCE_CODEC_VORBIS_DEC_LIB="../cadence_libs/xa_vorbis_dec.a" diff --git a/app/debug_overlay.conf b/app/debug_overlay.conf index 650b3c09f7f2..914210d4184d 100644 --- a/app/debug_overlay.conf +++ b/app/debug_overlay.conf @@ -1,9 +1,10 @@ CONFIG_DEBUG=y CONFIG_ASSERT=y -# Disabled until DSP panic #8621 is fixed -# CONFIG_ZTEST=y -# CONFIG_SOF_BOOT_TEST=y +CONFIG_ZTEST_NO_YIELD=n +CONFIG_ZTEST_SUMMARY=n +CONFIG_SOF_BOOT_TEST_ALLOWED=y +CONFIG_TEST_EXTRA_STACK_SIZE=7168 CONFIG_DAI_VERBOSE_GLITCH_WARNINGS=y diff --git a/app/debug_stream_overlay.conf b/app/debug_stream_overlay.conf index 0195e5070b33..e3cb6834320e 100644 --- a/app/debug_stream_overlay.conf +++ b/app/debug_stream_overlay.conf @@ -1,5 +1,7 @@ # Enable debug-stream protocol CONFIG_SOF_DEBUG_STREAM_SLOT=y +# Enable text message sending with ds_msg() +CONFIG_SOF_DEBUG_STREAM_TEXT_MSG=y # Add thread_info-client for debug stream CONFIG_SOF_DEBUG_STREAM_THREAD_INFO=y # Zephyr option for storing human readable thread names diff --git a/app/os_linux_overlay.conf b/app/os_linux_overlay.conf index a1399d4ebe2c..e862a1cfdcc8 100644 --- a/app/os_linux_overlay.conf +++ b/app/os_linux_overlay.conf @@ -6,3 +6,4 @@ # SOF Linux driver does not require FW to retain its # state, so context save can be disabled CONFIG_ADSP_IMR_CONTEXT_SAVE=n +CONFIG_SOF_USERSPACE_PROXY=n diff --git a/app/overlays/mtl/dax_overlay.conf b/app/overlays/mtl/dax_overlay.conf new file mode 100644 index 000000000000..f73f79addf32 --- /dev/null +++ b/app/overlays/mtl/dax_overlay.conf @@ -0,0 +1,11 @@ +CONFIG_COMP_MODULE_ADAPTER=y +CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING=y +CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK=n +CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n +CONFIG_SOF_STACK_SIZE=8192 + +# LLEXT +CONFIG_LLEXT_HEAP_SIZE=32 +# Disabled due to issues encountered on the MTL platform. +# See https://github.com/thesofproject/sof/issues/10370 +CONFIG_LLEXT_EXPERIMENTAL=n diff --git a/app/overlays/ptl/dax_overlay.conf b/app/overlays/ptl/dax_overlay.conf new file mode 100644 index 000000000000..9211e845cc36 --- /dev/null +++ b/app/overlays/ptl/dax_overlay.conf @@ -0,0 +1,8 @@ +CONFIG_COMP_MODULE_ADAPTER=y +CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING=y +CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK=n +CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n +CONFIG_SOF_STACK_SIZE=8192 + +# LLEXT +CONFIG_LLEXT_HEAP_SIZE=32 diff --git a/app/prj.conf b/app/prj.conf index e072f1df2fd2..260488e7852b 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -1,4 +1,3 @@ -CONFIG_SOF=y CONFIG_BUILD_OUTPUT_BIN=n # The additional stripped .elf files are deterministic. @@ -30,6 +29,8 @@ CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 CONFIG_LOG_BUFFER_SIZE=4096 # Use stack that is sufficient for SOF backends CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=4096 +# Use Linux kernel style timestamp format +CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y # Requires heap_info() be implemented, but no Zephyr wrapper CONFIG_DEBUG_MEMORY_USAGE_SCAN=n diff --git a/app/src/main.c b/app/src/main.c index 0f5c1f84fe0e..30f755f6a9c6 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -54,7 +54,6 @@ static int sof_app_main(void) void test_main(void) { sof_app_main(); - k_sleep(K_FOREVER); } #else int main(void) diff --git a/doc/sof.doxygen.in b/doc/sof.doxygen.in index bfbea17a7149..6379da500f11 100644 --- a/doc/sof.doxygen.in +++ b/doc/sof.doxygen.in @@ -40,3 +40,4 @@ TYPEDEF_HIDES_STRUCT = YES #FILTER_SOURCE_FILES = YES HTML_TIMESTAMP = NO +WARN_AS_ERROR = NO diff --git a/posix/include/rtos/alloc.h b/posix/include/rtos/alloc.h index 7927f17394e5..b8efac0d3112 100644 --- a/posix/include/rtos/alloc.h +++ b/posix/include/rtos/alloc.h @@ -38,22 +38,24 @@ * the first two positions are reserved for SOF_BUF_ flags */ - /** \brief Indicates we should return DMA-able memory. */ + /** \brief Allocate DMA-able memory. */ #define SOF_MEM_FLAG_DMA BIT(2) -/** \brief Indicates that original content should not be copied by realloc. */ +/** \brief realloc() skips copying the original content. */ #define SOF_MEM_FLAG_NO_COPY BIT(3) -/** \brief Indicates that if we should return uncached address. */ +/** \brief Allocate uncached address. */ #define SOF_MEM_FLAG_COHERENT BIT(4) -/** \brief Indicates that if we should return L3 address. */ +/** \brief Allocate L3 address. */ #define SOF_MEM_FLAG_L3 BIT(5) -/** \brief Indicates that if we should return Low power memory address. */ +/** \brief Allocate Low power memory address. */ #define SOF_MEM_FLAG_LOW_POWER BIT(6) -/** \brief Indicates that if we should return kernel memory address. */ +/** \brief Allocate kernel memory address. */ #define SOF_MEM_FLAG_KERNEL BIT(7) -/** \brief Indicates that if we should return user memory address. */ +/** \brief Allocate user memory address. */ #define SOF_MEM_FLAG_USER BIT(8) -/** \brief Indicates that if we should return shared user memory address. */ +/** \brief Allocate shared user memory address. */ #define SOF_MEM_FLAG_USER_SHARED_BUFFER BIT(9) +/** \brief Use allocation method for large buffers. */ +#define SOF_MEM_FLAG_LARGE_BUFFER BIT(10) /** @} */ @@ -61,8 +63,15 @@ * Allocates memory block. * @param flags Flags, see SOF_MEM_FLAG_... * @param bytes Size in bytes. + * @param alignment Alignment in bytes. * @return Pointer to the allocated memory or NULL if failed. */ +void *rmalloc_align(uint32_t flags, size_t bytes, + uint32_t alignment); + +/** + * Similar to rmalloc_align(), but no alignment can be specified. + */ void *rmalloc(uint32_t flags, size_t bytes); /** @@ -124,6 +133,15 @@ void rfree(void *ptr); */ void *rzalloc_core_sys(int core, size_t bytes); +struct k_heap; +static inline void k_heap_init(struct k_heap *heap, void *mem, size_t bytes) +{ +} +void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, + size_t alignment); +void sof_heap_free(struct k_heap *heap, void *addr); +struct k_heap *sof_sys_heap_get(void); + /** * Calculates length of the null-terminated string. * @param s String. diff --git a/posix/include/rtos/kernel.h b/posix/include/rtos/kernel.h index 5921d86b0012..714fc6672a1d 100644 --- a/posix/include/rtos/kernel.h +++ b/posix/include/rtos/kernel.h @@ -43,4 +43,8 @@ static inline void k_usleep(int32_t us) wait_delay_us(us); } +struct k_heap { + int unused; +}; + #endif /* __POSIX_RTOS_KERNEL_H__ */ diff --git a/posix/include/rtos/userspace_helper.h b/posix/include/rtos/userspace_helper.h index dda440a33ac4..09a52b7804d5 100644 --- a/posix/include/rtos/userspace_helper.h +++ b/posix/include/rtos/userspace_helper.h @@ -26,7 +26,7 @@ struct sys_heap; /** * Initialize private processing module heap. * @param N/A. - * @return pointer to the sys_heap structure. + * @return pointer to the k_heap structure. * * @note * Function used only when CONFIG_USERSPACE is set. @@ -34,69 +34,12 @@ struct sys_heap; * that should be isolated. The heap helps to accumulate all dynamic allocations in single memory * region which is then added to modules memory domain. */ -static inline struct sys_heap *module_driver_heap_init(void) +static inline struct k_heap *module_driver_heap_init(void) { return NULL; } - #endif -/** - * Allocates memory block from private module sys_heap if exists, otherwise call rballoc_align(). - * @param sys_heap - pointer to the sys_heap structure - * @param flags - Flags, see SOF_MEM_FLAG_... - * @param bytes - Size in bytes. - * @param alignment - Alignment in bytes. - * @return Pointer to the allocated memory or NULL if failed. - * - * @note When CONFIG_USERSPACE not set function calls rballoc_align() - */ -static inline void *module_driver_heap_aligned_alloc(struct sys_heap *mod_drv_heap, uint32_t flags, - size_t bytes, uint32_t align) -{ - return rballoc_align(flags, bytes, align); -} - -/** - * Allocates memory block from private module sys_heap if exists, otherwise call rmalloc. - * @param sys_heap - pointer to the sys_heap structure - * @param flags - Flags, see SOF_MEM_FLAG_... - * @param bytes - Size in bytes. - * @return - Pointer to the allocated memory or NULL if failed. - * - * * @note When CONFIG_USERSPACE not set function calls rmalloc() - */ -static inline void *module_driver_heap_rmalloc(struct sys_heap *mod_drv_heap, uint32_t flags, - size_t bytes) -{ - return rmalloc(flags, bytes); -} - -/** - * Similar to user_rmalloc(), guarantees that returned block is zeroed. - * - * @note When CONFIG_USERSPACE not set function calls rzalloc() - */ -static inline void *module_driver_heap_rzalloc(struct sys_heap *mod_drv_heap, uint32_t flags, - size_t bytes) -{ - return rzalloc(flags, bytes); -} - -/** - * Frees the memory block from private module sys_heap if exists. Otherwise call rfree. - * @param ptr Pointer to the memory block. - * - * @note User should take care to not free memory allocated from sys_heap - * with module_driver_heap set to NULL. It will cause exception. - * - * When CONFIG_USERSPACE not set function calls rfree() - */ -static inline void module_driver_heap_free(struct sys_heap *mod_drv_heap, void *mem) -{ - rfree(mem); -} - /** * Free private processing module heap. * @param sys_heap pointer to the sys_heap structure. @@ -105,7 +48,7 @@ static inline void module_driver_heap_free(struct sys_heap *mod_drv_heap, void * * Function used only when CONFIG_USERSPACE is set. * Frees private module heap. */ -static inline void module_driver_heap_remove(struct sys_heap *mod_drv_heap) +static inline void module_driver_heap_remove(struct k_heap *mod_drv_heap) { } #endif /* __RTOS_USERSPACE_HELPER_H__ */ diff --git a/scripts/docker_build/zephyr_lite/Dockerfile b/scripts/docker_build/zephyr_lite/Dockerfile index 0c52b1f668f4..fb891468e5e9 100644 --- a/scripts/docker_build/zephyr_lite/Dockerfile +++ b/scripts/docker_build/zephyr_lite/Dockerfile @@ -2,36 +2,26 @@ # Copyright(c) 2025 Intel Corporation. All rights reserved. # Use zephyr-build as base image -FROM ghcr.io/zephyrproject-rtos/zephyr-build:v0.27.4 as base +FROM ghcr.io/zephyrproject-rtos/zephyr-build:v0.28.4 as base # Remove additional toolchains. # As this is not ideal solution there is a plan to build docker image without zephyr-build as the base -# and install only needeed toolchains in the future. -RUN cd /opt/toolchains/zephyr-sdk-0.17.0 && \ - sudo rm -rvf arc* \ +# and install only needed toolchains in the future. +USER root + +RUN cd /opt/toolchains/zephyr-sdk-0.17.4 && \ + rm -rvf arc* \ micro* \ mips* \ nios* \ risc* \ sparc* \ + sysroots \ x86* \ xtensa-espressif* \ xtensa-sample* \ xtensa-dc233c* -# Some of tests require python 3.12 - instll it from source -RUN cd /tmp && wget -q --show-progress --progress=bar:force:noscroll --no-check-certificate https://www.python.org/ftp/python/3.12.9/Python-3.12.9.tgz && \ - tar -xf Python-3.12.9.tgz && \ - cd Python-3.12.9 && \ - ./configure && \ - sudo make -j$(nproc) && \ - sudo make install && \ - sudo rm -rf /tmp/Python-3* - -# Reinstall python3.10 packages with python3.12 -RUN python3.10 -m pip freeze > /tmp/python3.10.pip.txt && \ - cat /tmp/python3.10.pip.txt | xargs -n 1 python3.12 -m pip install || true - # Use ubuntu24.04 as base for zephyr-lite FROM ubuntu:24.04 as zephyr-lite @@ -39,9 +29,11 @@ FROM ubuntu:24.04 as zephyr-lite # /opt for toolchains and sdk # /usr for binaries and libs # /home for libs installed in .local +# /etc/ssl for ssl certs for python packages COPY --from=base /opt /opt COPY --from=base /usr /usr COPY --from=base /home /home +COPY --from=base /etc/ssl /etc/ssl USER root @@ -49,10 +41,17 @@ USER root # Add user to dialout and sudo group RUN useradd -ms /bin/bash user && \ chown -R user:user /home/user && \ + chown -R user:user /opt/python && \ usermod -a -G dialout,sudo user USER user +# Install cmake and jsonschema in venv +RUN /opt/python/venv/bin/pip install 'cmake>=3.21' jsonschema + # Set zephyr env variables -ENV ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-0.17.0 +ENV PATH="/opt/python/venv/bin/:$PATH" +ENV ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-0.17.4 ENV ZEPHYR_TOOLCHAIN_VARIANT=zephyr + +CMD ["/bin/bash", "-l"] diff --git a/scripts/set_xtensa_params.sh b/scripts/set_xtensa_params.sh index 92e4d7d384a6..4bdaf93c809d 100644 --- a/scripts/set_xtensa_params.sh +++ b/scripts/set_xtensa_params.sh @@ -66,6 +66,11 @@ case "$platform" in XTENSA_CORE="ace30_LX7HiFi4_PIF" TOOLCHAIN_VER="RI-2022.10-linux" ;; + nvl) + PLATFORM="$platform" + XTENSA_CORE="ace4px_HiFi5MMU_PIF_nlib" + TOOLCHAIN_VER="RI-2022.10-linux" + ;; # NXP imx8) @@ -153,7 +158,7 @@ esac # Pre-zephyr "XTOS" build, testbench,... case "$platform" in - mtl|lnl|ptl|acp_7_0|mt8196) + mtl|lnl|ptl|acp_7_0|mt8196|nvl) SOF_CC_BASE='clang';; *) SOF_CC_BASE='xcc';; diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index 40931ba6623a..7610f81c1b81 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -145,6 +145,11 @@ class PlatformConfig: f"RJ-2024.3{xtensa_tools_version_postfix}", "HiFi5_MPU_lock_2023_11", ), + "mt8365" : PlatformConfig( + "mtk", "mt8365/mt8365/adsp", + f"RJ-2024.3{xtensa_tools_version_postfix}", + "hifi4_Aquila_E2_PROD", + ), } # These can all be built out of the box. --all builds all these. @@ -688,9 +693,13 @@ def clean_staging(platform): def rimage_west_configuration(platform_dict, dest_dir): """Configure rimage in a new file `dest_dir/westconfig.ini`, starting from the workspace .west/config. - Returns a tuple (west ConfigFile, pathlib.Path to that new file). + Returns a tuple: (west.configuration.Configuration, pathlib.Path to that new file). """ + # This complex and painful saving and copying can be dropped and + # greatly simplified once any of these alternatives gets finally + # implemented in `west config`: + # https://github.com/zephyrproject-rtos/west/issues/429 or 849, 867,.. saved_local_var = os.environ.get('WEST_CONFIG_LOCAL') workspace_west_config_path = os.environ.get('WEST_CONFIG_LOCAL', str(west_top / ".west" / "config")) @@ -1288,7 +1297,7 @@ def gzip_compress(fname, gzdst=None): RI_INFO_UNSUPPORTED += ['imx8', 'imx8x', 'imx8m', 'imx8ulp', 'imx95'] RI_INFO_UNSUPPORTED += ['rn', 'acp_6_0'] -RI_INFO_UNSUPPORTED += ['mt8186', 'mt8188', 'mt8195', 'mt8196'] +RI_INFO_UNSUPPORTED += ['mt8186', 'mt8188', 'mt8195', 'mt8196', 'mt8365'] # For temporary workarounds. Unlike _UNSUPPORTED above, the platforms below will print a warning. RI_INFO_FIXME = [ ] diff --git a/src/arch/host/Kconfig b/src/arch/host/Kconfig deleted file mode 100644 index de92f43a868c..000000000000 --- a/src/arch/host/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -# Host architecture configs - -config CORE_COUNT - int - default 1 - help - Number of used cores diff --git a/src/arch/host/configs/library_defconfig b/src/arch/host/configs/library_defconfig index 5c1ffe029cd6..28c486bec58d 100644 --- a/src/arch/host/configs/library_defconfig +++ b/src/arch/host/configs/library_defconfig @@ -2,6 +2,7 @@ CONFIG_COMP_ARIA=y CONFIG_COMP_ASRC=y CONFIG_COMP_CROSSOVER=y CONFIG_COMP_DCBLOCK=y +CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING=y CONFIG_COMP_DRC=y CONFIG_COMP_FIR=y CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=y @@ -18,8 +19,10 @@ CONFIG_COMP_SEL=y CONFIG_COMP_SOUND_DOSE=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y +CONFIG_COMP_STFT_PROCESS=y CONFIG_COMP_STUBS=y CONFIG_COMP_TDFB=y +CONFIG_COMP_TONE=y CONFIG_COMP_VOLUME=y CONFIG_COMP_VOLUME_LINEAR_RAMP=y CONFIG_COMP_VOLUME_WINDOWS_FADE=y diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index d9de3c578d8e..29e602871af7 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -86,6 +86,9 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) if(CONFIG_COMP_SRC) add_subdirectory(src) endif() + if(CONFIG_COMP_STFT_PROCESS) + add_subdirectory(stft_process) + endif() if(CONFIG_COMP_TDFB) add_subdirectory(tdfb) endif() @@ -121,9 +124,7 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) add_subdirectory(mic_privacy_manager) endif() if(CONFIG_COMP_TONE) - add_local_sources(sof - tone.c - ) + add_subdirectory(tone) endif() if(CONFIG_ZEPHYR_NATIVE_DRIVERS) list(APPEND base_files host-zephyr.c) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index 6bc1bd6ca012..1f7d362ffdc2 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -93,13 +93,6 @@ config COMP_STUBS Select to force all 3P blocks to link against stubs rather than their libraries. This should only be used in testing environments like fuzzers or CI. -config COMP_TONE - bool "Tone component" - select CORDIC_FIXED - help - Select for Tone component. - Warning: This component is deprecated and will be removed from SOF v2.8. - config COMP_KPB bool "KPB component" default y @@ -151,9 +144,11 @@ rsource "selector/Kconfig" rsource "smart_amp/Kconfig" rsource "sound_dose/Kconfig" rsource "src/Kconfig" +rsource "stft_process/Kconfig" rsource "tdfb/Kconfig" rsource "template/Kconfig" rsource "tensorflow/Kconfig" +rsource "tone/Kconfig" rsource "up_down_mixer/Kconfig" rsource "volume/Kconfig" # --- End Kconfig Sources (alphabetical order) --- diff --git a/src/audio/aria/aria.c b/src/audio/aria/aria.c index ef9ced95adde..0c9ffee5dd39 100644 --- a/src/audio/aria/aria.c +++ b/src/audio/aria/aria.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -33,8 +32,6 @@ LOG_MODULE_REGISTER(aria, CONFIG_SOF_LOG_LEVEL); /* these ids aligns windows driver requirement to support windows driver */ SOF_DEFINE_REG_UUID(aria); -DECLARE_TR_CTX(aria_comp_tr, SOF_UUID(aria_uuid), LOG_LEVEL_INFO); - /** * \brief Aria gain index mapping table */ @@ -121,12 +118,12 @@ static int aria_init(struct processing_module *mod) size_t ibs, chc, sgs, sgc, req_mem, att; void *buf; - comp_info(dev, "aria_init()"); + comp_info(dev, "entry"); list_init(&dev->bsource_list); list_init(&dev->bsink_list); - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) { return -ENOMEM; } @@ -145,10 +142,10 @@ static int aria_init(struct processing_module *mod) } mod_data->private = cd; - buf = rballoc(SOF_MEM_FLAG_USER, req_mem); + buf = mod_balloc(mod, req_mem); if (!buf) { - rfree(cd); + mod_free(mod, cd); comp_err(dev, "allocation failed for size %d", req_mem); return -ENOMEM; } @@ -160,8 +157,8 @@ static int aria_free(struct processing_module *mod) { struct aria_data *cd = module_get_private_data(mod); - rfree(cd->data_addr); - rfree(cd); + mod_free(mod, cd->data_addr); + mod_free(mod, cd); return 0; } @@ -187,7 +184,7 @@ static int aria_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; struct aria_data *cd = module_get_private_data(mod); - comp_info(dev, "aria_prepare()"); + comp_info(dev, "entry"); source = comp_dev_get_first_data_producer(dev); sink = comp_dev_get_first_data_consumer(dev); @@ -228,7 +225,7 @@ static int aria_reset(struct processing_module *mod) struct aria_data *cd = module_get_private_data(mod); int idx; - comp_info(dev, "aria_reset()"); + comp_info(dev, "entry"); if (dev->state == COMP_STATE_ACTIVE) { comp_info(dev, "aria module is in active state. Ignore resetting"); @@ -255,7 +252,7 @@ static int aria_process(struct processing_module *mod, uint32_t copy_bytes; uint32_t frames = input_buffers[0].size; - comp_dbg(dev, "aria_copy()"); + comp_dbg(dev, "entry"); frames = MIN(frames, cd->smpl_group_cnt); @@ -282,7 +279,7 @@ static int aria_set_config(struct processing_module *mod, uint32_t param_id, struct aria_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_info(dev, "aria_set_config()"); + comp_info(dev, "entry"); if (param_id == ARIA_SET_ATTENUATION) { if (fragment_size != sizeof(uint32_t)) { comp_err(dev, "Illegal fragment_size = %d", fragment_size); @@ -327,6 +324,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(aria_comp_tr, SOF_UUID(aria_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(aria_interface, aria_uuid, aria_comp_tr); SOF_MODULE_INIT(aria, sys_comp_module_aria_interface_init); diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 281d2f82aaf7..e9c9e6e736d4 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -101,7 +100,7 @@ static void src_copy_s32(struct processing_module *mod, in_frames, &idx); if (ret) - comp_err(dev, "src_copy_s32(), error %d", ret); + comp_err(dev, "error %d", ret); buf = (int32_t *)cd->obuf[0]; n = out_frames * audio_stream_get_channels(sink); @@ -177,7 +176,7 @@ static void src_copy_s16(struct processing_module *mod, in_frames, &idx); if (ret) - comp_err(dev, "src_copy_s16(), error %d", ret); + comp_err(dev, "error %d", ret); buf = (int16_t *)cd->obuf[0]; n = out_frames * audio_stream_get_channels(sink); @@ -207,17 +206,17 @@ static int asrc_init(struct processing_module *mod) const ipc_asrc_cfg *ipc_asrc = (const ipc_asrc_cfg *)mod_data->cfg.init_data; struct comp_data *cd; - comp_info(dev, "asrc_init(), source_rate=%d, sink_rate=%d, asynchronous_mode=%d, operation_mode=%d", + comp_info(dev, "source_rate=%d, sink_rate=%d, asynchronous_mode=%d, operation_mode=%d", asrc_get_source_rate(ipc_asrc), asrc_get_sink_rate(ipc_asrc), asrc_get_asynchronous_mode(ipc_asrc), asrc_get_operation_mode(ipc_asrc)); /* validate init data - either SRC sink or source rate must be set */ if (asrc_get_source_rate(ipc_asrc) == 0 || asrc_get_sink_rate(ipc_asrc) == 0) { - comp_err(dev, "asrc_init(), sink or source rates are not set"); + comp_err(dev, "sink or source rates are not set"); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -242,7 +241,7 @@ static int asrc_init(struct processing_module *mod) return 0; } -static int asrc_initialize_buffers(struct asrc_farrow *src_obj) +static int asrc_initialize_buffers(struct processing_module *mod, struct asrc_farrow *src_obj) { int32_t *buf_32; int16_t *buf_16; @@ -261,7 +260,7 @@ static int asrc_initialize_buffers(struct asrc_farrow *src_obj) buffer_size = src_obj->buffer_length * sizeof(int32_t); for (ch = 0; ch < src_obj->num_channels; ch++) { - buf_32 = rzalloc(SOF_MEM_FLAG_USER, buffer_size); + buf_32 = mod_zalloc(mod, buffer_size); if (!buf_32) return -ENOMEM; @@ -272,7 +271,7 @@ static int asrc_initialize_buffers(struct asrc_farrow *src_obj) buffer_size = src_obj->buffer_length * sizeof(int16_t); for (ch = 0; ch < src_obj->num_channels; ch++) { - buf_16 = rzalloc(SOF_MEM_FLAG_USER, buffer_size); + buf_16 = mod_zalloc(mod, buffer_size); if (!buf_16) return -ENOMEM; @@ -284,7 +283,7 @@ static int asrc_initialize_buffers(struct asrc_farrow *src_obj) return 0; } -static void asrc_release_buffers(struct asrc_farrow *src_obj) +static void asrc_release_buffers(struct processing_module *mod, struct asrc_farrow *src_obj) { int32_t *buf_32; int16_t *buf_16; @@ -299,7 +298,7 @@ static void asrc_release_buffers(struct asrc_farrow *src_obj) if (buf_32) { src_obj->ring_buffers32[ch] = NULL; - rfree(buf_32); + mod_free(mod, buf_32); } } else @@ -308,7 +307,7 @@ static void asrc_release_buffers(struct asrc_farrow *src_obj) if (buf_16) { src_obj->ring_buffers16[ch] = NULL; - rfree(buf_16); + mod_free(mod, buf_16); } } } @@ -318,13 +317,13 @@ static int asrc_free(struct processing_module *mod) struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "asrc_free()"); + comp_dbg(dev, "entry"); - rfree(cd->buf); - asrc_release_buffers(cd->asrc_obj); - asrc_free_polyphase_filter(cd->asrc_obj); - rfree(cd->asrc_obj); - rfree(cd); + mod_free(mod, cd->buf); + asrc_release_buffers(mod, cd->asrc_obj); + asrc_free_polyphase_filter(mod, cd->asrc_obj); + mod_free(mod, cd->asrc_obj); + mod_free(mod, cd); return 0; } @@ -333,7 +332,7 @@ static int asrc_set_config(struct processing_module *mod, uint32_t config_id, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size) { - comp_err(mod->dev, "asrc_set_config()"); + comp_err(mod->dev, "entry"); return -EINVAL; } @@ -344,7 +343,7 @@ static int asrc_verify_params(struct processing_module *mod, struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "asrc_verify_params()"); + comp_dbg(dev, "entry"); /* check whether params->rate (received from driver) are equal * to asrc->source_rate (PLAYBACK) or asrc->sink_rate (CAPTURE) set @@ -387,7 +386,7 @@ static int asrc_params(struct processing_module *mod) struct comp_buffer *sourceb, *sinkb; int err; - comp_info(dev, "asrc_params()"); + comp_info(dev, "entry"); asrc_set_stream_params(cd, pcm_params); @@ -417,7 +416,7 @@ static int asrc_params(struct processing_module *mod) cd->sink_rate = audio_stream_get_rate(&sinkb->stream); if (!cd->sink_rate) { - comp_err(dev, "asrc_params(), zero sink rate"); + comp_err(dev, "zero sink rate"); return -EINVAL; } @@ -436,7 +435,7 @@ static int asrc_params(struct processing_module *mod) cd->sink_frames_max = cd->sink_frames + 10; cd->frames = MAX(cd->source_frames_max, cd->sink_frames_max); - comp_info(dev, "asrc_params(), source_rate=%u, sink_rate=%u, source_frames_max=%d, sink_frames_max=%d", + comp_info(dev, "source_rate=%u, sink_rate=%u, source_frames_max=%d, sink_frames_max=%d", cd->source_rate, cd->sink_rate, cd->source_frames_max, cd->sink_frames_max); @@ -507,7 +506,7 @@ static int asrc_trigger(struct processing_module *mod, int cmd) struct comp_dev *dev = mod->dev; int ret; - comp_info(dev, "asrc_trigger()"); + comp_info(dev, "entry"); /* Enable timestamping in pipeline DAI */ if (cmd == COMP_TRIGGER_START && cd->track_drift) { @@ -547,7 +546,7 @@ static int asrc_prepare(struct processing_module *mod, int ret; int i; - comp_info(dev, "asrc_prepare()"); + comp_info(dev, "entry"); ret = asrc_params(mod); if (ret < 0) @@ -581,12 +580,12 @@ static int asrc_prepare(struct processing_module *mod, /* validate */ if (!sink_period_bytes) { - comp_err(dev, "asrc_prepare(), sink_period_bytes = 0"); + comp_err(dev, "sink_period_bytes = 0"); ret = -EINVAL; goto err; } if (!source_period_bytes) { - comp_err(dev, "asrc_prepare(), source_period_bytes = 0"); + comp_err(dev, "source_period_bytes = 0"); ret = -EINVAL; goto err; } @@ -605,7 +604,7 @@ static int asrc_prepare(struct processing_module *mod, cd->asrc_func = src_copy_s32; break; default: - comp_err(dev, "asrc_prepare(), invalid frame format"); + comp_err(dev, "invalid frame format"); return -EINVAL; } @@ -614,11 +613,10 @@ static int asrc_prepare(struct processing_module *mod, cd->buf_size = (cd->source_frames_max + cd->sink_frames_max) * frame_bytes; - cd->buf = rzalloc(SOF_MEM_FLAG_USER, - cd->buf_size); + cd->buf = mod_zalloc(mod, cd->buf_size); if (!cd->buf) { cd->buf_size = 0; - comp_err(dev, "asrc_prepare(), allocation fail for size %d", + comp_err(dev, "allocation fail for size %d", cd->buf_size); ret = -ENOMEM; goto err; @@ -632,18 +630,17 @@ static int asrc_prepare(struct processing_module *mod, /* Get required size and allocate memory for ASRC */ sample_bits = sample_bytes * 8; - ret = asrc_get_required_size(dev, &cd->asrc_size, + ret = asrc_get_required_size(mod, &cd->asrc_size, audio_stream_get_channels(&sourceb->stream), sample_bits); if (ret) { - comp_err(dev, "asrc_prepare(), get_required_size_bytes failed"); + comp_err(dev, "get_required_size_bytes failed"); goto err_free_buf; } - cd->asrc_obj = rzalloc(SOF_MEM_FLAG_USER, - cd->asrc_size); + cd->asrc_obj = mod_zalloc(mod, cd->asrc_size); if (!cd->asrc_obj) { - comp_err(dev, "asrc_prepare(), allocation fail for size %d", + comp_err(dev, "allocation fail for size %d", cd->asrc_size); cd->asrc_size = 0; ret = -ENOMEM; @@ -659,7 +656,7 @@ static int asrc_prepare(struct processing_module *mod, fs_sec = cd->source_rate; } - ret = asrc_initialise(dev, cd->asrc_obj, audio_stream_get_channels(&sourceb->stream), + ret = asrc_initialise(mod, cd->asrc_obj, audio_stream_get_channels(&sourceb->stream), fs_prim, fs_sec, ASRC_IOF_INTERLEAVED, ASRC_IOF_INTERLEAVED, ASRC_BM_LINEAR, cd->frames, sample_bits, @@ -670,7 +667,7 @@ static int asrc_prepare(struct processing_module *mod, } /* Allocate ring buffers */ - ret = asrc_initialize_buffers(cd->asrc_obj); + ret = asrc_initialize_buffers(mod, cd->asrc_obj); /* check for errors */ if (ret) { @@ -688,7 +685,7 @@ static int asrc_prepare(struct processing_module *mod, cd->skew_min = cd->skew; cd->skew_max = cd->skew; - comp_info(dev, "asrc_prepare(), skew = %d", cd->skew); + comp_info(dev, "skew = %d", cd->skew); ret = asrc_update_drift(dev, cd->asrc_obj, cd->skew); if (ret) { comp_err(dev, "asrc_update_drift(), error %d", ret); @@ -698,12 +695,12 @@ static int asrc_prepare(struct processing_module *mod, return 0; err_free_asrc: - asrc_release_buffers(cd->asrc_obj); - rfree(cd->asrc_obj); + asrc_release_buffers(mod, cd->asrc_obj); + mod_free(mod, cd->asrc_obj); cd->asrc_obj = NULL; err_free_buf: - rfree(cd->buf); + mod_free(mod, cd->buf); cd->buf = NULL; err: @@ -759,7 +756,7 @@ static int asrc_control_loop(struct comp_dev *dev, struct comp_data *cd) /* Prevent divide by zero */ if (delta_sample == 0 || tsd.walclk_rate == 0) { - comp_err(dev, "asrc_control_loop(), DAI timestamp failed"); + comp_err(dev, "DAI timestamp failed"); return -EINVAL; } @@ -799,7 +796,7 @@ static int asrc_process(struct processing_module *mod, int frames_snk; int ret; - comp_dbg(dev, "asrc_process()"); + comp_dbg(dev, "entry"); ret = asrc_control_loop(dev, cd); if (ret) @@ -844,7 +841,7 @@ static int asrc_process(struct processing_module *mod, cd->asrc_func(mod, source_s, sink_s, &consumed, &produced); buffer_stream_writeback(sink, produced * audio_stream_frame_bytes(sink_s)); - comp_dbg(dev, "asrc_process(), consumed = %u, produced = %u", consumed, produced); + comp_dbg(dev, "consumed = %u, produced = %u", consumed, produced); output_buffers[0].size = produced * audio_stream_frame_bytes(sink_s); input_buffers[0].consumed = consumed * audio_stream_frame_bytes(source_s); @@ -858,17 +855,17 @@ static int asrc_reset(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); - comp_dbg(dev, "asrc_reset(), skew_min=%d, skew_max=%d", cd->skew_min, cd->skew_max); + comp_dbg(dev, "skew_min=%d, skew_max=%d", cd->skew_min, cd->skew_max); /* If any resources feasible to stop */ if (cd->track_drift) asrc_dai_stop_timestamp(cd); /* Free the allocations those were done in prepare() */ - asrc_release_buffers(cd->asrc_obj); - asrc_free_polyphase_filter(cd->asrc_obj); - rfree(cd->asrc_obj); - rfree(cd->buf); + asrc_release_buffers(mod, cd->asrc_obj); + asrc_free_polyphase_filter(mod, cd->asrc_obj); + mod_free(mod, cd->asrc_obj); + mod_free(mod, cd->buf); cd->asrc_obj = NULL; cd->buf = NULL; diff --git a/src/audio/asrc/asrc.toml b/src/audio/asrc/asrc.toml index 946842d13811..2e8f8eac837e 100644 --- a/src/audio/asrc/asrc.toml +++ b/src/audio/asrc/asrc.toml @@ -49,7 +49,7 @@ 12, 0, 0, 0, 20480, 30050000, 384, 192, 0, 30050, 0, 13, 0, 0, 0, 20480, 35152000, 384, 256, 0, 35152, 0, 14, 0, 0, 0, 20480, 81647000, 1536, 1440, 0, 81647, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 20480, 29755000, 64, 192, 0, 29755, 0, 1, 0, 0, 0, 20480, 58017000, 64, 384, 0, 58017, 0, 2, 0, 0, 0, 20480, 103471000, 512, 1440, 0, 103471, 0, diff --git a/src/audio/asrc/asrc_farrow.c b/src/audio/asrc/asrc_farrow.c index 987a11408af0..dcd58fad22bf 100644 --- a/src/audio/asrc/asrc_farrow.c +++ b/src/audio/asrc/asrc_farrow.c @@ -11,9 +11,9 @@ #include #include #include -#include #include #include +#include #include "asrc_farrow.h" LOG_MODULE_DECLARE(asrc, CONFIG_SOF_LOG_LEVEL); @@ -243,7 +243,7 @@ static const struct asrc_filter_params c_filter_params[CR_NUM] = { * Initialise the pointers to the filters, set the number of filters * and their length */ -static enum asrc_error_code initialise_filter(struct comp_dev *dev, +static enum asrc_error_code initialise_filter(struct processing_module *mod, struct asrc_farrow *src_obj); /* @@ -268,27 +268,28 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, * Pointers to each channels data. Buffers are allocated externally. */ -enum asrc_error_code asrc_get_required_size(struct comp_dev *dev, +enum asrc_error_code asrc_get_required_size(struct processing_module *mod, int *required_size, int num_channels, int bit_depth) { + struct comp_dev *dev = mod->dev; int size; /* check for parameter errors */ if (!required_size) { - comp_err(dev, "asrc_get_required_size(), invalid required_size"); + comp_err(dev, "invalid required_size"); return ASRC_EC_INVALID_POINTER; } if (num_channels < 1) { - comp_err(dev, "asrc_get_required_size(), invalid num_channels = %d", + comp_err(dev, "invalid num_channels = %d", num_channels); return ASRC_EC_INVALID_NUM_CHANNELS; } if (bit_depth != 16 && bit_depth != 32) { - comp_err(dev, "asrc_get_required_size_bytes(), invalid bit_depth = %d", + comp_err(dev, "invalid bit_depth = %d", bit_depth); return ASRC_EC_INVALID_BIT_DEPTH; } @@ -318,7 +319,7 @@ enum asrc_error_code asrc_get_required_size(struct comp_dev *dev, return ASRC_EC_OK; } -enum asrc_error_code asrc_initialise(struct comp_dev *dev, +enum asrc_error_code asrc_initialise(struct processing_module *mod, struct asrc_farrow *src_obj, int num_channels, int32_t fs_prim, @@ -331,38 +332,39 @@ enum asrc_error_code asrc_initialise(struct comp_dev *dev, enum asrc_control_mode control_mode, enum asrc_operation_mode operation_mode) { + struct comp_dev *dev = mod->dev; enum asrc_error_code error_code; /* check for parameter errors */ if (!src_obj) { - comp_err(dev, "asrc_initialise(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (num_channels < 1) { - comp_err(dev, "asrc_initialise(), num_channels = %d", + comp_err(dev, "num_channels = %d", num_channels); return ASRC_EC_INVALID_NUM_CHANNELS; } if (fs_prim < 8000 || fs_prim > 192000) { - comp_err(dev, "asrc_initialise(), fs_prim = %d", fs_prim); + comp_err(dev, "fs_prim = %d", fs_prim); return ASRC_EC_INVALID_SAMPLE_RATE; } if (fs_sec < 8000 || fs_sec > 192000) { - comp_err(dev, "asrc_initialise(), fs_src = %d", fs_sec); + comp_err(dev, "fs_src = %d", fs_sec); return ASRC_EC_INVALID_SAMPLE_RATE; } if (buffer_length < 2) { - comp_err(dev, "asrc_initialise(), buffer_length = %d", + comp_err(dev, "buffer_length = %d", buffer_length); return ASRC_EC_INVALID_BUFFER_LENGTH; } if (bit_depth != 16 && bit_depth != 32) { - comp_err(dev, "asrc_initialise(), bit_depth = %d", + comp_err(dev, "bit_depth = %d", bit_depth); return ASRC_EC_INVALID_BIT_DEPTH; } @@ -395,7 +397,7 @@ enum asrc_error_code asrc_initialise(struct comp_dev *dev, /* check conversion ratios */ if (src_obj->fs_ratio == 0 || src_obj->fs_ratio_inv == 0) { - comp_err(dev, "asrc_initialise(), fail to calculate ratios"); + comp_err(dev, "fail to calculate ratios"); return ASRC_EC_INVALID_CONVERSION_RATIO; } @@ -410,11 +412,11 @@ enum asrc_error_code asrc_initialise(struct comp_dev *dev, * also sets the pointer to the corresponding * calc_impulse_response_nX function. */ - error_code = initialise_filter(dev, src_obj); + error_code = initialise_filter(mod, src_obj); /* check for errors */ if (error_code != ASRC_EC_OK) { - comp_err(dev, "asrc_initialise(), failed filter initialise"); + comp_err(dev, "failed filter initialise"); return error_code; } @@ -438,28 +440,30 @@ enum asrc_error_code asrc_initialise(struct comp_dev *dev, return ASRC_EC_OK; } -enum asrc_error_code asrc_set_fs_ratio(struct comp_dev *dev, +enum asrc_error_code asrc_set_fs_ratio(struct processing_module *mod, struct asrc_farrow *src_obj, int32_t fs_prim, int32_t fs_sec) { + struct comp_dev *dev = mod->dev; + /* Check for parameter errors */ if (!src_obj) { - comp_err(dev, "asrc_set_fs_ratio(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (!src_obj->is_initialised) { - comp_err(dev, "asrc_set_fs_ratio(), not initialised"); + comp_err(dev, "not initialised"); return ASRC_EC_INIT_FAILED; } if (fs_prim < 8000 || fs_prim > 192000) { - comp_err(dev, "asrc_set_fs_ratio(), fs_prim = %d", fs_prim); + comp_err(dev, "fs_prim = %d", fs_prim); return ASRC_EC_INVALID_SAMPLE_RATE; } if (fs_sec < 8000 || fs_sec > 192000) { - comp_err(dev, "asrc_set_fs_ratio(), fs_sec = %d", fs_sec); + comp_err(dev, "fs_sec = %d", fs_sec); return ASRC_EC_INVALID_SAMPLE_RATE; } @@ -479,7 +483,7 @@ enum asrc_error_code asrc_set_fs_ratio(struct comp_dev *dev, /* check conversion ratios */ if (src_obj->fs_ratio == 0 || src_obj->fs_ratio_inv == 0) { - comp_err(dev, "asrc_set_fs_ratio(), failed to calculate ratios"); + comp_err(dev, "failed to calculate ratios"); return ASRC_EC_INVALID_CONVERSION_RATIO; } @@ -490,10 +494,10 @@ enum asrc_error_code asrc_set_fs_ratio(struct comp_dev *dev, /* See initialise_asrc(...) for further information * Update the filters accordingly */ - enum asrc_error_code error_code = initialise_filter(dev, src_obj); + enum asrc_error_code error_code = initialise_filter(mod, src_obj); /* check for errors */ if (error_code != ASRC_EC_OK) { - comp_err(dev, "asrc_set_fs_ratio(), failed filter initialise"); + comp_err(dev, "failed filter initialise"); return error_code; } @@ -520,12 +524,12 @@ enum asrc_error_code asrc_set_input_format(struct comp_dev *dev, { /* check for parameter errors */ if (!src_obj) { - comp_err(dev, "asrc_set_input_format(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (!src_obj->is_initialised) { - comp_err(dev, "asrc_set_input_format(), not initialised"); + comp_err(dev, "not initialised"); return ASRC_EC_INIT_FAILED; } @@ -540,12 +544,12 @@ enum asrc_error_code asrc_set_output_format(struct comp_dev *dev, { /* check for parameter errors */ if (!src_obj) { - comp_err(dev, "asrc_set_output_format(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (!src_obj->is_initialised) { - comp_err(dev, "asrc_set_output_format(), not initialised"); + comp_err(dev, "not initialised"); return ASRC_EC_INIT_FAILED; } @@ -554,28 +558,29 @@ enum asrc_error_code asrc_set_output_format(struct comp_dev *dev, return ASRC_EC_OK; } -static const int32_t *__get_polyphase_filter(const int32_t *filter, size_t size) +static const int32_t *__get_polyphase_filter(struct processing_module *mod, + const int32_t *filter, size_t size) { #if CONFIG_FAST_GET - return fast_get(filter, size); + return mod_fast_get(mod, filter, size); #else return filter; #endif } -#define get_polyphase_filter(f) __get_polyphase_filter(f, sizeof(f)) +#define get_polyphase_filter(m, f) __get_polyphase_filter(m, f, sizeof(f)) -static void put_polyphase_filter(const int32_t *filter) +static void put_polyphase_filter(struct processing_module *mod, const int32_t *filter) { #if CONFIG_FAST_GET - fast_put(filter); + mod_fast_put(mod, filter); #endif } -void asrc_free_polyphase_filter(struct asrc_farrow *src_obj) +void asrc_free_polyphase_filter(struct processing_module *mod, struct asrc_farrow *src_obj) { if (src_obj && src_obj->polyphase_filters) { - put_polyphase_filter(src_obj->polyphase_filters); + put_polyphase_filter(mod, src_obj->polyphase_filters); src_obj->polyphase_filters = NULL; } } @@ -583,9 +588,10 @@ void asrc_free_polyphase_filter(struct asrc_farrow *src_obj) /* * FILTER FUNCTIONS */ -static enum asrc_error_code initialise_filter(struct comp_dev *dev, +static enum asrc_error_code initialise_filter(struct processing_module *mod, struct asrc_farrow *src_obj) { + struct comp_dev *dev = mod->dev; int fs_in; int fs_out; @@ -606,11 +612,11 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, /* Reset coefficients for possible exit with error. */ src_obj->filter_length = 0; src_obj->num_filters = 0; - asrc_free_polyphase_filter(src_obj); + asrc_free_polyphase_filter(mod, src_obj); if (fs_in == 0 || fs_out == 0) { /* Avoid possible divisions by zero. */ - comp_err(dev, "initialise_filter(), fs_in = %d, fs_out = %d", + comp_err(dev, "fs_in = %d, fs_out = %d", fs_in, fs_out); return ASRC_EC_INVALID_SAMPLE_RATE; } else if (fs_in == 48000 && fs_out >= 48000) { @@ -622,7 +628,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO48000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO48000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to48000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to48000); } else if (fs_in <= fs_out) { /* All upsampling use cases can share the same set of * filter coefficients. @@ -631,7 +637,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_44100TO48000].filter_length; src_obj->num_filters = c_filter_params[CR_44100TO48000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff44100to48000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff44100to48000); } else if (fs_in == 48000) { switch (fs_out) { #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000) @@ -640,7 +646,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO08000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO08000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to08000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to08000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025) @@ -649,7 +655,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO11025].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO11025].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to11025); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to11025); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000) @@ -658,7 +664,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO12000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO12000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to12000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to12000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000) @@ -667,7 +673,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO16000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO16000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to16000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to16000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050) @@ -676,7 +682,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO22050].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO22050].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to22050); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to22050); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000) @@ -685,7 +691,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO24000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO24000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to24000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to24000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000) @@ -694,7 +700,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO32000].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO32000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to32000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to32000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100) @@ -703,11 +709,11 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_48000TO44100].filter_length; src_obj->num_filters = c_filter_params[CR_48000TO44100].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff48000to44100); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff48000to44100); break; #endif default: - comp_err(dev, "initialise_filter(), fs_out = %d", + comp_err(dev, "fs_out = %d", fs_out); return ASRC_EC_INVALID_SAMPLE_RATE; } @@ -719,7 +725,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_24000TO08000].filter_length; src_obj->num_filters = c_filter_params[CR_24000TO08000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff24000to08000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff24000to08000); break; #endif #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000) @@ -728,23 +734,23 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, c_filter_params[CR_24000TO16000].filter_length; src_obj->num_filters = c_filter_params[CR_24000TO16000].num_filters; - src_obj->polyphase_filters = get_polyphase_filter(coeff24000to16000); + src_obj->polyphase_filters = get_polyphase_filter(mod, coeff24000to16000); break; #endif default: - comp_err(dev, "initialise_filter(), fs_out = %d", + comp_err(dev, "fs_out = %d", fs_out); return ASRC_EC_INVALID_SAMPLE_RATE; } } else { /* Conversion ratio is not supported. */ - comp_err(dev, "initialise_filter(), fs_in = %d", fs_in); + comp_err(dev, "fs_in = %d", fs_in); return ASRC_EC_INVALID_SAMPLE_RATE; } /* Check that filter length does not exceed allocated */ if (src_obj->filter_length > ASRC_MAX_FILTER_LENGTH) { - comp_err(dev, "initialise_filter(), filter_length %d exceeds max", + comp_err(dev, "filter_length %d exceeds max", src_obj->filter_length); return ASRC_EC_INVALID_FILTER_LENGTH; } @@ -766,7 +772,7 @@ static enum asrc_error_code initialise_filter(struct comp_dev *dev, src_obj->calc_ir = &asrc_calc_impulse_response_n7; break; default: - comp_err(dev, "initialise_filter(), num_filters = %d", + comp_err(dev, "num_filters = %d", src_obj->num_filters); return ASRC_EC_INVALID_CONVERSION_RATIO; } @@ -783,12 +789,12 @@ enum asrc_error_code asrc_update_drift(struct comp_dev *dev, /* check for parameter errors */ if (!src_obj) { - comp_err(dev, "asrc_update_drift(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (!src_obj->is_initialised) { - comp_err(dev, "asrc_update_drift(), not initialised"); + comp_err(dev, "not initialised"); return ASRC_EC_INIT_FAILED; } @@ -799,7 +805,7 @@ enum asrc_error_code asrc_update_drift(struct comp_dev *dev, /* Skew is Q2.30 */ if (clock_skew < SKEW_MIN || clock_skew > SKEW_MAX) { - comp_err(dev, "asrc_update_drift(), clock_skew = %d", + comp_err(dev, "clock_skew = %d", clock_skew); return ASRC_EC_INVALID_CLOCK_SKEW; } @@ -831,12 +837,12 @@ enum asrc_error_code asrc_update_fs_ratio(struct comp_dev *dev, /* Check input for errors */ if (!src_obj) { - comp_err(dev, "asrc_update_fs_ratio(), null src_obj"); + comp_err(dev, "null src_obj"); return ASRC_EC_INVALID_POINTER; } if (!src_obj->is_initialised) { - comp_err(dev, "asrc_update_fs_ratio(), not initialized"); + comp_err(dev, "not initialized"); return ASRC_EC_INIT_FAILED; } diff --git a/src/audio/asrc/asrc_farrow.h b/src/audio/asrc/asrc_farrow.h index 766ead172d58..48e564c2d1e1 100644 --- a/src/audio/asrc/asrc_farrow.h +++ b/src/audio/asrc/asrc_farrow.h @@ -231,7 +231,7 @@ struct asrc_farrow { * @param[in] bit_depth The wordlength that will be used for representing * the PCM samples, must be 16 or 32. */ -enum asrc_error_code asrc_get_required_size(struct comp_dev *dev, +enum asrc_error_code asrc_get_required_size(struct processing_module *mod, int *required_size, int num_channels, int bit_depth); @@ -268,7 +268,7 @@ enum asrc_error_code asrc_get_required_size(struct comp_dev *dev, * @param[in] operation_mode Choose 'push' or 'pull', depending on the mode * you want your ASRC to operate in. */ -enum asrc_error_code asrc_initialise(struct comp_dev *dev, +enum asrc_error_code asrc_initialise(struct processing_module *mod, struct asrc_farrow *src_obj, int num_channels, int32_t fs_prim, @@ -286,7 +286,7 @@ enum asrc_error_code asrc_initialise(struct comp_dev *dev, * * @param[in] src_obj Pointer to the ias_src_farrow. */ -void asrc_free_polyphase_filter(struct asrc_farrow *src_obj); +void asrc_free_polyphase_filter(struct processing_module *mod, struct asrc_farrow *src_obj); /* * @brief Process the sample rate converter for one frame; the frame @@ -591,7 +591,7 @@ enum asrc_error_code asrc_update_fs_ratio(struct comp_dev *dev, * @param[in] fs_prim Primary sampling rate. * @param[in] fs_sec Secondary sampling rate. */ -enum asrc_error_code asrc_set_fs_ratio(struct comp_dev *dev, +enum asrc_error_code asrc_set_fs_ratio(struct processing_module *mod, struct asrc_farrow *src_obj, int32_t fs_prim, int32_t fs_sec); diff --git a/src/audio/asrc/asrc_ipc3.c b/src/audio/asrc/asrc_ipc3.c index 30dfbecddc6b..ca917318d7e5 100644 --- a/src/audio/asrc/asrc_ipc3.c +++ b/src/audio/asrc/asrc_ipc3.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/src/audio/asrc/asrc_ipc4.c b/src/audio/asrc/asrc_ipc4.c index 3e5d8bf7818f..1047799f207b 100644 --- a/src/audio/asrc/asrc_ipc4.c +++ b/src/audio/asrc/asrc_ipc4.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/src/audio/asrc/llext/CMakeLists.txt b/src/audio/asrc/llext/CMakeLists.txt index 8ef1d2e26fa6..27d5889d166a 100644 --- a/src/audio/asrc/llext/CMakeLists.txt +++ b/src/audio/asrc/llext/CMakeLists.txt @@ -4,6 +4,7 @@ sof_llext_build("asrc" SOURCES ../asrc.c ../asrc_farrow_hifi3.c + ../asrc_farrow_hifi5.c ../asrc_farrow.c ../asrc_farrow_generic.c ../asrc_ipc4.c diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index ed7f131d04e4..17c86fdb1df3 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,90 @@ DECLARE_TR_CTX(basefw_comp_tr, SOF_UUID(basefw_uuid), LOG_LEVEL_INFO); static struct ipc4_system_time_info global_system_time_info; static uint64_t global_cycle_delta; +__cold static uint32_t get_host_buffer_size(void) +{ + struct sof_dma *dma_host; + uint32_t periods; + + assert_can_be_cold(); + + dma_host = sof_dma_get(SOF_DMA_DIR_HMEM_TO_LMEM, 0, SOF_DMA_DEV_HOST, + SOF_DMA_ACCESS_SHARED); + if (!dma_host) { + LOG_WRN("Failed to get host DMA channel"); + return 0; + } + + periods = dma_host->plat_data.period_count; + + sof_dma_put(dma_host); + + return periods; +} + +struct sof_ipc4_codec_info_data { + uint32_t count; + uint32_t items[32]; +} __packed __aligned(4); + +/** + * Encodes codec and direction information into a single 32-bit value. + * @param codec Codec type (bits 0-7) + * @param dir Stream direction (bits 8-11) + * @return Encoded 32-bit value + */ +#define SET_CODEC_INFO_ITEM(codec, dir) (((codec) & 0xff) | (((dir) & 0xf) << 8)) + +static void get_codec_info(struct sof_tlv **tuple) +{ + struct sof_ipc4_codec_info_data codec_info = { 0 }; + +#ifdef CONFIG_CADENCE_CODEC_AAC_DEC + codec_info.items[codec_info.count++] = + SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_AAC, SOF_IPC_STREAM_PLAYBACK); +#endif +#ifdef CONFIG_CADENCE_CODEC_MP3_DEC + codec_info.items[codec_info.count++] = + SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_MP3, SOF_IPC_STREAM_PLAYBACK); +#endif +#ifdef CONFIG_CADENCE_CODEC_MP3_ENC + codec_info.items[codec_info.count++] = + SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_MP3, SOF_IPC_STREAM_CAPTURE); +#endif +#ifdef CONFIG_CADENCE_CODEC_VORBIS_DEC + codec_info.items[codec_info.count++] = + SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_VORBIS, SOF_IPC_STREAM_PLAYBACK); +#endif + + if (!codec_info.count) + return; + + tlv_value_set(*tuple, IPC4_SOF_CODEC_INFO, sizeof(codec_info.count) + + sizeof(codec_info.items[0]) * codec_info.count, &codec_info); + + *tuple = tlv_next(*tuple); +} + +#define SOF_CONFIG_MEMBER_SIZE(struct_name) (sizeof(struct sof_tlv) + \ + sizeof(struct struct_name)) +#define SOF_CONFIG_SIZE_MAX (SOF_CONFIG_MEMBER_SIZE(sof_ipc4_codec_info_data)) + +static void base_fw_sof_config(struct sof_tlv **tuple) +{ + char sof_config_data[SOF_CONFIG_SIZE_MAX] = { 0 }; + struct sof_tlv *sof_config_tuple = (struct sof_tlv *)sof_config_data; + uint32_t sof_config_size; + + get_codec_info(&sof_config_tuple); + sof_config_size = (uint32_t)((char *)sof_config_tuple - sof_config_data); + if (sof_config_size == 0) + return; + + tlv_value_set(*tuple, IPC4_FW_SOF_INFO, sof_config_size, sof_config_data); + + *tuple = tlv_next(*tuple); +} + __cold static int basefw_config(uint32_t *data_offset, char *data) { uint16_t version[4] = {SOF_MAJOR, SOF_MINOR, SOF_MICRO, SOF_BUILD}; @@ -124,6 +209,13 @@ __cold static int basefw_config(uint32_t *data_offset, char *data) tuple = tlv_next(tuple); + tlv_value_uint32_set(tuple, IPC4_FW_MIN_HOST_BUFFER_PERIODS, + get_host_buffer_size()); + + tuple = tlv_next(tuple); + + base_fw_sof_config(&tuple); + /* add platform specific tuples */ basefw_vendor_fw_config(&plat_data_offset, (char *)tuple); @@ -604,6 +696,16 @@ __cold static int basefw_get_large_config(struct comp_dev *dev, uint32_t param_i data_offset, data); }; +__cold static int basefw_astate_table(void) +{ + assert_can_be_cold(); + + /* Trivial handler possible due to an empty Astate Table requested in get_large_config */ + STATIC_ASSERT(IPC4_MAX_CLK_STATES == 0, IPC4_NON_ZERO_ASTATE_UNSUPPORTED); + + return IPC4_SUCCESS; +} + /** * Handles the DMA Control IPC message to initialize or modify DMA gateway configuration. * @@ -655,6 +757,8 @@ __cold static int basefw_set_large_config(struct comp_dev *dev, uint32_t param_i assert_can_be_cold(); switch (param_id) { + case IPC4_ASTATE_TABLE: + return basefw_astate_table(); case IPC4_DMA_CONTROL: return basefw_dma_control(first_block, last_block, data_offset, data); case IPC4_PERF_MEASUREMENTS_STATE: diff --git a/src/audio/base_fw_intel.c b/src/audio/base_fw_intel.c index 7fa0d5c28705..3601d0c5bd72 100644 --- a/src/audio/base_fw_intel.c +++ b/src/audio/base_fw_intel.c @@ -103,7 +103,7 @@ __cold int basefw_vendor_hw_config(uint32_t *data_offset, char *data) tuple = tlv_next(tuple); tlv_value_uint32_set(tuple, IPC4_LP_EBB_COUNT_HW_CFG, PLATFORM_LPSRAM_EBB_COUNT); -#if defined(CONFIG_SOC_INTEL_ACE30) || defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) tuple = tlv_next(tuple); tlv_value_uint32_set(tuple, IPC4_I2S_CAPS_HW_CFG, I2S_VER_30_PTL); #endif @@ -422,7 +422,7 @@ __cold int basefw_vendor_dma_control(uint32_t node_id, const char *config_data, { union ipc4_connector_node_id node = (union ipc4_connector_node_id)node_id; int ret, result; - enum dai_type type; + enum sof_ipc_dai_type type; assert_can_be_cold(); @@ -442,7 +442,7 @@ __cold int basefw_vendor_dma_control(uint32_t node_id, const char *config_data, return IPC4_SUCCESS; case ipc4_i2s_link_output_class: case ipc4_i2s_link_input_class: - type = DAI_INTEL_SSP; + type = SOF_DAI_INTEL_SSP; break; default: return IPC4_INVALID_RESOURCE_ID; diff --git a/src/audio/buffers/audio_buffer.c b/src/audio/buffers/audio_buffer.c index 8ab0a711e7b1..1ecf8472dd65 100644 --- a/src/audio/buffers/audio_buffer.c +++ b/src/audio/buffers/audio_buffer.c @@ -10,6 +10,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -182,12 +186,44 @@ int audio_buffer_source_set_alignment_constants(struct sof_source *source, return 0; } +uint32_t audio_buffer_sink_get_lft(struct sof_sink *sink) +{ + struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink); + /* get number of ms in the buffer */ + size_t bytes_per_sec = sink_get_frame_bytes(&buffer->_sink_api) * + sink_get_rate(&buffer->_sink_api); + size_t bytes_per_ms = bytes_per_sec / 1000; + + /* round up for frequencies like 44100 */ + if (bytes_per_ms * 1000 != bytes_per_sec) + bytes_per_ms++; + uint32_t us_in_buffer = + 1000 * source_get_data_available(&buffer->_source_api) / bytes_per_ms; + + return us_in_buffer; + + /* + * TODO, Currently there's no DP to DP connection + * >>> the code below is never accessible and won't work because of cache incoherence <<< + * + * to make DP to DP connection possible: + * + * 1) module data must be ALWAYS located in non cached memory alias, allowing + * cross core access to params like period (needed below) and calling + * module_get_deadline for the next module, regardless of cores the modules are + * running on + * 2) comp_buffer must be removed from all pipeline code, replaced with a generic abstract + * class audio_buffer - allowing using comp_buffer and ring_buffer without current + * "hybrid buffer" solution + */ +} + void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared, const struct source_ops *source_ops, const struct sink_ops *sink_ops, const struct audio_buffer_ops *audio_buffer_ops, struct sof_audio_stream_params *audio_stream_params) { - CORE_CHECK_STRUCT_INIT(&buffer, is_shared); + CORE_CHECK_STRUCT_INIT(buffer, is_shared); buffer->buffer_type = buffer_type; buffer->ops = audio_buffer_ops; assert(audio_buffer_ops->free); diff --git a/src/audio/buffers/comp_buffer.c b/src/audio/buffers/comp_buffer.c index b4f53e7cf7f1..d6562b8d821f 100644 --- a/src/audio/buffers/comp_buffer.c +++ b/src/audio/buffers/comp_buffer.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -158,8 +159,16 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer) /* In case some listeners didn't unregister from buffer's callbacks */ notifier_unregister_all(NULL, buffer); + struct k_heap *heap = buffer->audio_buffer.heap; + rfree(buffer->stream.addr); - rfree(buffer); + sof_heap_free(heap, buffer); + if (heap) { + struct dp_heap_user *mod_heap_user = container_of(heap, struct dp_heap_user, heap); + + if (!--mod_heap_user->client_count) + rfree(mod_heap_user); + } } APP_TASK_DATA static const struct source_ops comp_buffer_source_ops = { @@ -178,6 +187,7 @@ APP_TASK_DATA static const struct sink_ops comp_buffer_sink_ops = { .audio_set_ipc_params = audio_buffer_sink_set_ipc_params, .on_audio_format_set = audio_buffer_sink_on_audio_format_set, .set_alignment_constants = audio_buffer_sink_set_alignment_constants, + .get_lft = audio_buffer_sink_get_lft, }; static const struct audio_buffer_ops audio_buffer_ops = { @@ -185,10 +195,11 @@ static const struct audio_buffer_ops audio_buffer_ops = { .reset = comp_buffer_reset, .audio_set_ipc_params = comp_buffer_set_ipc_params, .on_audio_format_set = comp_buffer_format_set, - .set_alignment_constants = comp_buffer_set_alignment_constants + .set_alignment_constants = comp_buffer_set_alignment_constants, }; -static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, +static struct comp_buffer *buffer_alloc_struct(struct k_heap *heap, + void *stream_addr, size_t size, uint32_t flags, bool is_shared) { struct comp_buffer *buffer; @@ -199,13 +210,14 @@ static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, if (is_shared) flags |= SOF_MEM_FLAG_COHERENT; - buffer = rzalloc(flags, sizeof(*buffer)); - + buffer = sof_heap_alloc(heap, flags, sizeof(*buffer), 0); if (!buffer) { tr_err(&buffer_tr, "could not alloc structure"); return NULL; } + memset(buffer, 0, sizeof(*buffer)); + buffer->flags = flags; /* Force channels to 2 for init to prevent bad call to clz in buffer_init_stream */ buffer->stream.runtime_stream_params.channels = 2; @@ -220,6 +232,7 @@ static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, audio_stream_set_underrun(&buffer->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED)); audio_stream_set_overrun(&buffer->stream, !!(flags & SOF_BUF_OVERRUN_PERMITTED)); + buffer->audio_buffer.heap = heap; comp_buffer_reset_source_list(buffer); comp_buffer_reset_sink_list(buffer); @@ -227,7 +240,7 @@ static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, return buffer; } -struct comp_buffer *buffer_alloc(size_t size, uint32_t flags, uint32_t align, +struct comp_buffer *buffer_alloc(struct k_heap *heap, size_t size, uint32_t flags, uint32_t align, bool is_shared) { struct comp_buffer *buffer; @@ -248,7 +261,7 @@ struct comp_buffer *buffer_alloc(size_t size, uint32_t flags, uint32_t align, return NULL; } - buffer = buffer_alloc_struct(stream_addr, size, flags, is_shared); + buffer = buffer_alloc_struct(heap, stream_addr, size, flags, is_shared); if (!buffer) { tr_err(&buffer_tr, "could not alloc buffer structure"); rfree(stream_addr); @@ -257,7 +270,8 @@ struct comp_buffer *buffer_alloc(size_t size, uint32_t flags, uint32_t align, return buffer; } -struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_size, +struct comp_buffer *buffer_alloc_range(struct k_heap *heap, size_t preferred_size, + size_t minimum_size, uint32_t flags, uint32_t align, bool is_shared) { struct comp_buffer *buffer; @@ -291,7 +305,7 @@ struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_siz return NULL; } - buffer = buffer_alloc_struct(stream_addr, size, flags, is_shared); + buffer = buffer_alloc_struct(heap, stream_addr, size, flags, is_shared); if (!buffer) { tr_err(&buffer_tr, "could not alloc buffer structure"); rfree(stream_addr); @@ -418,7 +432,7 @@ int buffer_set_params(struct comp_buffer *buffer, CORE_CHECK_STRUCT(&buffer->audio_buffer); if (!params) { - buf_err(buffer, "buffer_set_params(): !params"); + buf_err(buffer, "!params"); return -EINVAL; } @@ -427,7 +441,7 @@ int buffer_set_params(struct comp_buffer *buffer, ret = audio_stream_set_params(&buffer->stream, params); if (ret < 0) { - buf_err(buffer, "buffer_set_params(): audio_stream_set_params failed"); + buf_err(buffer, "audio_stream_set_params failed"); return -EINVAL; } @@ -476,7 +490,7 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) struct comp_dev *src_component = comp_buffer_get_source_component(buffer); struct comp_dev *sink_component = comp_buffer_get_sink_component(buffer); - buf_dbg(buffer, "comp_update_buffer_produce(), no bytes to produce, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", + buf_dbg(buffer, "no bytes to produce, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", src_component ? dev_comp_id(src_component) : (unsigned int)UINT32_MAX, src_component ? dev_comp_type(src_component) : (unsigned int)UINT32_MAX, sink_component ? dev_comp_id(sink_component) : (unsigned int)UINT32_MAX, @@ -491,11 +505,11 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); #if CONFIG_SOF_LOG_DBG_BUFFER - buf_dbg(buffer, "comp_update_buffer_produce(), ((buffer->avail << 16) | buffer->free) = %08x, ((buffer->id << 16) | buffer->size) = %08x", + buf_dbg(buffer, "((buffer->avail << 16) | buffer->free) = %08x, ((buffer->id << 16) | buffer->size) = %08x", (audio_stream_get_avail_bytes(&buffer->stream) << 16) | audio_stream_get_free_bytes(&buffer->stream), (buffer->id << 16) | audio_stream_get_size(&buffer->stream)); - buf_dbg(buffer, "comp_update_buffer_produce(), ((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x", + buf_dbg(buffer, "((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x", ((char *)audio_stream_get_rptr(&buffer->stream) - (char *)audio_stream_get_addr(&buffer->stream)) << 16 | ((char *)audio_stream_get_wptr(&buffer->stream) - @@ -519,7 +533,7 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) struct comp_dev *src_component = comp_buffer_get_source_component(buffer); struct comp_dev *sink_component = comp_buffer_get_sink_component(buffer); - buf_dbg(buffer, "comp_update_buffer_consume(), no bytes to consume, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", + buf_dbg(buffer, "no bytes to consume, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", src_component ? dev_comp_id(src_component) : (unsigned int)UINT32_MAX, src_component ? dev_comp_type(src_component) : (unsigned int)UINT32_MAX, sink_component ? dev_comp_id(sink_component) : (unsigned int)UINT32_MAX, @@ -534,7 +548,7 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); #if CONFIG_SOF_LOG_DBG_BUFFER - buf_dbg(buffer, "comp_update_buffer_consume(), (buffer->avail << 16) | buffer->free = %08x, (buffer->id << 16) | buffer->size = %08x, (buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x", + buf_dbg(buffer, "(buffer->avail << 16) | buffer->free = %08x, (buffer->id << 16) | buffer->size = %08x, (buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x", (audio_stream_get_avail_bytes(&buffer->stream) << 16) | audio_stream_get_free_bytes(&buffer->stream), (buffer->id << 16) | audio_stream_get_size(&buffer->stream), diff --git a/src/audio/buffers/ring_buffer.c b/src/audio/buffers/ring_buffer.c index a71a27022e0a..11ebd736dfe4 100644 --- a/src/audio/buffers/ring_buffer.c +++ b/src/audio/buffers/ring_buffer.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -93,11 +94,11 @@ static void ring_buffer_free(struct sof_audio_buffer *audio_buffer) if (!audio_buffer) return; - struct ring_buffer *ring_buffer = - container_of(audio_buffer, struct ring_buffer, audio_buffer); + struct ring_buffer *ring_buffer = container_of(audio_buffer, + struct ring_buffer, audio_buffer); - rfree((__sparse_force void *)ring_buffer->_data_buffer); - rfree(ring_buffer); + sof_heap_free(audio_buffer->heap, (__sparse_force void *)ring_buffer->_data_buffer); + sof_heap_free(audio_buffer->heap, ring_buffer); } static void ring_buffer_reset(struct sof_audio_buffer *audio_buffer) @@ -273,11 +274,12 @@ static const struct sink_ops ring_buffer_sink_ops = { .audio_set_ipc_params = audio_buffer_sink_set_ipc_params, .on_audio_format_set = audio_buffer_sink_on_audio_format_set, .set_alignment_constants = audio_buffer_sink_set_alignment_constants, + .get_lft = audio_buffer_sink_get_lft, }; static const struct audio_buffer_ops audio_buffer_ops = { .free = ring_buffer_free, - .reset = ring_buffer_reset + .reset = ring_buffer_reset, }; struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_available, @@ -285,14 +287,17 @@ struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_availabl uint32_t id) { struct ring_buffer *ring_buffer; + struct k_heap *heap = dev->mod->priv.resources.heap; int memory_flags = (is_shared ? SOF_MEM_FLAG_COHERENT : 0) | user_get_buffer_memory_region(dev->drv); /* allocate ring_buffer structure */ - ring_buffer = rzalloc(memory_flags, sizeof(*ring_buffer)); + ring_buffer = sof_heap_alloc(heap, memory_flags, sizeof(*ring_buffer), 0); if (!ring_buffer) return NULL; + memset(ring_buffer, 0, sizeof(*ring_buffer)); + /* init base structure. The audio_stream_params is NULL because ring_buffer * is currently used as a secondary buffer for DP only * @@ -302,6 +307,7 @@ struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_availabl audio_buffer_init(&ring_buffer->audio_buffer, BUFFER_TYPE_RING_BUFFER, is_shared, &ring_buffer_source_ops, &ring_buffer_sink_ops, &audio_buffer_ops, NULL); + ring_buffer->audio_buffer.heap = heap; /* set obs/ibs in sink/source interfaces */ sink_set_min_free_space(audio_buffer_get_sink(&ring_buffer->audio_buffer), @@ -356,11 +362,11 @@ struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_availabl ring_buffer->data_buffer_size = 3 * max_ibs_obs; /* allocate data buffer - always in cached memory alias */ - ring_buffer->data_buffer_size = - ALIGN_UP(ring_buffer->data_buffer_size, PLATFORM_DCACHE_ALIGN); - ring_buffer->_data_buffer = (__sparse_force __sparse_cache void *) - rballoc_align(memory_flags, ring_buffer->data_buffer_size, - PLATFORM_DCACHE_ALIGN); + ring_buffer->data_buffer_size = ALIGN_UP(ring_buffer->data_buffer_size, + PLATFORM_DCACHE_ALIGN); + ring_buffer->_data_buffer = (__sparse_force __sparse_cache void *)sof_heap_alloc(heap, + user_get_buffer_memory_region(dev->drv), + ring_buffer->data_buffer_size, PLATFORM_DCACHE_ALIGN); if (!ring_buffer->_data_buffer) goto err; @@ -372,6 +378,6 @@ struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_availabl return ring_buffer; err: tr_err(&ring_buffer_tr, "Ring buffer creation failure"); - rfree(ring_buffer); + sof_heap_free(heap, ring_buffer); return NULL; } diff --git a/src/audio/chain_dma.c b/src/audio/chain_dma.c index 975f2c6daaa1..3882c38f700e 100644 --- a/src/audio/chain_dma.c +++ b/src/audio/chain_dma.c @@ -591,7 +591,7 @@ __cold static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uin fifo_size = ALIGN_UP_INTERNAL(fifo_size, addr_align); /* allocate not shared buffer */ - cd->dma_buffer = buffer_alloc(fifo_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, + cd->dma_buffer = buffer_alloc(NULL, fifo_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, addr_align, BUFFER_USAGE_NOT_SHARED); if (!cd->dma_buffer) { @@ -671,7 +671,7 @@ __cold static struct comp_dev *chain_task_create(const struct comp_driver *drv, rfree(cd); error: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -683,7 +683,7 @@ __cold static void chain_task_free(struct comp_dev *dev) chain_release(dev); rfree(cd); - rfree(dev); + comp_free_device(dev); } static const struct comp_driver comp_chain_dma = { diff --git a/src/audio/codec/dts/dts.c b/src/audio/codec/dts/dts.c index 0bc590017004..cd1da3363517 100644 --- a/src/audio/codec/dts/dts.c +++ b/src/audio/codec/dts/dts.c @@ -8,11 +8,9 @@ #include #include "DtsSofInterface.h" - LOG_MODULE_REGISTER(dts, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(dts); -DECLARE_TR_CTX(dts_tr, SOF_UUID(dts_uuid), LOG_LEVEL_INFO); #define MAX_EXPECTED_DTS_CONFIG_DATA_SIZE 8192 @@ -40,14 +38,14 @@ static void dts_effect_free_codec_memory(void *mod_void, void *pMem) struct processing_module *mod = mod_void; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "dts_effect_free_codec_memory() start"); + comp_dbg(dev, "start"); int ret = mod_free(mod, pMem); if (ret) - comp_err(dev, "dts_effect_free_codec_memory() mod_free failed %d", ret); + comp_err(dev, "mod_free failed %d", ret); - comp_dbg(dev, "dts_effect_free_codec_memory() done"); + comp_dbg(dev, "done"); } static int dts_effect_convert_sof_interface_result(struct comp_dev *dev, @@ -82,7 +80,7 @@ static int dts_effect_populate_buffer_configuration(struct comp_dev *dev, DtsSofInterfaceBufferFormat buffer_format; unsigned int buffer_fmt, frame_fmt, rate, channels; - comp_dbg(dev, "dts_effect_populate_buffer_configuration() start"); + comp_dbg(dev, "start"); if (!source) return -EINVAL; @@ -127,7 +125,7 @@ static int dts_effect_populate_buffer_configuration(struct comp_dev *dev, buffer_config->numChannels = channels; buffer_config->periodInFrames = dev->frames; - comp_dbg(dev, "dts_effect_populate_buffer_configuration() done"); + comp_dbg(dev, "done"); return 0; } @@ -141,14 +139,14 @@ static int dts_codec_init(struct processing_module *mod) DtsSofInterfaceVersionInfo interface_version; DtsSofInterfaceVersionInfo sdk_version; - comp_dbg(dev, "dts_codec_init() start"); + comp_dbg(dev, "start"); dts_result = dtsSofInterfaceInit((DtsSofInterfaceInst **)&(codec->private), dts_effect_allocate_codec_memory, dts_effect_free_codec_memory, mod); ret = dts_effect_convert_sof_interface_result(dev, dts_result); if (ret) - comp_err(dev, "dts_codec_init() dtsSofInterfaceInit failed %d %d", ret, dts_result); + comp_err(dev, "dtsSofInterfaceInit failed %d %d", ret, dts_result); /* Obtain the current versions of DTS interface and SDK */ dts_result = dtsSofInterfaceGetVersion(&interface_version, &sdk_version); @@ -156,13 +154,13 @@ static int dts_codec_init(struct processing_module *mod) /* Not necessary to fail initialisation if only get version failed */ if (dts_result == DTS_SOF_INTERFACE_RESULT_SUCCESS) { comp_info(dev, - "dts_codec_init() DTS SOF Interface version %d.%d.%d.%d", + "DTS SOF Interface version %d.%d.%d.%d", interface_version.major, interface_version.minor, interface_version.patch, interface_version.build); comp_info(dev, - "dts_codec_init() DTS SDK version %d.%d.%d.%d", + "DTS SDK version %d.%d.%d.%d", sdk_version.major, sdk_version.minor, sdk_version.patch, @@ -170,9 +168,9 @@ static int dts_codec_init(struct processing_module *mod) } if (ret) - comp_err(dev, "dts_codec_init() failed %d %d", ret, dts_result); + comp_err(dev, "failed %d %d", ret, dts_result); - comp_dbg(dev, "dts_codec_init() done"); + comp_dbg(dev, "done"); return ret; } @@ -187,12 +185,12 @@ static int dts_codec_prepare(struct processing_module *mod, DtsSofInterfaceBufferConfiguration buffer_configuration; DtsSofInterfaceResult dts_result; - comp_dbg(dev, "dts_codec_prepare() start"); + comp_dbg(dev, "start"); ret = dts_effect_populate_buffer_configuration(dev, &buffer_configuration); if (ret) { comp_err(dev, - "dts_codec_prepare() dts_effect_populate_buffer_configuration failed %d", + "dts_effect_populate_buffer_configuration failed %d", ret); return ret; } @@ -207,9 +205,9 @@ static int dts_codec_prepare(struct processing_module *mod, ret = dts_effect_convert_sof_interface_result(dev, dts_result); if (ret) - comp_err(dev, "dts_codec_prepare() failed %d", ret); + comp_err(dev, "failed %d", ret); - comp_dbg(dev, "dts_codec_prepare() done"); + comp_dbg(dev, "done"); return ret; } @@ -221,7 +219,7 @@ static int dts_codec_init_process(struct processing_module *mod) struct module_data *codec = &mod->priv; DtsSofInterfaceResult dts_result; - comp_dbg(dev, "dts_codec_init_process() start"); + comp_dbg(dev, "start"); dts_result = dtsSofInterfaceInitProcess(codec->private); ret = dts_effect_convert_sof_interface_result(dev, dts_result); @@ -231,9 +229,9 @@ static int dts_codec_init_process(struct processing_module *mod) codec->mpd.init_done = 1; if (ret) - comp_err(dev, "dts_codec_init_process() failed %d %d", ret, dts_result); + comp_err(dev, "failed %d %d", ret, dts_result); - comp_dbg(dev, "dts_codec_init_process() done"); + comp_dbg(dev, "done"); return ret; } @@ -265,7 +263,7 @@ dts_codec_process(struct processing_module *mod, input_buffers[0].data, codec->mpd.in_buff_size); codec->mpd.avail = codec->mpd.in_buff_size; - comp_dbg(dev, "dts_codec_process() start"); + comp_dbg(dev, "start"); dts_result = dtsSofInterfaceProcess(codec->private, &bytes_processed); ret = dts_effect_convert_sof_interface_result(dev, dts_result); @@ -275,7 +273,7 @@ dts_codec_process(struct processing_module *mod, input_buffers[0].consumed = codec->mpd.consumed; if (ret) { - comp_err(dev, "dts_codec_process() failed %d %d", ret, dts_result); + comp_err(dev, "failed %d %d", ret, dts_result); return ret; } @@ -284,7 +282,7 @@ dts_codec_process(struct processing_module *mod, codec->mpd.produced); output_buffers[0].size = codec->mpd.produced; - comp_dbg(dev, "dts_codec_process() done"); + comp_dbg(dev, "done"); return ret; } @@ -304,17 +302,17 @@ static int dts_codec_apply_config(struct processing_module *mod) uint32_t param_number = 0; DtsSofInterfaceResult dts_result; - comp_dbg(dev, "dts_codec_apply_config() start"); + comp_dbg(dev, "start"); config = &codec->cfg; /* Check that config->data isn't invalid and has size greater than 0 */ config_header_size = sizeof(config->size) + sizeof(config->avail); if (config->size < config_header_size) { - comp_warn(dev, "dts_codec_apply_config() config->data is invalid"); + comp_warn(dev, "config->data is invalid"); return 0; } else if (config->size == config_header_size) { - comp_warn(dev, "dts_codec_apply_config() size of config->data is 0"); + comp_warn(dev, "size of config->data is 0"); return 0; } @@ -324,7 +322,7 @@ static int dts_codec_apply_config(struct processing_module *mod) /* Check that config->data is not greater than the max expected for DTS data */ if (config_data_size > MAX_EXPECTED_DTS_CONFIG_DATA_SIZE) { comp_err(dev, - "dts_codec_apply_config() size of config->data is larger than max for DTS data"); + "size of config->data is larger than max for DTS data"); return -EINVAL; } @@ -336,7 +334,7 @@ static int dts_codec_apply_config(struct processing_module *mod) /* If param->size is less than param_header_size, then this param is not valid */ if (param->size < param_header_size) { - comp_err(dev, "dts_codec_apply_config() param is invalid"); + comp_err(dev, "param is invalid"); return -EINVAL; } @@ -345,7 +343,7 @@ static int dts_codec_apply_config(struct processing_module *mod) /* Calculate size of param->data */ param_data_size = param->size - param_header_size; - comp_dbg(dev, "dts_codec_apply_config() id %d size %d", + comp_dbg(dev, "id %d size %d", param->id, param_data_size); if (param_data_size) { @@ -354,7 +352,7 @@ static int dts_codec_apply_config(struct processing_module *mod) ret = dts_effect_convert_sof_interface_result(dev, dts_result); if (ret) { comp_err(dev, - "dts_codec_apply_config() dtsSofInterfaceApplyConfig failed %d", + "dtsSofInterfaceApplyConfig failed %d", dts_result); return ret; } @@ -365,7 +363,7 @@ static int dts_codec_apply_config(struct processing_module *mod) i += param->size; } - comp_dbg(dev, "dts_codec_apply_config() done"); + comp_dbg(dev, "done"); return ret; } @@ -377,15 +375,15 @@ static int dts_codec_reset(struct processing_module *mod) struct module_data *codec = &mod->priv; DtsSofInterfaceResult dts_result; - comp_dbg(dev, "dts_codec_reset() start"); + comp_dbg(dev, "start"); dts_result = dtsSofInterfaceReset(codec->private); ret = dts_effect_convert_sof_interface_result(dev, dts_result); if (ret) - comp_err(dev, "dts_codec_reset() failed %d %d", ret, dts_result); + comp_err(dev, "failed %d %d", ret, dts_result); - comp_dbg(dev, "dts_codec_reset() done"); + comp_dbg(dev, "done"); return ret; } @@ -397,15 +395,15 @@ static int dts_codec_free(struct processing_module *mod) struct module_data *codec = &mod->priv; DtsSofInterfaceResult dts_result; - comp_dbg(dev, "dts_codec_free() start"); + comp_dbg(dev, "start"); dts_result = dtsSofInterfaceFree(codec->private); ret = dts_effect_convert_sof_interface_result(dev, dts_result); if (ret) - comp_err(dev, "dts_codec_free() failed %d %d", ret, dts_result); + comp_err(dev, "failed %d %d", ret, dts_result); - comp_dbg(dev, "dts_codec_free() done"); + comp_dbg(dev, "done"); return ret; } @@ -480,6 +478,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(dts_tr, SOF_UUID(dts_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(dts_interface, dts_uuid, dts_tr); SOF_MODULE_INIT(dts, sys_comp_module_dts_interface_init); diff --git a/src/audio/component.c b/src/audio/component.c index 0964b0b62ebb..941be20f8534 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -53,7 +53,6 @@ int comp_register(struct comp_driver_info *drv) return 0; } -EXPORT_SYMBOL(comp_register); void comp_unregister(struct comp_driver_info *drv) { @@ -104,7 +103,7 @@ int comp_set_state(struct comp_dev *dev, int cmd) int requested_state = comp_get_requested_state(cmd); if (dev->state == requested_state) { - comp_info(dev, "comp_set_state(), state already set to %u", + comp_info(dev, "state already set to %u", dev->state); #ifdef CONFIG_IPC_MAJOR_4 return 0; @@ -517,7 +516,7 @@ static bool comp_check_eos(struct comp_dev *dev) * the EOS state. However, silence is generated to flush its internal * buffers, so pass this state to the output buffers. */ - comp_dbg(dev, "comp_check_eos() - EOS flush detected"); + comp_dbg(dev, "- EOS flush detected"); sink_state = AUDIOBUF_STATE_END_OF_STREAM_FLUSH; break; } else if (state == AUDIOBUF_STATE_END_OF_STREAM) { @@ -525,7 +524,7 @@ static bool comp_check_eos(struct comp_dev *dev) size_t min_avail = source_get_min_available(source); if (source_get_data_available(source) < min_avail) { - comp_dbg(dev, "comp_check_eos() - EOS detected"); + comp_dbg(dev, "- EOS detected"); if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { /* For DP modules, fill missing input data with silence to * allow it to process the remaining data. diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 9aab0858a305..0468664c0634 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -53,8 +52,6 @@ LOG_MODULE_REGISTER(copier, CONFIG_SOF_LOG_LEVEL); /* this id aligns windows driver requirement to support windows driver */ SOF_DEFINE_REG_UUID(copier); -DECLARE_TR_CTX(copier_comp_tr, SOF_UUID(copier_uuid), LOG_LEVEL_INFO); - #if CONFIG_INTEL_ADSP_MIC_PRIVACY static void mic_privacy_event(void *arg, enum notify_id type, void *data) { @@ -62,19 +59,19 @@ static void mic_privacy_event(void *arg, enum notify_id type, void *data) struct mic_privacy_settings *mic_privacy_settings = data; if (type == NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE) { - LOG_INF("mic_privacy_event, state1 = %d, state2 = %d ", + LOG_INF("state1 = %d, state2 = %d ", mic_privacy_settings->mic_privacy_state, mic_priv_data->mic_privacy_state); if (mic_privacy_settings->mic_privacy_state == MIC_PRIV_UNMUTED) { if (mic_priv_data->mic_privacy_state == MIC_PRIV_MUTED) { mic_priv_data->mic_privacy_state = MIC_PRIV_FADE_IN; - LOG_INF("mic_privacy_event switch to FADE_IN"); + LOG_INF("switch to FADE_IN"); } } else { /* In case when mute would be triggered before copier instantiation. */ if (mic_priv_data->mic_privacy_state != MIC_PRIV_MUTED) { mic_priv_data->mic_privacy_state = MIC_PRIV_FADE_OUT; - LOG_INF("mic_privacy_event switch to FADE_OUT"); + LOG_INF("switch to FADE_OUT"); } } mic_priv_data->max_ramp_time_in_ms = (mic_privacy_settings->max_ramp_time * 1000) / @@ -82,13 +79,12 @@ static void mic_privacy_event(void *arg, enum notify_id type, void *data) } } -static int mic_privacy_configure(struct comp_dev *dev, struct copier_data *cd) +static int mic_privacy_configure(struct processing_module *mod, struct copier_data *cd) { struct mic_privacy_data *mic_priv_data; int ret; - mic_priv_data = rzalloc(SOF_MEM_FLAG_USER, - sizeof(struct mic_privacy_data)); + mic_priv_data = mod_zalloc(mod, sizeof(struct mic_privacy_data)); if (!mic_priv_data) return -ENOMEM; @@ -100,10 +96,10 @@ static int mic_privacy_configure(struct comp_dev *dev, struct copier_data *cd) uint32_t zeroing_wait_time = (mic_privacy_get_dma_zeroing_wait_time() * 1000) / ADSP_RTC_FREQUENCY; - ret = copier_gain_set_params(dev, &mic_priv_data->mic_priv_gain_params, + ret = copier_gain_set_params(mod->dev, &mic_priv_data->mic_priv_gain_params, zeroing_wait_time, SOF_DAI_INTEL_NONE); if (ret != 0) { - rfree(mic_priv_data); + mod_free(mod, mic_priv_data); return ret; } @@ -111,92 +107,59 @@ static int mic_privacy_configure(struct comp_dev *dev, struct copier_data *cd) ret = notifier_register(cd->mic_priv, NULL, NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE, mic_privacy_event, 0); + if (ret != 0) - rfree(mic_priv_data); + mod_free(mod, mic_priv_data); return ret; } -static void mic_privacy_free(struct copier_data *cd) +static void mic_privacy_free(struct processing_module *mod) { + struct copier_data *cd = module_get_private_data(mod); + if (cd->gtw_type == ipc4_gtw_dmic) mic_privacy_enable_dmic_irq(false); notifier_unregister(cd->mic_priv, NULL, NOTIFIER_ID_MIC_PRIVACY_STATE_CHANGE); - rfree(cd->mic_priv); + mod_free(mod, cd->mic_priv); } #endif __cold static int copier_init(struct processing_module *mod) { union ipc4_connector_node_id node_id; - struct ipc_comp_dev *ipc_pipe; - struct ipc *ipc = ipc_get(); struct copier_data *cd; struct comp_dev *dev = mod->dev; struct module_data *md = &mod->priv; struct ipc4_copier_module_cfg *copier = (struct ipc4_copier_module_cfg *)md->cfg.init_data; - struct comp_ipc_config *config = &dev->ipc_config; - void *gtw_cfg = NULL; - size_t gtw_cfg_size; + size_t cfg_total_size = sizeof(*copier); + size_t gtw_cfg_var_size = 0; int i, ret = 0; assert_can_be_cold(); - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + if (copier->gtw_cfg.config_length > 1) { + /* one word already included in gateway_cfg struct hence subtraction */ + gtw_cfg_var_size += (copier->gtw_cfg.config_length - 1) << 2; + cfg_total_size += gtw_cfg_var_size; + } + + cd = mod_zalloc(mod, sizeof(*cd) + gtw_cfg_var_size); if (!cd) return -ENOMEM; md->private = cd; - /* - * Don't copy the config_data[] variable size array, we don't need to - * store it, it's only used during IPC processing, besides we haven't - * allocated space for it, so don't "fix" this! - */ - if (memcpy_s(&cd->config, sizeof(cd->config), copier, sizeof(*copier)) < 0) { - ret = -EINVAL; - goto error_cd; - } - - /* Allocate memory and store gateway_cfg in runtime. Gateway cfg has to - * be kept even after copier is created e.g. during SET_PIPELINE_STATE - * IPC when dai_config_dma_channel() is called second time and DMA - * config is used to assign dma_channel_id value. - */ - if (copier->gtw_cfg.config_length) { - gtw_cfg_size = copier->gtw_cfg.config_length << 2; - gtw_cfg = rmalloc(SOF_MEM_FLAG_USER, - gtw_cfg_size); - if (!gtw_cfg) { - ret = -ENOMEM; - goto error_cd; - } - ret = memcpy_s(gtw_cfg, gtw_cfg_size, &copier->gtw_cfg.config_data, - gtw_cfg_size); - if (ret) { - comp_err(dev, "Unable to copy gateway config from copier blob"); - goto error; - } - - cd->gtw_cfg = gtw_cfg; + if (memcpy_s(&cd->config, cfg_total_size, copier, cfg_total_size) < 0) { + ret = -EINVAL; + goto error; } for (i = 0; i < IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; i++) cd->out_fmt[i] = cd->config.out_fmt; - ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, - config->pipeline_id, - IPC_COMP_IGNORE_REMOTE); - if (!ipc_pipe) { - comp_err(dev, "pipeline %d is not existed", config->pipeline_id); - ret = -EPIPE; - goto error; - } - - dev->pipeline = ipc_pipe->pipeline; - node_id = copier->gtw_cfg.node_id; /* copier is linked to gateway */ if (node_id.dw != IPC4_INVALID_NODE_ID) { @@ -205,7 +168,7 @@ __cold static int copier_init(struct processing_module *mod) switch (node_id.f.dma_type) { case ipc4_hda_host_output_class: case ipc4_hda_host_input_class: - ret = copier_host_create(dev, cd, copier, ipc_pipe->pipeline); + ret = copier_host_create(mod, copier, dev->pipeline); if (ret < 0) { comp_err(dev, "unable to create host"); goto error; @@ -213,7 +176,7 @@ __cold static int copier_init(struct processing_module *mod) #if CONFIG_INTEL_ADSP_MIC_PRIVACY if (cd->direction == SOF_IPC_STREAM_CAPTURE && node_id.f.dma_type == ipc4_hda_host_output_class) { - ret = mic_privacy_configure(dev, cd); + ret = mic_privacy_configure(mod, cd); if (ret < 0) { comp_err(dev, "unable to configure mic privacy"); goto error; @@ -228,14 +191,14 @@ __cold static int copier_init(struct processing_module *mod) case ipc4_i2s_link_input_class: case ipc4_alh_link_output_class: case ipc4_alh_link_input_class: - ret = copier_dai_create(dev, cd, copier, ipc_pipe->pipeline); + ret = copier_dai_create(dev, cd, copier, dev->pipeline); if (ret < 0) { comp_err(dev, "unable to create dai"); goto error; } #if CONFIG_INTEL_ADSP_MIC_PRIVACY if (cd->direction == SOF_IPC_STREAM_CAPTURE) { - ret = mic_privacy_configure(dev, cd); + ret = mic_privacy_configure(mod, cd); if (ret < 0) { comp_err(dev, "unable to configure mic privacy"); goto error; @@ -246,7 +209,7 @@ __cold static int copier_init(struct processing_module *mod) #if CONFIG_IPC4_GATEWAY case ipc4_ipc_output_class: case ipc4_ipc_input_class: - ret = copier_ipcgtw_create(dev, cd, copier, ipc_pipe->pipeline); + ret = copier_ipcgtw_create(mod, copier, dev->pipeline); if (ret < 0) { comp_err(dev, "unable to create IPC gateway"); goto error; @@ -271,9 +234,7 @@ __cold static int copier_init(struct processing_module *mod) dev->state = COMP_STATE_READY; return 0; error: - rfree(gtw_cfg); -error_cd: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -285,27 +246,25 @@ __cold static int copier_free(struct processing_module *mod) assert_can_be_cold(); #if CONFIG_INTEL_ADSP_MIC_PRIVACY - mic_privacy_free(cd); + mic_privacy_free(mod); #endif switch (dev->ipc_config.type) { case SOF_COMP_HOST: if (!cd->ipc_gtw) - copier_host_free(cd); + copier_host_free(mod); else /* handle gtw case */ - copier_ipcgtw_free(cd); + copier_ipcgtw_free(mod); break; case SOF_COMP_DAI: - copier_dai_free(cd); + copier_dai_free(mod); break; default: break; } - if (cd) - rfree(cd->gtw_cfg); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -324,7 +283,7 @@ static int copier_prepare(struct processing_module *mod, if (ret < 0) return ret; - comp_info(dev, "copier_prepare()"); + comp_info(dev, "entry"); switch (dev->ipc_config.type) { case SOF_COMP_HOST: @@ -366,7 +325,7 @@ static int copier_reset(struct processing_module *mod) struct ipc4_pipeline_registers pipe_reg; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "copier_reset()"); + comp_dbg(dev, "entry"); cd->input_total_data_processed = 0; cd->output_total_data_processed = 0; @@ -404,7 +363,7 @@ static int copier_comp_trigger(struct comp_dev *dev, int cmd) uint32_t latency; int ret; - comp_dbg(dev, "copier_comp_trigger()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, cmd); if (ret < 0) @@ -540,7 +499,12 @@ static int do_conversion_copy(struct comp_dev *dev, comp_get_copy_limits(src, sink, processed_data); - i = IPC4_SINK_QUEUE_ID(buf_get_id(sink)); + /* + * Buffer ID is constructed as IPC4_COMP_ID(src_queue, dst_queue). + * From the buffer's perspective, copier's sink is the source, + * so we use IPC4_SRC_QUEUE_ID() to get the correct copier sink index. + */ + i = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); if (i >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) return -EINVAL; buffer_stream_invalidate(src, processed_data->source_bytes); @@ -617,7 +581,12 @@ static int copier_module_copy(struct processing_module *mod, uint32_t source_samples; int sink_queue_id; - sink_queue_id = IPC4_SINK_QUEUE_ID(buf_get_id(sink_c)); + /* + * Buffer ID is constructed as IPC4_COMP_ID(src_queue, dst_queue). + * From the buffer's perspective, copier's sink is the source, + * so we use IPC4_SRC_QUEUE_ID() to get the correct copier sink index. + */ + sink_queue_id = IPC4_SRC_QUEUE_ID(buf_get_id(sink_c)); if (sink_queue_id >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) return -EINVAL; @@ -700,7 +669,7 @@ static int copier_process(struct processing_module *mod, struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "copier_process()"); + comp_dbg(dev, "entry"); switch (dev->ipc_config.type) { case SOF_COMP_HOST: @@ -730,7 +699,7 @@ static int copier_params(struct processing_module *mod) struct comp_dev *dev = mod->dev; int i, ret = 0; - comp_dbg(dev, "copier_params()"); + comp_dbg(dev, "entry"); copier_update_params(cd, dev, params); @@ -1242,5 +1211,7 @@ static const struct module_interface copier_interface = { .endpoint_ops = &copier_endpoint_ops, }; +DECLARE_TR_CTX(copier_comp_tr, SOF_UUID(copier_uuid), LOG_LEVEL_INFO); + DECLARE_MODULE_ADAPTER(copier_interface, copier_uuid, copier_comp_tr); SOF_MODULE_INIT(copier, sys_comp_module_copier_interface_init); diff --git a/src/audio/copier/copier.h b/src/audio/copier/copier.h index 4a6091d99dca..4e29e18d33a6 100644 --- a/src/audio/copier/copier.h +++ b/src/audio/copier/copier.h @@ -241,13 +241,6 @@ struct ipc4_data_segment_enabled { } __attribute__((packed, aligned(4))); struct copier_data { - /* - * struct ipc4_copier_module_cfg actually has variable size, but we - * don't need the variable size array at the end, we won't be copying it - * from the IPC data. - */ - struct ipc4_copier_module_cfg config; - void *gtw_cfg; enum ipc4_gateway_type gtw_type; uint32_t endpoint_num; @@ -277,6 +270,8 @@ struct copier_data { #if CONFIG_INTEL_ADSP_MIC_PRIVACY struct mic_privacy_data *mic_priv; #endif + /* Has to be at the end due to variable size array */ + struct ipc4_copier_module_cfg config; }; int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, diff --git a/src/audio/copier/copier.toml b/src/audio/copier/copier.toml index 3f3b0ac17899..acb2a5f8876f 100644 --- a/src/audio/copier/copier.toml +++ b/src/audio/copier/copier.toml @@ -92,7 +92,7 @@ 28, 0, 0, 0, 280, 6058000, 64, 64, 0, 6058, 0, 29, 0, 0, 0, 280, 6198000, 64, 64, 0, 6198, 0, 30, 0, 0, 0, 280, 6034000, 32, 32, 0, 6034, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 280, 7915000, 768, 768, 0, 7915, 0, 1, 0, 0, 0, 280, 9487000, 768, 768, 0, 9487, 0, 2, 0, 0, 0, 280, 7363000, 384, 384, 0, 7363, 0, diff --git a/src/audio/copier/copier_dai.c b/src/audio/copier/copier_dai.c index 828ee259b79b..821aa59d7640 100644 --- a/src/audio/copier/copier_dai.c +++ b/src/audio/copier/copier_dai.c @@ -204,9 +204,10 @@ __cold static int copier_dai_init(struct comp_dev *dev, return ret; } - dd = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*dd)); + dd = mod_alloc_ext(mod, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*dd), 0); if (!dd) return -ENOMEM; + memset(dd, 0, sizeof(*dd)); ret = dai_common_new(dd, dev, dai); if (ret < 0) @@ -223,12 +224,14 @@ __cold static int copier_dai_init(struct comp_dev *dev, /* Allocate gain data if selected for this dai type and set basic params */ if (dai->apply_gain) { - struct copier_gain_params *gain_data = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, - sizeof(*gain_data)); + struct copier_gain_params *gain_data = + mod_alloc_ext(mod, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*gain_data), 0); if (!gain_data) { ret = -ENOMEM; goto e_zephyr_free; } + memset(gain_data, 0, sizeof(*gain_data)); cd->dd[index]->gain_data = gain_data; ret = copier_gain_set_params(dev, cd->dd[index]->gain_data, @@ -244,11 +247,11 @@ __cold static int copier_dai_init(struct comp_dev *dev, return 0; gain_free: - rfree(dd->gain_data); + mod_free(mod, dd->gain_data); e_zephyr_free: dai_common_free(dd); free_dd: - rfree(dd); + mod_free(mod, dd); return ret; } @@ -267,6 +270,8 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, struct ipc_config_dai dai; int dai_count; int i, ret; + uint8_t *gtw_cfg_data = (uint8_t *)cd->config.gtw_cfg.config_data; + size_t gtw_cfg_szie = cd->config.gtw_cfg.config_length * 4; assert_can_be_cold(); @@ -293,8 +298,7 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, dai.type = SOF_DAI_INTEL_SSP; dai.is_config_blob = true; cd->gtw_type = ipc4_gtw_ssp; - ret = ipc4_find_dma_config(&dai, (uint8_t *)cd->gtw_cfg, - copier->gtw_cfg.config_length * 4); + ret = ipc4_find_dma_config(&dai, gtw_cfg_data, gtw_cfg_szie); if (ret != 0) { comp_err(dev, "No ssp dma_config found in blob!"); return -EINVAL; @@ -312,8 +316,8 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, dai.is_config_blob = true; cd->gtw_type = ipc4_gtw_alh; #endif /* ACE_VERSION > ACE_VERSION_1_5 */ - ret = copier_alh_assign_dai_index(dev, cd->gtw_cfg, node_id, - &dai, dai_index, &dai_count); + ret = copier_alh_assign_dai_index(dev, gtw_cfg_data, node_id, &dai, dai_index, + &dai_count); if (ret) return ret; break; @@ -321,8 +325,7 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, dai.type = SOF_DAI_INTEL_DMIC; dai.is_config_blob = true; cd->gtw_type = ipc4_gtw_dmic; - ret = ipc4_find_dma_config(&dai, (uint8_t *)cd->gtw_cfg, - copier->gtw_cfg.config_length * 4); + ret = ipc4_find_dma_config(&dai, gtw_cfg_data, gtw_cfg_szie); if (ret != 0) { comp_err(dev, "No dmic dma_config found in blob!"); return -EINVAL; @@ -374,14 +377,16 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, return 0; } -__cold void copier_dai_free(struct copier_data *cd) +__cold void copier_dai_free(struct processing_module *mod) { + struct copier_data *cd = module_get_private_data(mod); + assert_can_be_cold(); for (int i = 0; i < cd->endpoint_num; i++) { dai_common_free(cd->dd[i]); - rfree(cd->dd[i]->gain_data); - rfree(cd->dd[i]); + mod_free(mod, cd->dd[i]->gain_data); + mod_free(mod, cd->dd[i]); } /* only dai have multi endpoint case */ if (cd->multi_endpoint_buffer) diff --git a/src/audio/copier/copier_gain.c b/src/audio/copier/copier_gain.c index 4c077665e7d0..fc9f6664add8 100644 --- a/src/audio/copier/copier_gain.c +++ b/src/audio/copier/copier_gain.c @@ -34,12 +34,8 @@ __cold int copier_gain_set_params(struct comp_dev *dev, struct copier_gain_param switch (dai_type) { case SOF_DAI_INTEL_DMIC: { - struct dmic_config_data *dmic_cfg = cd->gtw_cfg; - - if (!dmic_cfg) { - comp_err(dev, "No dmic config found"); - return -EINVAL; - } + struct dmic_config_data *dmic_cfg = + (void *)cd->config.gtw_cfg.config_data; union dmic_global_cfg *dmic_glb_cfg = &dmic_cfg->dmic_blob.global_cfg; diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index da1ca4dbf942..916d3b9899fc 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -169,7 +169,7 @@ int copier_gain_input16(struct comp_buffer *buff, enum copier_gain_state state, /* Apply fade */ for (j = 0; j < nch; j++) { - dst += j; + dst_tmp = dst + j; /* Quadratic fade part in Q15 format*/ gain_env_sq = q_multsr_16x16(gain_env[j], gain_env[j], 15); @@ -180,8 +180,8 @@ int copier_gain_input16(struct comp_buffer *buff, enum copier_gain_state state, gain_env_sq, 15); for (i = 0; i < nmax; i += nch) - dst[i] = q_multsr_sat_16x16(dst[i], gain, - GAIN_Q10_INT_SHIFT); + dst_tmp[i] = q_multsr_sat_16x16(dst_tmp[i], gain, + GAIN_Q10_INT_SHIFT); } samples -= nmax; dst = audio_stream_wrap(&buff->stream, dst + nmax); @@ -260,7 +260,7 @@ int copier_gain_input32(struct comp_buffer *buff, enum copier_gain_state state, /* Apply fade */ for (j = 0; j < nch; j++) { - dst += j; + dst_tmp = dst + j; /* Quadratic fade part in Q15 format*/ gain_env_sq = q_multsr_16x16(gain_env[j], gain_env[j], 15); @@ -271,8 +271,8 @@ int copier_gain_input32(struct comp_buffer *buff, enum copier_gain_state state, gain_env_sq, 15); for (i = 0; i < nmax; i += nch) - dst[i] = q_multsr_sat_32x32(dst[i], gain, - GAIN_Q10_INT_SHIFT); + dst_tmp[i] = q_multsr_sat_32x32(dst_tmp[i], gain, + GAIN_Q10_INT_SHIFT); } samples -= nmax; dst = audio_stream_wrap(&buff->stream, dst + nmax); @@ -328,7 +328,7 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, /* update each sink format */ comp_dev_for_each_consumer(dev, sink) { int j; - j = IPC4_SINK_QUEUE_ID(buf_get_id(sink)); + j = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); ipc4_update_buffer_format(sink, &cd->out_fmt[j]); } @@ -427,7 +427,7 @@ __cold int create_multi_endpoint_buffer(struct comp_dev *dev, ipc_buf.size = buf_size; ipc_buf.comp.pipeline_id = config->pipeline_id; ipc_buf.comp.core = config->core; - buffer = buffer_new(&ipc_buf, BUFFER_USAGE_NOT_SHARED); + buffer = buffer_new(NULL, &ipc_buf, BUFFER_USAGE_NOT_SHARED); if (!buffer) return -ENOMEM; diff --git a/src/audio/copier/copier_host.c b/src/audio/copier/copier_host.c index 8315ad4535e2..fe17a49328b9 100644 --- a/src/audio/copier/copier_host.c +++ b/src/audio/copier/copier_host.c @@ -50,6 +50,7 @@ __cold static int add_to_fpi_sync_group(struct comp_dev *parent_dev, struct ipc4_copier_sync_group *sync_group) { struct fpi_sync_group *group = find_group_by_id(sync_group->group_id); + struct processing_module *mod = comp_mod(parent_dev); assert_can_be_cold(); @@ -62,11 +63,13 @@ __cold static int add_to_fpi_sync_group(struct comp_dev *parent_dev, group->ref_count++; } else { - group = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*group)); + group = mod_alloc_ext(mod, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*group), 0); if (!group) { comp_err(parent_dev, "Failed to alloc memory for new group"); return -ENOMEM; } + memset(group, 0, sizeof(*group)); group->id = sync_group->group_id; group->period = sync_group->fpi_update_period_usec; @@ -81,9 +84,10 @@ __cold static int add_to_fpi_sync_group(struct comp_dev *parent_dev, return 0; } -__cold static void delete_from_fpi_sync_group(struct host_data *hd) +__cold static void delete_from_fpi_sync_group(struct processing_module *mod) { - struct fpi_sync_group *group = find_group_by_id(hd->group_id); + struct copier_data *cd = module_get_private_data(mod); + struct fpi_sync_group *group = find_group_by_id(cd->hd->group_id); assert_can_be_cold(); @@ -93,7 +97,7 @@ __cold static void delete_from_fpi_sync_group(struct host_data *hd) group->ref_count--; if (group->ref_count == 0) { list_item_del(&group->item); - rfree(group); + mod_free(mod, group); } } #endif @@ -131,11 +135,12 @@ __cold static int init_pipeline_reg(struct comp_dev *dev) * Sof host component can support this case so copier reuses host * component to support host gateway. */ -__cold int copier_host_create(struct comp_dev *dev, struct copier_data *cd, +__cold int copier_host_create(struct processing_module *mod, const struct ipc4_copier_module_cfg *copier_cfg, struct pipeline *pipeline) { - struct processing_module *mod = comp_mod(dev); + struct copier_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; struct comp_ipc_config *config = &dev->ipc_config; struct ipc_config_host ipc_host; struct host_data *hd; @@ -177,7 +182,7 @@ __cold int copier_host_create(struct comp_dev *dev, struct copier_data *cd, ipc_host.dma_buffer_size = copier_cfg->gtw_cfg.dma_buffer_size; ipc_host.feature_mask = copier_cfg->copier_feature_mask; - hd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*hd)); + hd = mod_zalloc(mod, sizeof(*hd)); if (!hd) return -ENOMEM; @@ -205,14 +210,16 @@ __cold int copier_host_create(struct comp_dev *dev, struct copier_data *cd, if (value_ptr) { struct ipc4_copier_sync_group *sync_group; - if (value_size != sizeof(struct ipc4_copier_sync_group)) - return -EINVAL; + if (value_size != sizeof(struct ipc4_copier_sync_group)) { + ret = -EINVAL; + goto e_conv; + } sync_group = (struct ipc4_copier_sync_group *)((void *)value_ptr); ret = add_to_fpi_sync_group(dev, hd, sync_group); if (ret < 0) - return ret; + goto e_conv; } } #endif @@ -249,21 +256,23 @@ __cold int copier_host_create(struct comp_dev *dev, struct copier_data *cd, e_conv: host_common_free(hd); e_data: - rfree(hd); + mod_free(mod, hd); return ret; } -__cold void copier_host_free(struct copier_data *cd) +__cold void copier_host_free(struct processing_module *mod) { + struct copier_data *cd = module_get_private_data(mod); + assert_can_be_cold(); #if CONFIG_HOST_DMA_STREAM_SYNCHRONIZATION if (cd->hd->is_grouped) - delete_from_fpi_sync_group(cd->hd); + delete_from_fpi_sync_group(mod); #endif host_common_free(cd->hd); - rfree(cd->hd); + mod_free(mod, cd->hd); } /* This is called by DMA driver every time when DMA completes its current @@ -275,7 +284,7 @@ void copier_host_dma_cb(struct comp_dev *dev, size_t bytes) struct copier_data *cd = module_get_private_data(mod); int ret, frames; - comp_dbg(dev, "copier_host_dma_cb() %p", dev); + comp_dbg(dev, "%p", dev); /* update position */ host_common_update(cd->hd, dev, bytes); @@ -293,7 +302,7 @@ void copier_host_dma_cb(struct comp_dev *dev, size_t bytes) ret = apply_attenuation(dev, cd, cd->hd->local_buffer, frames); if (ret < 0) - comp_dbg(dev, "copier_host_dma_cb() apply attenuation failed! %d", ret); + comp_dbg(dev, "apply attenuation failed! %d", ret); buffer_stream_writeback(cd->hd->local_buffer, bytes); } diff --git a/src/audio/copier/copier_ipcgtw.c b/src/audio/copier/copier_ipcgtw.c index ea518b5e12f2..ed365c1e50d8 100644 --- a/src/audio/copier/copier_ipcgtw.c +++ b/src/audio/copier/copier_ipcgtw.c @@ -2,10 +2,10 @@ // // Copyright 2023 Intel Corporation. All rights reserved. +#include #include #include #include -#include #include #include #include "copier.h" @@ -13,10 +13,6 @@ LOG_MODULE_REGISTER(ipcgtw, CONFIG_SOF_LOG_LEVEL); -SOF_DEFINE_REG_UUID(ipcgw); - -DECLARE_TR_CTX(ipcgtw_comp_tr, SOF_UUID(ipcgw_uuid), LOG_LEVEL_INFO); - /* List of existing IPC gateways */ static struct list_item ipcgtw_list_head = LIST_INIT(ipcgtw_list_head); @@ -207,10 +203,12 @@ void copier_ipcgtw_reset(struct comp_dev *dev) } } -__cold int copier_ipcgtw_create(struct comp_dev *dev, struct copier_data *cd, +__cold int copier_ipcgtw_create(struct processing_module *mod, const struct ipc4_copier_module_cfg *copier, struct pipeline *pipeline) { + struct copier_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; struct comp_ipc_config *config = &dev->ipc_config; struct ipcgtw_data *ipcgtw_data; const struct ipc4_copier_gateway_cfg *gtw_cfg; @@ -231,7 +229,7 @@ __cold int copier_ipcgtw_create(struct comp_dev *dev, struct copier_data *cd, config->type = SOF_COMP_HOST; cd->gtw_type = ipc4_gtw_host; - ipcgtw_data = rzalloc(SOF_MEM_FLAG_USER, sizeof(*ipcgtw_data)); + ipcgtw_data = mod_zalloc(mod, sizeof(*ipcgtw_data)); if (!ipcgtw_data) return -ENOMEM; @@ -273,14 +271,16 @@ __cold int copier_ipcgtw_create(struct comp_dev *dev, struct copier_data *cd, return 0; e_ipcgtw: - rfree(ipcgtw_data); + mod_free(mod, ipcgtw_data); return ret; } -__cold void copier_ipcgtw_free(struct copier_data *cd) +__cold void copier_ipcgtw_free(struct processing_module *mod) { + struct copier_data *cd = module_get_private_data(mod); + assert_can_be_cold(); list_item_del(&cd->ipcgtw_data->item); - rfree(cd->ipcgtw_data); + mod_free(mod, cd->ipcgtw_data); } diff --git a/src/audio/copier/dai_copier.h b/src/audio/copier/dai_copier.h index 0ec7f04ae6ac..481b06b4bc58 100644 --- a/src/audio/copier/dai_copier.h +++ b/src/audio/copier/dai_copier.h @@ -79,7 +79,7 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, const struct ipc4_copier_module_cfg *copier, struct pipeline *pipeline); -void copier_dai_free(struct copier_data *cd); +void copier_dai_free(struct processing_module *mod); int copier_dai_prepare(struct comp_dev *dev, struct copier_data *cd); diff --git a/src/audio/copier/host_copier.h b/src/audio/copier/host_copier.h index e8f5fc58ca91..28605ed9c3ab 100644 --- a/src/audio/copier/host_copier.h +++ b/src/audio/copier/host_copier.h @@ -129,10 +129,10 @@ static inline int host_common_copy(struct host_data *hd, struct comp_dev *dev, c } void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t bytes); void host_common_one_shot(struct host_data *hd, uint32_t bytes); -int copier_host_create(struct comp_dev *dev, struct copier_data *cd, +int copier_host_create(struct processing_module *mod, const struct ipc4_copier_module_cfg *copier_cfg, struct pipeline *pipeline); -void copier_host_free(struct copier_data *cd); +void copier_host_free(struct processing_module *mod); int copier_host_params(struct copier_data *cd, struct comp_dev *dev, struct sof_ipc_stream_params *params); void copier_host_dma_cb(struct comp_dev *dev, size_t bytes); diff --git a/src/audio/copier/ipcgtw_copier.h b/src/audio/copier/ipcgtw_copier.h index ef42ede75ddd..a9ea82914d4e 100644 --- a/src/audio/copier/ipcgtw_copier.h +++ b/src/audio/copier/ipcgtw_copier.h @@ -95,17 +95,17 @@ struct ipc4_ipc_gateway_cmd_data_reply { int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, void *reply_payload, uint32_t *reply_payload_size); -int copier_ipcgtw_create(struct comp_dev *dev, struct copier_data *cd, +int copier_ipcgtw_create(struct processing_module *mod, const struct ipc4_copier_module_cfg *copier, struct pipeline *pipeline); #if CONFIG_IPC4_GATEWAY -void copier_ipcgtw_free(struct copier_data *cd); +void copier_ipcgtw_free(struct processing_module *mod); int copier_ipcgtw_params(struct ipcgtw_data *ipcgtw_data, struct comp_dev *dev, struct sof_ipc_stream_params *params); void copier_ipcgtw_reset(struct comp_dev *dev); #else -static inline void copier_ipcgtw_free(struct copier_data *cd) {} +static inline void copier_ipcgtw_free(struct processing_module *mod) {} static inline void copier_ipcgtw_reset(struct comp_dev *dev) {} static inline int copier_ipcgtw_params(struct ipcgtw_data *ipcgtw_data, struct comp_dev *dev, struct sof_ipc_stream_params *params) diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index d1c0eefa4d7f..a8c31eecdb55 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -41,18 +40,17 @@ LOG_MODULE_REGISTER(crossover, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(crossover); -DECLARE_TR_CTX(crossover_tr, SOF_UUID(crossover_uuid), LOG_LEVEL_INFO); - /** * \brief Reset the state (coefficients and delay) of the crossover filter * across all channels */ -static void crossover_reset_state(struct comp_data *cd) +static void crossover_reset_state(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); int i; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - crossover_reset_state_ch(&cd->state[i]); + crossover_reset_state_ch(mod, &cd->state[i]); } /** @@ -73,7 +71,7 @@ int crossover_get_stream_index(struct processing_module *mod, if (assign_sink[i] == pipe_id) return i; - comp_err(mod->dev, "crossover_get_stream_index() error: couldn't find any assignment for connected pipeline %u", + comp_err(mod->dev, "error: couldn't find any assignment for connected pipeline %u", pipe_id); return -EINVAL; @@ -127,14 +125,14 @@ static int crossover_assign_sinks(struct processing_module *mod, */ if (i < 0) { comp_err(dev, - "crossover_assign_sinks(), could not find sink %d in config", + "could not find sink %d in config", sink_id); break; } if (assigned_obufs[i]) { comp_err(dev, - "crossover_assign_sinks(), multiple sinks with id %d are assigned", + "multiple sinks with id %d are assigned", sink_id); break; } @@ -156,7 +154,8 @@ static int crossover_assign_sinks(struct processing_module *mod, * high/low pass filter. * \param[out] lr4 initialized struct */ -static int crossover_init_coef_lr4(struct sof_eq_iir_biquad *coef, +static int crossover_init_coef_lr4(struct processing_module *mod, + struct sof_eq_iir_biquad *coef, struct iir_state_df1 *lr4) { int ret; @@ -169,8 +168,7 @@ static int crossover_init_coef_lr4(struct sof_eq_iir_biquad *coef, * in series due to identity. To maintain the structure of * iir_state_df1, it requires two copies of coefficients in a row. */ - lr4->coef = rzalloc(SOF_MEM_FLAG_USER, - sizeof(struct sof_eq_iir_biquad) * 2); + lr4->coef = mod_zalloc(mod, sizeof(struct sof_eq_iir_biquad) * 2); if (!lr4->coef) return -ENOMEM; @@ -189,8 +187,7 @@ static int crossover_init_coef_lr4(struct sof_eq_iir_biquad *coef, * delay[0..1] -> state for first biquad * delay[2..3] -> state for second biquad */ - lr4->delay = rzalloc(SOF_MEM_FLAG_USER, - sizeof(uint64_t) * CROSSOVER_NUM_DELAYS_LR4); + lr4->delay = mod_zalloc(mod, sizeof(uint64_t) * CROSSOVER_NUM_DELAYS_LR4); if (!lr4->delay) return -ENOMEM; @@ -203,7 +200,8 @@ static int crossover_init_coef_lr4(struct sof_eq_iir_biquad *coef, /** * \brief Initializes the crossover coefficients for one channel */ -int crossover_init_coef_ch(struct sof_eq_iir_biquad *coef, +int crossover_init_coef_ch(struct processing_module *mod, + struct sof_eq_iir_biquad *coef, struct crossover_state *ch_state, int32_t num_sinks) { @@ -214,12 +212,12 @@ int crossover_init_coef_ch(struct sof_eq_iir_biquad *coef, for (i = 0; i < num_lr4s; i++) { /* Get the low pass coefficients */ - err = crossover_init_coef_lr4(&coef[j], + err = crossover_init_coef_lr4(mod, &coef[j], &ch_state->lowpass[i]); if (err < 0) return -EINVAL; /* Get the high pass coefficients */ - err = crossover_init_coef_lr4(&coef[j + 1], + err = crossover_init_coef_lr4(mod, &coef[j + 1], &ch_state->highpass[i]); if (err < 0) return -EINVAL; @@ -243,29 +241,29 @@ static int crossover_init_coef(struct processing_module *mod, int nch) int ch, err; if (!config) { - comp_err(mod->dev, "crossover_init_coef(), no config is set"); + comp_err(mod->dev, "no config is set"); return -EINVAL; } /* Sanity checks */ if (nch > PLATFORM_MAX_CHANNELS) { - comp_err(mod->dev, "crossover_init_coef(), invalid channels count (%i)", nch); + comp_err(mod->dev, "invalid channels count (%i)", nch); return -EINVAL; } - comp_info(mod->dev, "crossover_init_coef(), initializing %i-way crossover", + comp_info(mod->dev, "initializing %i-way crossover", config->num_sinks); /* Collect the coef array and assign it to every channel */ crossover = config->coef; for (ch = 0; ch < nch; ch++) { - err = crossover_init_coef_ch(crossover, &cd->state[ch], + err = crossover_init_coef_ch(mod, crossover, &cd->state[ch], config->num_sinks); /* Free all previously allocated blocks in case of an error */ if (err < 0) { - comp_err(mod->dev, "crossover_init_coef(), could not assign coefficients to ch %d", + comp_err(mod->dev, "could not assign coefficients to ch %d", ch); - crossover_reset_state(cd); + crossover_reset_state(mod); return err; } } @@ -278,11 +276,10 @@ static int crossover_init_coef(struct processing_module *mod, int nch) */ static int crossover_setup(struct processing_module *mod, int nch) { - struct comp_data *cd = module_get_private_data(mod); int ret = 0; /* Reset any previous state */ - crossover_reset_state(cd); + crossover_reset_state(mod); /* Assign LR4 coefficients from config */ ret = crossover_init_coef(mod, nch); @@ -303,23 +300,23 @@ static int crossover_init(struct processing_module *mod) size_t bs = ipc_crossover->size; int ret; - comp_info(dev, "crossover_init()"); + comp_info(dev, "entry"); /* Check that the coefficients blob size is sane */ if (bs > SOF_CROSSOVER_MAX_SIZE) { - comp_err(dev, "crossover_init(), blob size (%d) exceeds maximum allowed size (%i)", + comp_err(dev, "blob size (%d) exceeds maximum allowed size (%i)", bs, SOF_CROSSOVER_MAX_SIZE); return -ENOMEM; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; md->private = cd; /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { comp_err(dev, "comp_data_blob_handler_new() failed."); ret = -ENOMEM; @@ -335,16 +332,16 @@ static int crossover_init(struct processing_module *mod) ret = crossover_output_pin_init(mod); if (ret < 0) { - comp_err(dev, "crossover_init_output_pins() failed."); + comp_err(dev, "failed."); goto cd_fail; } - crossover_reset_state(cd); + crossover_reset_state(mod); return 0; cd_fail: - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -355,13 +352,13 @@ static int crossover_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "crossover_free()"); + comp_info(mod->dev, "entry"); - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); - crossover_reset_state(cd); + crossover_reset_state(mod); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -378,13 +375,13 @@ static int crossover_validate_config(struct processing_module *mod, int32_t num_assigned_sinks; if (size > SOF_CROSSOVER_MAX_SIZE || !size) { - comp_err(dev, "crossover_validate_config(), size %d is invalid", size); + comp_err(dev, "size %d is invalid", size); return -EINVAL; } if (config->num_sinks > SOF_CROSSOVER_MAX_STREAMS || config->num_sinks < 2) { - comp_err(dev, "crossover_validate_config(), invalid num_sinks %i, expected number between 2 and %i", + comp_err(dev, "invalid num_sinks %i, expected number between 2 and %i", config->num_sinks, SOF_CROSSOVER_MAX_STREAMS); return -EINVAL; } @@ -398,7 +395,7 @@ static int crossover_validate_config(struct processing_module *mod, * is different than what is configured. */ if (num_assigned_sinks != config->num_sinks) { - comp_err(dev, "crossover_validate_config(), number of assigned sinks %d, expected from config %d", + comp_err(dev, "number of assigned sinks %d, expected from config %d", num_assigned_sinks, config->num_sinks); return -EINVAL; } @@ -415,7 +412,7 @@ static int crossover_set_config(struct processing_module *mod, uint32_t config_i struct comp_data *cd = module_get_private_data(mod); int ret; - comp_info(mod->dev, "crossover_set_config()"); + comp_info(mod->dev, "entry"); ret = crossover_check_config(mod, fragment); if (ret < 0) @@ -433,7 +430,7 @@ static int crossover_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; int ret; - comp_info(mod->dev, "crossover_get_config()"); + comp_info(mod->dev, "entry"); ret = crossover_check_config(mod, fragment); if (ret < 0) @@ -470,14 +467,14 @@ static int crossover_process_audio_stream(struct processing_module *mod, int ret; int i; - comp_dbg(dev, "crossover_process_audio_stream()"); + comp_dbg(dev, "entry"); /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); ret = crossover_setup(mod, audio_stream_get_channels(source)); if (ret < 0) { - comp_err(dev, "crossover_process_audio_stream(), failed Crossover setup"); + comp_err(dev, "failed Crossover setup"); return ret; } } @@ -532,7 +529,7 @@ static int crossover_prepare(struct processing_module *mod, struct comp_buffer *source, *sink; int channels; - comp_info(dev, "crossover_prepare()"); + comp_info(dev, "entry"); source = comp_dev_get_first_data_producer(dev); if (!source) { @@ -558,7 +555,7 @@ static int crossover_prepare(struct processing_module *mod, } } - comp_info(dev, "crossover_prepare(), source_format=%d, sink_formats=%d, nch=%d", + comp_info(dev, "source_format=%d, sink_formats=%d, nch=%d", cd->source_format, cd->source_format, channels); cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); @@ -566,7 +563,7 @@ static int crossover_prepare(struct processing_module *mod, /* Initialize Crossover */ if (cd->config && crossover_validate_config(mod, cd->config) < 0) { /* If config is invalid then delete it */ - comp_err(dev, "crossover_prepare(), invalid binary config format"); + comp_err(dev, "invalid binary config format"); crossover_free_config(&cd->config); } @@ -574,29 +571,29 @@ static int crossover_prepare(struct processing_module *mod, int ret = crossover_setup(mod, channels); if (ret < 0) { - comp_err(dev, "crossover_prepare(), setup failed"); + comp_err(dev, "setup failed"); return ret; } cd->crossover_process = crossover_find_proc_func(cd->source_format); if (!cd->crossover_process) { - comp_err(dev, "crossover_prepare(), No processing function matching frame_fmt %i", + comp_err(dev, "No processing function matching frame_fmt %i", cd->source_format); return -EINVAL; } cd->crossover_split = crossover_find_split_func(cd->config->num_sinks); if (!cd->crossover_split) { - comp_err(dev, "crossover_prepare(), No split function matching num_sinks %i", + comp_err(dev, "No split function matching num_sinks %i", cd->config->num_sinks); return -EINVAL; } } else { - comp_info(dev, "crossover_prepare(), setting crossover to passthrough mode"); + comp_info(dev, "setting crossover to passthrough mode"); cd->crossover_process = crossover_find_proc_func_pass(cd->source_format); if (!cd->crossover_process) { - comp_err(dev, "crossover_prepare(), No passthrough function matching frame_fmt %i", + comp_err(dev, "No passthrough function matching frame_fmt %i", cd->source_format); return -EINVAL; } @@ -614,9 +611,9 @@ static int crossover_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "crossover_reset()"); + comp_info(mod->dev, "entry"); - crossover_reset_state(cd); + crossover_reset_state(mod); cd->crossover_process = NULL; cd->crossover_split = NULL; @@ -649,6 +646,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(crossover_tr, SOF_UUID(crossover_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(crossover_interface, crossover_uuid, crossover_tr); SOF_MODULE_INIT(crossover, sys_comp_module_crossover_interface_init); diff --git a/src/audio/crossover/crossover_ipc3.c b/src/audio/crossover/crossover_ipc3.c index 07eb39ebca95..48f56ac3cced 100644 --- a/src/audio/crossover/crossover_ipc3.c +++ b/src/audio/crossover/crossover_ipc3.c @@ -48,13 +48,13 @@ int crossover_check_sink_assign(struct processing_module *mod, i = crossover_get_stream_index(mod, config, pipeline_id); if (i < 0) { - comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %d", + comp_warn(dev, "could not assign sink %d", pipeline_id); break; } if (assigned_sinks[i]) { - comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pipeline %d are assigned", + comp_warn(dev, "multiple sinks from pipeline %d are assigned", pipeline_id); break; } diff --git a/src/audio/crossover/crossover_ipc4.c b/src/audio/crossover/crossover_ipc4.c index 981d34bafb7f..3e0beffeeeb1 100644 --- a/src/audio/crossover/crossover_ipc4.c +++ b/src/audio/crossover/crossover_ipc4.c @@ -81,13 +81,13 @@ int crossover_check_sink_assign(struct processing_module *mod, pin_index = cd->output_pin_index[j]; i = crossover_get_stream_index(mod, config, pin_index); if (i < 0) { - comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %u", + comp_warn(dev, "could not assign sink %u", pin_index); break; } if (assigned_sinks[i]) { - comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pin %u are assigned", + comp_warn(dev, "multiple sinks from pin %u are assigned", pin_index); break; } @@ -113,7 +113,7 @@ void crossover_params(struct processing_module *mod) struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "crossover_params()"); + comp_dbg(dev, "entry"); ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); diff --git a/src/audio/dai-legacy.c b/src/audio/dai-legacy.c index 59e2caed95b9..11179334e6fe 100644 --- a/src/audio/dai-legacy.c +++ b/src/audio/dai-legacy.c @@ -41,8 +41,6 @@ LOG_MODULE_REGISTER(dai_comp, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(dai); -DECLARE_TR_CTX(dai_comp_tr, SOF_UUID(dai_uuid), LOG_LEVEL_INFO); - #if CONFIG_COMP_DAI_GROUP static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, int cmd); @@ -62,7 +60,7 @@ int dai_assign_group(struct dai_data *dd, struct comp_dev *dev, uint32_t group_i { if (dd->group) { if (dd->group->group_id != group_id) { - comp_err(dev, "dai_assign_group(), DAI already in group %d, requested %d", + comp_err(dev, "DAI already in group %d, requested %d", dd->group->group_id, group_id); return -EINVAL; } @@ -73,12 +71,12 @@ int dai_assign_group(struct dai_data *dd, struct comp_dev *dev, uint32_t group_i dd->group = dai_group_get(group_id, DAI_CREAT); if (!dd->group) { - comp_err(dev, "dai_assign_group(), failed to assign group %d", + comp_err(dev, "failed to assign group %d", group_id); return -EINVAL; } - comp_dbg(dev, "dai_assign_group(), group %d num %d", + comp_dbg(dev, "group %d num %d", group_id, dd->group->num_dais); /* Register for the atomic trigger event */ @@ -97,7 +95,7 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) uint32_t bytes = next->elem.size; int ret; - comp_dbg(dev, "dai_dma_cb()"); + comp_dbg(dev, "entry"); next->status = SOF_DMA_CB_STATUS_RELOAD; @@ -136,7 +134,7 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) dd->local_buffer : dd->dma_buffer; sink_c = dev->direction == SOF_IPC_STREAM_PLAYBACK ? dd->dma_buffer : dd->local_buffer; - comp_err(dev, "dai_dma_cb() dma buffer copy failed, dir %d bytes %d avail %d free %d", + comp_err(dev, "dma buffer copy failed, dir %d bytes %d avail %d free %d", dev->direction, bytes, audio_stream_get_avail_samples(&source_c->stream) * audio_stream_frame_bytes(&source_c->stream), @@ -198,7 +196,7 @@ static struct comp_dev *dai_new(const struct comp_driver *drv, dd = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*dd)); if (!dd) { - rfree(dev); + comp_free_device(dev); return NULL; } @@ -213,7 +211,7 @@ static struct comp_dev *dai_new(const struct comp_driver *drv, error: rfree(dd); - rfree(dev); + comp_free_device(dev); return NULL; } @@ -250,7 +248,7 @@ static void dai_free(struct comp_dev *dev) dai_common_free(dd); rfree(dd); - rfree(dev); + comp_free_device(dev); } int dai_common_get_hw_params(struct dai_data *dd, struct comp_dev *dev, @@ -293,7 +291,7 @@ static int dai_comp_hw_params(struct comp_dev *dev, struct dai_data *dd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "dai_comp_hw_params()"); + comp_dbg(dev, "entry"); /* configure hw dai stream params */ ret = dai_hw_params(dd->dai, params); @@ -371,7 +369,7 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes, config->is_scheduling_source = comp_is_scheduling_source(dev); config->period = dev->pipeline->period; - comp_info(dev, "dai_playback_params() dest_dev = %d stream_id = %d src_width = %d dest_width = %d", + comp_info(dev, "dest_dev = %d stream_id = %d src_width = %d dest_width = %d", config->dest_dev, dd->stream_id, config->src_width, config->dest_width); @@ -379,7 +377,7 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes, fifo = dai_get_fifo(dd->dai, dev->direction, dd->stream_id); - comp_info(dev, "dai_playback_params() fifo 0x%x", fifo); + comp_info(dev, "fifo 0x%x", fifo); err = dma_sg_alloc(&config->elem_array, SOF_MEM_FLAG_USER, config->direction, @@ -436,7 +434,7 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes, config->dest_width = config->src_width; } - comp_info(dev, "dai_capture_params() src_dev = %d stream_id = %d src_width = %d dest_width = %d", + comp_info(dev, "src_dev = %d stream_id = %d src_width = %d dest_width = %d", config->src_dev, dd->stream_id, config->src_width, config->dest_width); @@ -444,7 +442,7 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes, fifo = dai_get_fifo(dd->dai, dev->direction, dd->stream_id); - comp_info(dev, "dai_capture_params() fifo 0x%x", fifo); + comp_info(dev, "fifo 0x%x", fifo); err = dma_sg_alloc(&config->elem_array, SOF_MEM_FLAG_USER, config->direction, @@ -561,7 +559,8 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, return err; } } else { - dd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, + dd->dma_buffer = buffer_alloc(NULL, buffer_size, + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, addr_align, BUFFER_USAGE_NOT_SHARED); if (!dd->dma_buffer) { comp_err(dev, "failed to alloc dma buffer"); @@ -588,7 +587,7 @@ static int dai_params(struct comp_dev *dev, struct sof_ipc_stream_params *params { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_params()"); + comp_dbg(dev, "entry"); return dai_common_params(dd, dev, params); } @@ -615,7 +614,7 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev) } channel = dai_config_dma_channel(dd, dev, dd->dai_spec_config); - comp_info(dev, "dai_common_config_prepare(), channel = %d", channel); + comp_info(dev, "channel = %d", channel); /* do nothing for asking for channel free, for compatibility. */ if (channel == DMA_CHAN_INVALID) { @@ -683,7 +682,7 @@ static int dai_prepare(struct comp_dev *dev) struct dai_data *dd = comp_get_drvdata(dev); int ret; - comp_info(dev, "dai_prepare()"); + comp_info(dev, "entry"); ret = dai_common_config_prepare(dd, dev); if (ret < 0) @@ -726,7 +725,7 @@ static int dai_reset(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); - comp_info(dev, "dai_reset()"); + comp_info(dev, "entry"); dai_common_reset(dd, dev); @@ -740,7 +739,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, { int ret; - comp_dbg(dev, "dai_comp_trigger_internal(), command = %u", cmd); + comp_dbg(dev, "command = %u", cmd); ret = comp_set_state(dev, cmd); if (ret < 0) @@ -751,7 +750,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, switch (cmd) { case COMP_TRIGGER_START: - comp_dbg(dev, "dai_comp_trigger_internal(), START"); + comp_dbg(dev, "START"); /* only start the DAI if we are not XRUN handling */ if (dd->xrun == 0) { @@ -794,12 +793,12 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, platform_dai_wallclock(dev, &dd->wallclock); break; case COMP_TRIGGER_XRUN: - comp_info(dev, "dai_comp_trigger_internal(), XRUN"); + comp_info(dev, "XRUN"); dd->xrun = 1; COMPILER_FALLTHROUGH; case COMP_TRIGGER_STOP: - comp_dbg(dev, "dai_comp_trigger_internal(), STOP"); + comp_dbg(dev, "STOP"); /* * Some platforms cannot just simple disable * DMA channel during the transfer, @@ -817,7 +816,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, #endif break; case COMP_TRIGGER_PAUSE: - comp_dbg(dev, "dai_comp_trigger_internal(), PAUSE"); + comp_dbg(dev, "PAUSE"); ret = dma_pause_legacy(dd->chan); dai_trigger(dd->dai, cmd, dev->direction); break; @@ -842,7 +841,7 @@ int dai_common_trigger(struct dai_data *dd, struct comp_dev *dev, int cmd) /* DAI not in a group, use normal trigger */ if (!group) { - comp_dbg(dev, "dai_common_trigger(), non-atomic trigger"); + comp_dbg(dev, "non-atomic trigger"); return dai_comp_trigger_internal(dd, dev, cmd); } @@ -852,13 +851,13 @@ int dai_common_trigger(struct dai_data *dd, struct comp_dev *dev, int cmd) /* First DAI to receive the trigger command, * prepare for atomic trigger */ - comp_dbg(dev, "dai_common_trigger(), begin atomic trigger for group %d", + comp_dbg(dev, "begin atomic trigger for group %d", group->group_id); group->trigger_cmd = cmd; group->trigger_counter = group->num_dais - 1; } else if (group->trigger_cmd != cmd) { /* Already processing a different trigger command */ - comp_err(dev, "dai_common_trigger(), already processing atomic trigger"); + comp_err(dev, "already processing atomic trigger"); ret = -EAGAIN; } else { /* Count down the number of remaining DAIs required @@ -866,7 +865,7 @@ int dai_common_trigger(struct dai_data *dd, struct comp_dev *dev, int cmd) * takes place */ group->trigger_counter--; - comp_dbg(dev, "dai_common_trigger(), trigger counter %d, group %d", + comp_dbg(dev, "trigger counter %d, group %d", group->trigger_counter, group->group_id); if (!group->trigger_counter) { @@ -951,7 +950,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun copy_bytes = samples * sampling; - comp_dbg(dev, "dai_common_copy(), dir: %d copy_bytes= 0x%x, frames= %d", + comp_dbg(dev, "dir: %d copy_bytes= 0x%x, frames= %d", dev->direction, copy_bytes, samples / audio_stream_get_channels(&dd->local_buffer->stream)); @@ -989,7 +988,7 @@ static int dai_copy(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_copy()"); + comp_dbg(dev, "entry"); /* * DAI devices will only ever have 1 sink, so no need to pass an array of PCM converter @@ -1050,7 +1049,7 @@ static int dai_ts_start(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_ts_start()"); + comp_dbg(dev, "entry"); return dai_common_ts_start(dd, dev); } @@ -1067,7 +1066,7 @@ static int dai_ts_stop(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_ts_stop()"); + comp_dbg(dev, "entry"); return dai_common_ts_stop(dd, dev); } @@ -1084,7 +1083,7 @@ static int dai_ts_get(struct comp_dev *dev, struct timestamp_data *tsd) { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_ts_get()"); + comp_dbg(dev, "entry"); return dai_common_ts_get(dd, dev, tsd); } @@ -1104,6 +1103,8 @@ static uint64_t dai_get_processed_data(struct comp_dev *dev, uint32_t stream_no, return ret; } +DECLARE_TR_CTX(dai_comp_tr, SOF_UUID(dai_uuid), LOG_LEVEL_INFO); + static const struct comp_driver comp_dai = { .type = SOF_COMP_DAI, .uid = SOF_RT_UUID(dai_uuid), diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index ef1abb48cc31..e653e93ae082 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -64,8 +64,6 @@ LOG_MODULE_REGISTER(dai_comp, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(dai); -DECLARE_TR_CTX(dai_comp_tr, SOF_UUID(dai_uuid), LOG_LEVEL_INFO); - #if CONFIG_COMP_DAI_GROUP static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, int cmd); @@ -143,7 +141,7 @@ static int dai_trigger_op(struct dai *dai, int cmd, int direction) /* called from src/ipc/ipc3/handler.c and src/ipc/ipc4/dai.c */ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, - const void *spec_config) + const void *spec_config, size_t size) { const struct device *dev = dai->dev; const struct sof_ipc_dai_config *sof_cfg = spec_config; @@ -198,7 +196,7 @@ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, return -EINVAL; } - return dai_config_set(dev, &cfg, cfg_params); + return dai_config_set(dev, &cfg, cfg_params, size); } /* called from ipc/ipc3/dai.c */ @@ -263,7 +261,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, enum sof_dma_cb_status dma_status = SOF_DMA_CB_STATUS_RELOAD; int ret; - comp_dbg(dev, "dai_dma_cb()"); + comp_dbg(dev, "entry"); /* stop dma copy for pause/stop/xrun */ if (dev->state != COMP_STATE_ACTIVE || dd->xrun) { @@ -362,7 +360,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, sink_dev = comp_buffer_get_sink_component(sink); - j = IPC4_SINK_QUEUE_ID(buf_get_id(sink)); + j = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); if (j >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) { comp_err(dev, "Sink queue ID: %d >= max output pin count: %d\n", @@ -422,7 +420,7 @@ dai_dma_multi_endpoint_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t fr enum sof_dma_cb_status dma_status = SOF_DMA_CB_STATUS_RELOAD; uint32_t i, bytes; - comp_dbg(dev, "dai_dma_multi_endpoint_cb()"); + comp_dbg(dev, "entry"); /* stop dma copy for pause/stop/xrun */ if (dev->state != COMP_STATE_ACTIVE || dd->xrun) { @@ -591,7 +589,7 @@ __cold static struct comp_dev *dai_new(const struct comp_driver *drv, error: rfree(dd); e_data: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -607,7 +605,7 @@ __cold void dai_common_free(struct dai_data *dd) dai_group_put(dd->group); if (dd->chan) { - dma_release_channel(dd->dma->z_dev, dd->chan->index); + sof_dma_release_channel(dd->dma, dd->chan->index); dd->chan->dev_data = NULL; } @@ -632,7 +630,7 @@ __cold static void dai_free(struct comp_dev *dev) dai_common_free(dd); rfree(dd); - rfree(dev); + comp_free_device(dev); } int dai_common_get_hw_params(struct dai_data *dd, struct comp_dev *dev, @@ -641,7 +639,7 @@ int dai_common_get_hw_params(struct dai_data *dd, struct comp_dev *dev, struct dai_config cfg; int ret; - comp_dbg(dev, "dai_common_get_hw_params()"); + comp_dbg(dev, "entry"); ret = dai_config_get(dd->dai->dev, &cfg, dir); if (ret) @@ -683,7 +681,7 @@ static int dai_verify_params(struct dai_data *dd, struct comp_dev *dev, ret = dai_common_get_hw_params(dd, dev, &hw_params, params->direction); if (ret < 0) { - comp_err(dev, "dai_verify_params failed ret %d", ret); + comp_err(dev, "failed ret %d", ret); return ret; } @@ -798,7 +796,7 @@ static int dai_set_sg_config(struct dai_data *dd, struct comp_dev *dev, uint32_t comp_dbg(dev, "fifo 0x%x", fifo); - err = dma_get_attribute(dd->dma->z_dev, DMA_ATTR_MAX_BLOCK_COUNT, &max_block_count); + err = sof_dma_get_attribute(dd->dma, DMA_ATTR_MAX_BLOCK_COUNT, &max_block_count); if (err < 0) { comp_err(dev, "can't get max block count, err = %d", err); @@ -850,7 +848,7 @@ static int dai_set_dma_config(struct dai_data *dd, struct comp_dev *dev) struct dma_block_config *prev = NULL; int i; - comp_dbg(dev, "dai_set_dma_config()"); + comp_dbg(dev, "entry"); dma_cfg = rballoc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, sizeof(struct dma_config)); @@ -934,7 +932,7 @@ static int dai_set_dma_buffer(struct dai_data *dd, struct comp_dev *dev, uint32_t align; int err; - comp_dbg(dev, "dai_set_dma_buffer()"); + comp_dbg(dev, "entry"); if (dev->direction == SOF_IPC_STREAM_PLAYBACK) dd->local_buffer = comp_dev_get_first_data_producer(dev); @@ -954,14 +952,14 @@ static int dai_set_dma_buffer(struct dai_data *dd, struct comp_dev *dev, return -EINVAL; } - err = dma_get_attribute(dd->dma->z_dev, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, &addr_align); + err = sof_dma_get_attribute(dd->dma, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, &addr_align); if (err < 0) { comp_err(dev, "can't get dma buffer addr align, err = %d", err); return err; } - err = dma_get_attribute(dd->dma->z_dev, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, &align); + err = sof_dma_get_attribute(dd->dma, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, &align); if (err < 0 || !align) { comp_err(dev, "no valid dma align, err = %d, align = %u", err, align); @@ -1019,7 +1017,7 @@ static int dai_set_dma_buffer(struct dai_data *dd, struct comp_dev *dev, return err; } } else { - dd->dma_buffer = buffer_alloc_range(buffer_size_preferred, buffer_size, + dd->dma_buffer = buffer_alloc_range(NULL, buffer_size_preferred, buffer_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, addr_align, BUFFER_USAGE_NOT_SHARED); if (!dd->dma_buffer) { @@ -1119,7 +1117,7 @@ static int dai_params(struct comp_dev *dev, struct sof_ipc_stream_params *params { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_params()"); + comp_dbg(dev, "entry"); return dai_common_params(dd, dev, params); } @@ -1155,7 +1153,7 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev) } /* get DMA channel */ - channel = dma_request_channel(dd->dma->z_dev, &channel); + channel = sof_dma_request_channel(dd->dma, channel); if (channel < 0) { comp_err(dev, "dma_request_channel() failed"); dd->chan = NULL; @@ -1199,7 +1197,7 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev) return 0; } - ret = dma_config(dd->chan->dma->z_dev, dd->chan->index, dd->z_config); + ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config); if (ret < 0) comp_set_state(dev, COMP_TRIGGER_RESET); @@ -1211,7 +1209,7 @@ static int dai_prepare(struct comp_dev *dev) struct dai_data *dd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "dai_prepare()"); + comp_dbg(dev, "entry"); ret = dai_common_config_prepare(dd, dev); if (ret < 0) @@ -1259,7 +1257,7 @@ static int dai_reset(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); - comp_dbg(dev, "dai_reset()"); + comp_dbg(dev, "entry"); dai_common_reset(dd, dev); @@ -1286,7 +1284,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, /* only start the DAI if we are not XRUN handling */ if (dd->xrun == 0) { - ret = dma_start(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_start(dd->chan->dma, dd->chan->index); if (ret < 0) return ret; @@ -1324,16 +1322,16 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, /* only start the DAI if we are not XRUN handling */ if (dd->xrun == 0) { /* recover valid start position */ - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_stop(dd->chan->dma, dd->chan->index); if (ret < 0) return ret; /* dma_config needed after stop */ - ret = dma_config(dd->chan->dma->z_dev, dd->chan->index, dd->z_config); + ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config); if (ret < 0) return ret; - ret = dma_start(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_start(dd->chan->dma, dd->chan->index); if (ret < 0) return ret; @@ -1361,11 +1359,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, * as soon as possible. */ #if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_stop(dd->chan->dma, dd->chan->index); dai_trigger_op(dd->dai, cmd, dev->direction); #else dai_trigger_op(dd->dai, cmd, dev->direction); - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_stop(dd->chan->dma, dd->chan->index); if (ret) { comp_warn(dev, "dma was stopped earlier"); ret = 0; @@ -1375,11 +1373,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, case COMP_TRIGGER_PAUSE: comp_dbg(dev, "PAUSE"); #if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE - ret = dma_suspend(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_suspend(dd->chan->dma, dd->chan->index); dai_trigger_op(dd->dai, cmd, dev->direction); #else dai_trigger_op(dd->dai, cmd, dev->direction); - ret = dma_suspend(dd->chan->dma->z_dev, dd->chan->index); + ret = sof_dma_suspend(dd->chan->dma, dd->chan->index); #endif break; case COMP_TRIGGER_PRE_START: @@ -1468,10 +1466,16 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) return dai_common_trigger(dd, dev, cmd); } -/* get status from dma and check for xrun */ +/** + * Get status from the DMA driver. + * + * After status call, a check for xrun condition is done and + * depending on configuration, a xrun report is optionally sent. + * See also xrun reporting done in dai_report_reload_xrun(). + */ static int dai_get_status(struct comp_dev *dev, struct dai_data *dd, struct dma_status *stat) { - int ret = dma_get_status(dd->chan->dma->z_dev, dd->chan->index, stat); + int ret = sof_dma_get_status(dd->chan->dma, dd->chan->index, stat); #if CONFIG_XRUN_NOTIFICATIONS_ENABLE if (ret == -EPIPE && !dd->xrun_notification_sent) { struct ipc_msg *notify = ipc_notification_pool_get(IPC4_RESOURCE_EVENT_SIZE); @@ -1494,8 +1498,13 @@ static int dai_get_status(struct comp_dev *dev, struct dai_data *dd, struct dma_ return ret; } -/* report xrun occurrence */ -static void dai_report_xrun(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes) +/** + * Report xrun occurrence after DAI DMA driver reports + * an error for a reload attempt of 'bytes' of data. + * + * See also xrun detection done in dai_get_status(). + */ +static void dai_report_reload_xrun(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes) { if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { comp_err(dev, "underrun due to no data available"); @@ -1582,9 +1591,9 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, #endif for (i = 0; i < num_endpoints; i++) { - ret = dma_reload(dd[i]->chan->dma->z_dev, dd[i]->chan->index, 0, 0, 0); + ret = sof_dma_reload(dd[i]->chan->dma, dd[i]->chan->index, 0); if (ret < 0) { - dai_report_xrun(dd[i], dev, 0); + dai_report_reload_xrun(dd[i], dev, 0); return ret; } } @@ -1608,12 +1617,12 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, status = dai_dma_multi_endpoint_cb(dd[i], dev, frames, multi_endpoint_buffer); if (status == SOF_DMA_CB_STATUS_END) - dma_stop(dd[i]->chan->dma->z_dev, dd[i]->chan->index); + sof_dma_stop(dd[i]->chan->dma, dd[i]->chan->index); copy_bytes = frames * audio_stream_frame_bytes(&dd[i]->dma_buffer->stream); - ret = dma_reload(dd[i]->chan->dma->z_dev, dd[i]->chan->index, 0, 0, copy_bytes); + ret = sof_dma_reload(dd[i]->chan->dma, dd[i]->chan->index, copy_bytes); if (ret < 0) { - dai_report_xrun(dd[i], dev, copy_bytes); + dai_report_reload_xrun(dd[i], dev, copy_bytes); return ret; } @@ -1800,7 +1809,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun comp_warn(dev, "nothing to copy, src_frames: %u, sink_frames: %u", src_frames, sink_frames); #endif - dma_reload(dd->chan->dma->z_dev, dd->chan->index, 0, 0, 0); + sof_dma_reload(dd->chan->dma, dd->chan->index, 0); return 0; } @@ -1810,11 +1819,11 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun comp_warn(dev, "dai trigger copy failed"); if (dai_dma_cb(dd, dev, copy_bytes, converter) == SOF_DMA_CB_STATUS_END) - dma_stop(dd->chan->dma->z_dev, dd->chan->index); + sof_dma_stop(dd->chan->dma, dd->chan->index); - ret = dma_reload(dd->chan->dma->z_dev, dd->chan->index, 0, 0, copy_bytes); + ret = sof_dma_reload(dd->chan->dma, dd->chan->index, copy_bytes); if (ret < 0) { - dai_report_xrun(dd, dev, copy_bytes); + dai_report_reload_xrun(dd, dev, copy_bytes); return ret; } @@ -1984,6 +1993,8 @@ int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, struct bind_inf } #endif /* CONFIG_IPC_MAJOR_4 */ +DECLARE_TR_CTX(dai_comp_tr, SOF_UUID(dai_uuid), LOG_LEVEL_INFO); + static const struct comp_driver comp_dai = { .type = SOF_COMP_DAI, .uid = SOF_RT_UUID(dai_uuid), diff --git a/src/audio/data_blob.c b/src/audio/data_blob.c index 42d612fb3104..399244106f95 100644 --- a/src/audio/data_blob.c +++ b/src/audio/data_blob.c @@ -110,7 +110,7 @@ bool comp_is_new_data_blob_available(struct comp_data_blob_handler { assert(blob_handler); - comp_dbg(blob_handler->dev, "comp_is_new_data_blob_available()"); + comp_dbg(blob_handler->dev, "entry"); /* New data blob is available when new data blob is allocated (data_new * is not NULL), and the component has received all required chunks of data @@ -185,25 +185,25 @@ int comp_data_blob_set(struct comp_data_blob_handler *blob_handler, #if CONFIG_IPC_MAJOR_3 if (cdata->cmd != SOF_CTRL_CMD_BINARY) { - comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), illegal control command"); + comp_err(blob_handler->dev, "illegal control command"); return -EINVAL; } #endif - comp_dbg(blob_handler->dev, "comp_data_blob_set_cmd() pos = %d, fragment size = %zu", + comp_dbg(blob_handler->dev, "pos = %d, fragment size = %zu", pos, fragment_size); /* Check that there is no work-in-progress previous request */ if (blob_handler->data_new && (pos == MODULE_CFG_FRAGMENT_FIRST || pos == MODULE_CFG_FRAGMENT_SINGLE)) { - comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), busy with previous request"); + comp_err(blob_handler->dev, "busy with previous request"); return -EBUSY; } /* In single blob mode the component can not be reconfigured if the component is active. */ if (blob_handler->single_blob && blob_handler->dev->state == COMP_STATE_ACTIVE) { - comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), on the fly updates forbidden in single blob mode"); + comp_err(blob_handler->dev, "on the fly updates forbidden in single blob mode"); return -EBUSY; } @@ -441,13 +441,13 @@ int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler, assert(blob_handler); - comp_dbg(blob_handler->dev, "comp_data_blob_set_cmd() msg_index = %d, num_elems = %d, remaining = %d ", + comp_dbg(blob_handler->dev, "msg_index = %d, num_elems = %d, remaining = %d ", cdata->msg_index, cdata->num_elems, cdata->elems_remaining); /* Check that there is no work-in-progress previous request */ if (blob_handler->data_new && cdata->msg_index == 0) { - comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), busy with previous request"); + comp_err(blob_handler->dev, "busy with previous request"); return -EBUSY; } @@ -456,7 +456,7 @@ int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler, */ if (blob_handler->single_blob && blob_handler->dev->state == COMP_STATE_ACTIVE) { - comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), on the fly updates forbidden in single blob mode"); + comp_err(blob_handler->dev, "on the fly updates forbidden in single blob mode"); return -EBUSY; } @@ -581,7 +581,7 @@ int comp_data_blob_get_cmd(struct comp_data_blob_handler *blob_handler, return -EINVAL; } - comp_dbg(blob_handler->dev, "comp_data_blob_get_cmd() msg_index = %d, num_elems = %d, remaining = %d ", + comp_dbg(blob_handler->dev, "msg_index = %d, num_elems = %d, remaining = %d ", cdata->msg_index, cdata->num_elems, cdata->elems_remaining); @@ -590,7 +590,7 @@ int comp_data_blob_get_cmd(struct comp_data_blob_handler *blob_handler, /* reset data_pos variable in case of copying first element */ if (!cdata->msg_index) { blob_handler->data_pos = 0; - comp_dbg(blob_handler->dev, "comp_data_blob_get_cmd() model data_size = 0x%x", + comp_dbg(blob_handler->dev, "model data_size = 0x%x", blob_handler->data_size); } @@ -639,7 +639,7 @@ comp_data_blob_handler_new_ext(struct comp_dev *dev, bool single_blob, { struct comp_data_blob_handler *handler; - comp_dbg(dev, "comp_data_blob_handler_new_ext()"); + comp_dbg(dev, "entry"); handler = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct comp_data_blob_handler)); diff --git a/src/audio/dcblock/dcblock.c b/src/audio/dcblock/dcblock.c index d266f357554f..ea4159dcd432 100644 --- a/src/audio/dcblock/dcblock.c +++ b/src/audio/dcblock/dcblock.c @@ -36,8 +36,6 @@ LOG_MODULE_REGISTER(dcblock, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(dcblock); -DECLARE_TR_CTX(dcblock_tr, SOF_UUID(dcblock_uuid), LOG_LEVEL_INFO); - /** * \brief Sets the DC Blocking filter in pass through mode. * The frequency response of a DCB filter is: @@ -48,7 +46,7 @@ static void dcblock_set_passthrough(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "dcblock_set_passthrough()"); + comp_info(mod->dev, "entry"); int i; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -87,7 +85,7 @@ static int dcblock_init(struct processing_module *mod) size_t bs = ipc_dcblock->size; int ret; - comp_info(dev, "dcblock_init()"); + comp_info(dev, "entry"); cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); if (!cd) @@ -128,7 +126,7 @@ static int dcblock_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "dcblock_free()"); + comp_info(mod->dev, "entry"); comp_data_blob_handler_free(cd->model_handler); rfree(cd); return 0; @@ -172,7 +170,7 @@ static int dcblock_process(struct processing_module *mod, struct audio_stream *sink = output_buffers[0].data; uint32_t frames = input_buffers[0].size; - comp_dbg(mod->dev, "dcblock_process()"); + comp_dbg(mod->dev, "entry"); cd->dcblock_func(cd, source, sink, frames); @@ -193,7 +191,7 @@ static int dcblock_prepare(struct processing_module *mod, struct comp_buffer *sourceb, *sinkb; struct comp_dev *dev = mod->dev; - comp_info(dev, "dcblock_prepare()"); + comp_info(dev, "entry"); /* DC Filter component will only ever have one source and sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); @@ -214,11 +212,11 @@ static int dcblock_prepare(struct processing_module *mod, dcblock_init_state(cd); cd->dcblock_func = dcblock_find_func(cd->source_format); if (!cd->dcblock_func) { - comp_err(dev, "dcblock_prepare(), No processing function matching frames format"); + comp_err(dev, "No processing function matching frames format"); return -EINVAL; } - comp_info(mod->dev, "dcblock_prepare(), source_format=%d, sink_format=%d", + comp_info(mod->dev, "source_format=%d, sink_format=%d", cd->source_format, cd->sink_format); cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); @@ -239,7 +237,7 @@ static int dcblock_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "dcblock_reset()"); + comp_info(mod->dev, "entry"); dcblock_init_state(cd); @@ -272,6 +270,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(dcblock_tr, SOF_UUID(dcblock_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(dcblock_interface, dcblock_uuid, dcblock_tr); SOF_MODULE_INIT(dcblock, sys_comp_module_dcblock_interface_init); diff --git a/src/audio/dcblock/dcblock_ipc4.c b/src/audio/dcblock/dcblock_ipc4.c index d8030126a270..c375d11ec042 100644 --- a/src/audio/dcblock/dcblock_ipc4.c +++ b/src/audio/dcblock/dcblock_ipc4.c @@ -30,7 +30,7 @@ int dcblock_get_ipc_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "dcblock_get_ipc_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -44,7 +44,7 @@ int dcblock_set_ipc_config(struct processing_module *mod, { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "dcblock_set_ipc_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -56,7 +56,7 @@ void dcblock_params(struct processing_module *mod) struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "dcblock_params()"); + comp_dbg(dev, "entry"); ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index 6219f54c8842..3627b03b3a47 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -43,11 +42,11 @@ extern const struct sof_uuid drc_uuid; extern struct tr_ctx drc_tr; /* Called from drc_setup() from drc_process(), so cannot be __cold */ -void drc_reset_state(struct drc_state *state) +void drc_reset_state(struct processing_module *mod, struct drc_state *state) { int i; - rfree(state->pre_delay_buffers[0]); + mod_free(mod, state->pre_delay_buffers[0]); for (i = 0; i < PLATFORM_MAX_CHANNELS; ++i) { state->pre_delay_buffers[i] = NULL; } @@ -67,7 +66,8 @@ void drc_reset_state(struct drc_state *state) state->max_attack_compression_diff_db = INT32_MIN; } -int drc_init_pre_delay_buffers(struct drc_state *state, +int drc_init_pre_delay_buffers(struct processing_module *mod, + struct drc_state *state, size_t sample_bytes, int channels) { @@ -76,7 +76,7 @@ int drc_init_pre_delay_buffers(struct drc_state *state, int i; /* Allocate pre-delay (lookahead) buffers */ - state->pre_delay_buffers[0] = rballoc(SOF_MEM_FLAG_USER, bytes_total); + state->pre_delay_buffers[0] = mod_balloc(mod, bytes_total); if (!state->pre_delay_buffers[0]) return -ENOMEM; @@ -121,16 +121,17 @@ int drc_set_pre_delay_time(struct drc_state *state, } /* Called from drc_process(), so cannot be __cold */ -static int drc_setup(struct drc_comp_data *cd, uint16_t channels, uint32_t rate) +static int drc_setup(struct processing_module *mod, uint16_t channels, uint32_t rate) { + struct drc_comp_data *cd = module_get_private_data(mod); uint32_t sample_bytes = get_sample_bytes(cd->source_format); int ret; /* Reset any previous state */ - drc_reset_state(&cd->state); + drc_reset_state(mod, &cd->state); /* Allocate pre-delay buffers */ - ret = drc_init_pre_delay_buffers(&cd->state, (size_t)sample_bytes, (int)channels); + ret = drc_init_pre_delay_buffers(mod, &cd->state, (size_t)sample_bytes, (int)channels); if (ret < 0) return ret; @@ -153,27 +154,27 @@ __cold static int drc_init(struct processing_module *mod) assert_can_be_cold(); - comp_info(dev, "drc_init()"); + comp_info(dev, "entry"); /* Check first before proceeding with dev and cd that coefficients * blob size is sane. */ if (bs > SOF_DRC_MAX_SIZE) { - comp_err(dev, "drc_init(), error: configuration blob size = %u > %d", + comp_err(dev, "error: configuration blob size = %u > %d", bs, SOF_DRC_MAX_SIZE); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; md->private = cd; /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto cd_fail; } @@ -185,7 +186,7 @@ __cold static int drc_init(struct processing_module *mod) goto cd_fail; } - drc_reset_state(&cd->state); + drc_reset_state(mod, &cd->state); /* Initialize DRC to enabled. If defined by topology, a control may set * enabled to false before prepare() or during streaming with the switch @@ -196,8 +197,8 @@ __cold static int drc_init(struct processing_module *mod) return 0; cd_fail: - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -207,8 +208,8 @@ __cold static int drc_free(struct processing_module *mod) assert_can_be_cold(); - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return 0; } @@ -222,7 +223,7 @@ __cold static int drc_set_config(struct processing_module *mod, uint32_t param_i assert_can_be_cold(); - comp_dbg(dev, "drc_set_config()"); + comp_dbg(dev, "entry"); #if CONFIG_IPC_MAJOR_4 struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; @@ -232,7 +233,7 @@ __cold static int drc_set_config(struct processing_module *mod, uint32_t param_i if (ctl->id == SOF_DRC_CTRL_INDEX_ENABLE_SWITCH && ctl->num_elems == SOF_DRC_NUM_ELEMS_ENABLE_SWITCH) { cd->enable_switch = ctl->chanv[0].value; - comp_info(dev, "drc_set_config(), enable_switch = %d", cd->enable_switch); + comp_info(dev, "enable_switch = %d", cd->enable_switch); } else { comp_err(dev, "Illegal switch control id = %d, num_elems = %d", ctl->id, ctl->num_elems); @@ -242,12 +243,12 @@ __cold static int drc_set_config(struct processing_module *mod, uint32_t param_i return 0; case SOF_IPC4_ENUM_CONTROL_PARAM_ID: - comp_err(dev, "drc_set_config(), illegal control."); + comp_err(dev, "illegal control."); return -EINVAL; } #endif - comp_info(dev, "drc_set_config(), bytes control"); + comp_info(dev, "bytes control"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); } @@ -261,7 +262,7 @@ __cold static int drc_get_config(struct processing_module *mod, assert_can_be_cold(); - comp_info(mod->dev, "drc_get_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -279,12 +280,12 @@ static int drc_process(struct processing_module *mod, int frames = input_buffers[0].size; int ret; - comp_dbg(dev, "drc_process()"); + comp_dbg(dev, "entry"); /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); - ret = drc_setup(cd, audio_stream_get_channels(source), + ret = drc_setup(mod, audio_stream_get_channels(source), audio_stream_get_rate(source)); if (ret < 0) { comp_err(dev, "drc_copy(), failed DRC setup"); @@ -321,7 +322,7 @@ static void drc_params(struct processing_module *mod) struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "drc_params()"); + comp_dbg(dev, "entry"); ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); @@ -347,7 +348,7 @@ static int drc_prepare(struct processing_module *mod, int rate; int ret; - comp_info(dev, "drc_prepare()"); + comp_info(dev, "entry"); /* DRC component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); @@ -367,18 +368,18 @@ static int drc_prepare(struct processing_module *mod, rate = audio_stream_get_rate(&sinkb->stream); /* Initialize DRC */ - comp_info(dev, "drc_prepare(), source_format=%d", cd->source_format); + comp_info(dev, "source_format=%d", cd->source_format); cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); if (cd->config) { - ret = drc_setup(cd, channels, rate); + ret = drc_setup(mod, channels, rate); if (ret < 0) { - comp_err(dev, "drc_prepare() error: drc_setup failed."); + comp_err(dev, "error: drc_setup failed."); return ret; } cd->drc_func = drc_find_proc_func(cd->source_format); if (!cd->drc_func) { - comp_err(dev, "drc_prepare(), No proc func"); + comp_err(dev, "No proc func"); return -EINVAL; } @@ -395,7 +396,7 @@ static int drc_prepare(struct processing_module *mod, cd->drc_func = drc_default_pass; } - comp_info(dev, "drc_prepare(), DRC is configured."); + comp_info(dev, "DRC is configured."); return 0; } @@ -403,7 +404,7 @@ static int drc_reset(struct processing_module *mod) { struct drc_comp_data *cd = module_get_private_data(mod); - drc_reset_state(&cd->state); + drc_reset_state(mod, &cd->state); return 0; } diff --git a/src/audio/drc/drc_algorithm.h b/src/audio/drc/drc_algorithm.h index c0a942b09622..8d9d759eb3a8 100644 --- a/src/audio/drc/drc_algorithm.h +++ b/src/audio/drc/drc_algorithm.h @@ -14,10 +14,11 @@ #include "drc.h" /* drc reset function */ -void drc_reset_state(struct drc_state *state); +void drc_reset_state(struct processing_module *mod, struct drc_state *state); /* drc init functions */ -int drc_init_pre_delay_buffers(struct drc_state *state, +int drc_init_pre_delay_buffers(struct processing_module *mod, + struct drc_state *state, size_t sample_bytes, int channels); int drc_set_pre_delay_time(struct drc_state *state, diff --git a/src/audio/drc/drc_log.c b/src/audio/drc/drc_log.c index 63c88e65101a..f16feaabcedd 100644 --- a/src/audio/drc/drc_log.c +++ b/src/audio/drc/drc_log.c @@ -10,6 +10,4 @@ SOF_DEFINE_REG_UUID(drc); LOG_MODULE_REGISTER(drc, CONFIG_SOF_LOG_LEVEL); DECLARE_TR_CTX(drc_tr, SOF_UUID(drc_uuid), LOG_LEVEL_INFO); -EXPORT_SYMBOL(drc_tr); -EXPORT_SYMBOL(drc_uuid); EXPORT_SYMBOL(log_const_drc); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index ed946157ed4c..167debe03570 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -41,8 +40,6 @@ LOG_MODULE_REGISTER(eq_fir, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(eq_fir); -DECLARE_TR_CTX(eq_fir_tr, SOF_UUID(eq_fir_uuid), LOG_LEVEL_INFO); - /* Pass-through functions to replace FIR core while not configured for * response. */ @@ -58,15 +55,16 @@ static void eq_fir_passthrough(struct fir_state_32x16 fir[], audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source)); } -static void eq_fir_free_delaylines(struct comp_data *cd) +static void eq_fir_free_delaylines(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); struct fir_state_32x16 *fir = cd->fir; int i = 0; /* Free the common buffer for all EQs and point then * each FIR channel delay line to NULL. */ - rfree(cd->fir_delay); + mod_free(mod, cd->fir_delay); cd->fir_delay = NULL; cd->fir_delay_size = 0; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -106,11 +104,11 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf if (nch > PLATFORM_MAX_CHANNELS || config->channels_in_config > PLATFORM_MAX_CHANNELS || !config->channels_in_config) { - comp_err(dev, "eq_fir_init_coef(), invalid channels count"); + comp_err(dev, "invalid channels count"); return -EINVAL; } if (config->number_of_responses > SOF_EQ_FIR_MAX_RESPONSES) { - comp_err(dev, "eq_fir_init_coef(), # of resp exceeds max"); + comp_err(dev, "# of resp exceeds max"); return -EINVAL; } @@ -145,14 +143,14 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf * next channel response. */ if (fir) { - comp_info(dev, "eq_fir_init_coef(), ch %d is set to bypass", i); + comp_info(dev, "ch %d is set to bypass", i); fir_reset(&fir[i]); } continue; } if (resp >= config->number_of_responses) { - comp_err(dev, "eq_fir_init_coef(), requested response %d exceeds what has been defined", + comp_err(dev, "requested response %d exceeds what has been defined", resp); return -EINVAL; } @@ -163,7 +161,7 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf if (s > 0) { size_sum += s; } else { - comp_info(dev, "eq_fir_init_coef(), FIR length %d is invalid", eq->length); + comp_info(dev, "FIR length %d is invalid", eq->length); return -EINVAL; } @@ -177,7 +175,7 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf if (fir) { fir_init_coef(&fir[i], eq); - comp_info(dev, "eq_fir_init_coef(), ch %d is set to response = %d", + comp_info(dev, "ch %d is set to response = %d", i, resp); } } @@ -198,12 +196,14 @@ static void eq_fir_init_delay(struct fir_state_32x16 *fir, } } -static int eq_fir_setup(struct comp_dev *dev, struct comp_data *cd, int nch) +static int eq_fir_setup(struct processing_module *mod, int nch) { + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int delay_size; /* Free existing FIR channels data if it was allocated */ - eq_fir_free_delaylines(cd); + eq_fir_free_delaylines(mod); /* Update number of channels */ cd->nch = nch; @@ -220,9 +220,9 @@ static int eq_fir_setup(struct comp_dev *dev, struct comp_data *cd, int nch) return 0; /* Allocate all FIR channels data in a big chunk and clear it */ - cd->fir_delay = rballoc(SOF_MEM_FLAG_USER, delay_size); + cd->fir_delay = mod_balloc(mod, delay_size); if (!cd->fir_delay) { - comp_err(dev, "eq_fir_setup(), delay allocation failed for size %d", delay_size); + comp_err(dev, "delay allocation failed for size %d", delay_size); return -ENOMEM; } @@ -253,7 +253,7 @@ static int eq_fir_init(struct processing_module *mod) int i; int ret; - comp_info(dev, "eq_fir_init()"); + comp_info(dev, "entry"); /* Check first before proceeding with dev and cd that coefficients * blob size is sane. @@ -264,7 +264,7 @@ static int eq_fir_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -274,9 +274,9 @@ static int eq_fir_init(struct processing_module *mod) cd->nch = -1; /* component model data handler */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto err; } @@ -298,9 +298,9 @@ static int eq_fir_init(struct processing_module *mod) return 0; err_init: - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); err: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -308,12 +308,12 @@ static int eq_fir_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "eq_fir_free()"); + comp_dbg(mod->dev, "entry"); - eq_fir_free_delaylines(cd); - comp_data_blob_handler_free(cd->model_handler); + eq_fir_free_delaylines(mod); + mod_data_blob_handler_free(mod, cd->model_handler); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -325,7 +325,7 @@ static int eq_fir_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "eq_fir_get_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -337,7 +337,7 @@ static int eq_fir_set_config(struct processing_module *mod, uint32_t config_id, { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "eq_fir_set_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -355,23 +355,23 @@ static int eq_fir_process(struct processing_module *mod, uint32_t frame_count = input_buffers[0].size; int ret; - comp_dbg(mod->dev, "eq_fir_process()"); + comp_dbg(mod->dev, "entry"); /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); - ret = eq_fir_setup(mod->dev, cd, audio_stream_get_channels(source)); + ret = eq_fir_setup(mod, audio_stream_get_channels(source)); if (ret < 0) { - comp_err(mod->dev, "eq_fir_process(), failed FIR setup"); + comp_err(mod->dev, "failed FIR setup"); return ret; } else if (cd->fir_delay_size) { - comp_dbg(mod->dev, "eq_fir_process(), active"); + comp_dbg(mod->dev, "active"); ret = set_fir_func(mod, audio_stream_get_frm_fmt(source)); if (ret < 0) return ret; } else { cd->eq_fir_func = eq_fir_passthrough; - comp_dbg(mod->dev, "eq_fir_process(), pass-through"); + comp_dbg(mod->dev, "pass-through"); } } @@ -414,7 +414,7 @@ static int eq_fir_prepare(struct processing_module *mod, enum sof_ipc_frame frame_fmt; int ret = 0; - comp_dbg(dev, "eq_fir_prepare()"); + comp_dbg(dev, "entry"); /* EQ component will only ever have 1 source and 1 sink buffer. */ sourceb = comp_dev_get_first_data_producer(dev); @@ -437,7 +437,7 @@ static int eq_fir_prepare(struct processing_module *mod, cd->eq_fir_func = eq_fir_passthrough; cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); if (cd->config) { - ret = eq_fir_setup(dev, cd, channels); + ret = eq_fir_setup(mod, channels); if (ret < 0) comp_err(dev, "eq_fir_setup failed."); else if (cd->fir_delay_size) @@ -460,11 +460,11 @@ static int eq_fir_reset(struct processing_module *mod) int i; struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "eq_fir_reset()"); + comp_dbg(mod->dev, "entry"); comp_data_blob_set_validator(cd->model_handler, NULL); - eq_fir_free_delaylines(cd); + eq_fir_free_delaylines(mod); cd->eq_fir_func = NULL; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -497,6 +497,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(eq_fir_tr, SOF_UUID(eq_fir_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(eq_fir_interface, eq_fir_uuid, eq_fir_tr); SOF_MODULE_INIT(eq_fir, sys_comp_module_eq_fir_interface_init); diff --git a/src/audio/eq_fir/eq_fir_ipc3.c b/src/audio/eq_fir/eq_fir_ipc3.c index 5b5c7e48c675..ecfd873ffd7f 100644 --- a/src/audio/eq_fir/eq_fir_ipc3.c +++ b/src/audio/eq_fir/eq_fir_ipc3.c @@ -23,24 +23,24 @@ int set_fir_func(struct processing_module *mod, enum sof_ipc_frame fmt) switch (fmt) { #if CONFIG_FORMAT_S16LE case SOF_IPC_FRAME_S16_LE: - comp_dbg(mod->dev, "set_fir_func(), SOF_IPC_FRAME_S16_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S16_LE"); set_s16_fir(cd); break; #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE case SOF_IPC_FRAME_S24_4LE: - comp_dbg(mod->dev, "set_fir_func(), SOF_IPC_FRAME_S24_4LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S24_4LE"); set_s24_fir(cd); break; #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE case SOF_IPC_FRAME_S32_LE: - comp_dbg(mod->dev, "set_fir_func(), SOF_IPC_FRAME_S32_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S32_LE"); set_s32_fir(cd); break; #endif /* CONFIG_FORMAT_S32LE */ default: - comp_err(mod->dev, "set_fir_func(), invalid frame_fmt"); + comp_err(mod->dev, "invalid frame_fmt"); return -EINVAL; } return 0; diff --git a/src/audio/eq_fir/eq_fir_ipc4.c b/src/audio/eq_fir/eq_fir_ipc4.c index 74cda9752f6f..64ec2895e0dd 100644 --- a/src/audio/eq_fir/eq_fir_ipc4.c +++ b/src/audio/eq_fir/eq_fir_ipc4.c @@ -42,7 +42,7 @@ int set_fir_func(struct processing_module *mod, enum sof_ipc_frame fmt) break; #endif /* CONFIG_FORMAT_S32LE */ default: - comp_err(mod->dev, "set_fir_func(), invalid valid_bith_depth"); + comp_err(mod->dev, "invalid valid_bith_depth"); return -EINVAL; } return 0; @@ -54,7 +54,7 @@ int eq_fir_params(struct processing_module *mod) struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "eq_fir_params()"); + comp_dbg(dev, "entry"); ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 4b70fe355c77..ecce61521bc1 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -38,8 +37,6 @@ LOG_MODULE_REGISTER(eq_iir, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(eq_iir); -DECLARE_TR_CTX(eq_iir_tr, SOF_UUID(eq_iir_uuid), LOG_LEVEL_INFO); - /* * End of EQ setup code. Next the standard component methods. */ @@ -52,24 +49,24 @@ static int eq_iir_init(struct processing_module *mod) size_t bs = cfg->size; int i, ret; - comp_info(dev, "eq_iir_init()"); + comp_info(dev, "entry"); /* Check first before proceeding with dev and cd that coefficients blob size is sane */ if (bs > SOF_EQ_IIR_MAX_SIZE) { - comp_err(dev, "eq_iir_init(), coefficients blob size %zu exceeds maximum", bs); + comp_err(dev, "coefficients blob size %zu exceeds maximum", bs); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; md->private = cd; /* component model data handler */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto err; } @@ -80,7 +77,6 @@ static int eq_iir_init(struct processing_module *mod) ret = comp_init_data_blob(cd->model_handler, bs, cfg->data); if (ret < 0) { comp_err(dev, "comp_init_data_blob() failed with error: %d", ret); - comp_data_blob_handler_free(cd->model_handler); goto err; } @@ -88,8 +84,10 @@ static int eq_iir_init(struct processing_module *mod) iir_reset_df1(&cd->iir[i]); return 0; + err: - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -97,10 +95,10 @@ static int eq_iir_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - eq_iir_free_delaylines(cd); - comp_data_blob_handler_free(cd->model_handler); + eq_iir_free_delaylines(mod); + mod_data_blob_handler_free(mod, cd->model_handler); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -113,7 +111,7 @@ static int eq_iir_set_config(struct processing_module *mod, uint32_t config_id, { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "eq_iir_set_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -126,7 +124,7 @@ static int eq_iir_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "eq_iir_get_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -144,7 +142,7 @@ static int eq_iir_process(struct processing_module *mod, /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); - ret = eq_iir_new_blob(mod, cd, audio_stream_get_frm_fmt(source), + ret = eq_iir_new_blob(mod, audio_stream_get_frm_fmt(source), audio_stream_get_frm_fmt(sink), audio_stream_get_channels(source)); if (ret) @@ -185,7 +183,7 @@ static int eq_iir_prepare(struct processing_module *mod, int channels; int ret = 0; - comp_dbg(dev, "eq_iir_prepare()"); + comp_dbg(dev, "entry"); /* EQ component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); @@ -209,20 +207,20 @@ static int eq_iir_prepare(struct processing_module *mod, cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); /* Initialize EQ */ - comp_info(dev, "eq_iir_prepare(), source_format=%d, sink_format=%d", + comp_info(dev, "source_format=%d, sink_format=%d", source_format, sink_format); eq_iir_set_passthrough_func(cd, source_format, sink_format); /* Initialize EQ */ if (cd->config) { - ret = eq_iir_new_blob(mod, cd, source_format, sink_format, channels); + ret = eq_iir_new_blob(mod, source_format, sink_format, channels); if (ret) return ret; } if (!cd->eq_iir_func) { - comp_err(dev, "eq_iir_prepare(), No processing function found"); + comp_err(dev, "No processing function found"); ret = -EINVAL; } @@ -234,7 +232,7 @@ static int eq_iir_reset(struct processing_module *mod) struct comp_data *cd = module_get_private_data(mod); int i; - eq_iir_free_delaylines(cd); + eq_iir_free_delaylines(mod); cd->eq_iir_func = NULL; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -267,6 +265,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(eq_iir_tr, SOF_UUID(eq_iir_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(eq_iir_interface, eq_iir_uuid, eq_iir_tr); SOF_MODULE_INIT(eq_iir, sys_comp_module_eq_iir_interface_init); diff --git a/src/audio/eq_iir/eq_iir.h b/src/audio/eq_iir/eq_iir.h index 7b6b6c247574..12d888d66594 100644 --- a/src/audio/eq_iir/eq_iir.h +++ b/src/audio/eq_iir/eq_iir.h @@ -56,9 +56,8 @@ void eq_iir_s24_default(struct processing_module *mod, struct input_stream_buffe void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, uint32_t frames); -int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, - enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, - int channels); +int eq_iir_new_blob(struct processing_module *mod, enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format, int channels); void eq_iir_set_passthrough_func(struct comp_data *cd, enum sof_ipc_frame source_format, @@ -71,5 +70,5 @@ void eq_iir_pass(struct processing_module *mod, struct input_stream_buffer *bsou int eq_iir_setup(struct processing_module *mod, int nch); -void eq_iir_free_delaylines(struct comp_data *cd); +void eq_iir_free_delaylines(struct processing_module *mod); #endif /* __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ */ diff --git a/src/audio/eq_iir/eq_iir.toml b/src/audio/eq_iir/eq_iir.toml index b02eeb360395..a9933bffc9fb 100644 --- a/src/audio/eq_iir/eq_iir.toml +++ b/src/audio/eq_iir/eq_iir.toml @@ -23,8 +23,8 @@ mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 1000, 0, 0, 0, 0, 0, 4096, 20663000, 768, 768, 0, 20663, 0, 0, 0, 0, 0, 4096, 11357000, 384, 384, 0, 11357, 0] -#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_ACE30) || \ + defined(CONFIG_SOC_ACE40) mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] #endif diff --git a/src/audio/eq_iir/eq_iir_generic.c b/src/audio/eq_iir/eq_iir_generic.c index 4e7688b85004..fd3485a28eca 100644 --- a/src/audio/eq_iir/eq_iir_generic.c +++ b/src/audio/eq_iir/eq_iir_generic.c @@ -202,11 +202,11 @@ static int eq_iir_init_coef(struct processing_module *mod, int nch) if (nch > PLATFORM_MAX_CHANNELS || config->channels_in_config > PLATFORM_MAX_CHANNELS || !config->channels_in_config) { - comp_err(mod->dev, "eq_iir_init_coef(), invalid channels count"); + comp_err(mod->dev, "invalid channels count"); return -EINVAL; } if (config->number_of_responses > SOF_EQ_IIR_MAX_RESPONSES) { - comp_err(mod->dev, "eq_iir_init_coef(), # of resp exceeds max"); + comp_err(mod->dev, "# of resp exceeds max"); return -EINVAL; } @@ -241,13 +241,13 @@ static int eq_iir_init_coef(struct processing_module *mod, int nch) /* Initialize EQ channel to bypass and continue with * next channel response. */ - comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to bypass", i); + comp_info(mod->dev, "ch %d is set to bypass", i); iir_reset_df1(&iir[i]); continue; } if (resp >= config->number_of_responses) { - comp_err(mod->dev, "eq_iir_init_coef(), requested response %d exceeds defined", + comp_err(mod->dev, "requested response %d exceeds defined", resp); return -EINVAL; } @@ -258,13 +258,13 @@ static int eq_iir_init_coef(struct processing_module *mod, int nch) if (s > 0) { size_sum += s; } else { - comp_err(mod->dev, "eq_iir_init_coef(), sections count %d exceeds max", + comp_err(mod->dev, "sections count %d exceeds max", eq->num_sections); return -EINVAL; } iir_init_coef_df1(&iir[i], eq); - comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to response %d", i, resp); + comp_info(mod->dev, "ch %d is set to response %d", i, resp); } return size_sum; @@ -285,15 +285,16 @@ static void eq_iir_init_delay(struct iir_state_df1 *iir, } } -void eq_iir_free_delaylines(struct comp_data *cd) +void eq_iir_free_delaylines(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); struct iir_state_df1 *iir = cd->iir; int i = 0; /* Free the common buffer for all EQs and point then * each IIR channel delay line to NULL. */ - rfree(cd->iir_delay); + mod_free(mod, cd->iir_delay); cd->iir_delay = NULL; cd->iir_delay_size = 0; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -315,7 +316,7 @@ int eq_iir_setup(struct processing_module *mod, int nch) int delay_size; /* Free existing IIR channels data if it was allocated */ - eq_iir_free_delaylines(cd); + eq_iir_free_delaylines(mod); /* Set coefficients for each channel EQ from coefficient blob */ delay_size = eq_iir_init_coef(mod, nch); @@ -329,10 +330,9 @@ int eq_iir_setup(struct processing_module *mod, int nch) return 0; /* Allocate all IIR channels data in a big chunk and clear it */ - cd->iir_delay = rzalloc(SOF_MEM_FLAG_USER, - delay_size); + cd->iir_delay = mod_zalloc(mod, delay_size); if (!cd->iir_delay) { - comp_err(mod->dev, "eq_iir_setup(), delay allocation fail"); + comp_err(mod->dev, "delay allocation fail"); return -ENOMEM; } diff --git a/src/audio/eq_iir/eq_iir_ipc3.c b/src/audio/eq_iir/eq_iir_ipc3.c index b8c5536f0d32..69b27d64c3e7 100644 --- a/src/audio/eq_iir/eq_iir_ipc3.c +++ b/src/audio/eq_iir/eq_iir_ipc3.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -270,7 +269,7 @@ static int eq_iir_verify_params(struct comp_dev *dev, uint32_t buffer_flag; int ret; - comp_dbg(dev, "eq_iir_verify_params()"); + comp_dbg(dev, "entry"); /* The caller has verified, that sink and source buffers are connected */ @@ -298,22 +297,22 @@ static int eq_iir_verify_params(struct comp_dev *dev, return 0; } -int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, - enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, - int channels) +int eq_iir_new_blob(struct processing_module *mod, enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format, int channels) { + struct comp_data *cd = module_get_private_data(mod); int ret; ret = eq_iir_setup(mod, channels); if (ret < 0) { - comp_err(mod->dev, "eq_iir_new_blob(), failed IIR setup"); + comp_err(mod->dev, "failed IIR setup"); return ret; } else if (cd->iir_delay_size) { - comp_dbg(mod->dev, "eq_iir_new_blob(), active"); + comp_dbg(mod->dev, "active"); cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_configured, ARRAY_SIZE(fm_configured)); } else { - comp_dbg(mod->dev, "eq_iir_new_blob(), pass-through"); + comp_dbg(mod->dev, "pass-through"); cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, ARRAY_SIZE(fm_passthrough)); } diff --git a/src/audio/eq_iir/eq_iir_ipc4.c b/src/audio/eq_iir/eq_iir_ipc4.c index ece765d3140b..c19d7f2650fa 100644 --- a/src/audio/eq_iir/eq_iir_ipc4.c +++ b/src/audio/eq_iir/eq_iir_ipc4.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -77,21 +76,21 @@ static eq_iir_func eq_iir_find_func(struct processing_module *mod) return NULL; } -int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, - enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, - int channels) +int eq_iir_new_blob(struct processing_module *mod, enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format, int channels) { + struct comp_data *cd = module_get_private_data(mod); int ret; ret = eq_iir_setup(mod, channels); if (ret < 0) { - comp_err(mod->dev, "eq_iir_new_blob(), failed IIR setup"); + comp_err(mod->dev, "failed IIR setup"); return ret; } else if (cd->iir_delay_size) { - comp_dbg(mod->dev, "eq_iir_new_blob(), active"); + comp_dbg(mod->dev, "active"); cd->eq_iir_func = eq_iir_find_func(mod); } else { - comp_dbg(mod->dev, "eq_iir_new_blob(), pass-through"); + comp_dbg(mod->dev, "pass-through"); cd->eq_iir_func = eq_iir_pass; } @@ -107,7 +106,7 @@ static int eq_iir_params(struct processing_module *mod) enum sof_ipc_frame valid_fmt, frame_fmt; int i; - comp_dbg(dev, "eq_iir_params()"); + comp_dbg(dev, "entry"); comp_params = *params; comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; comp_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; diff --git a/src/audio/eq_iir/tune/sof_example_iir_eq.m b/src/audio/eq_iir/tune/sof_example_iir_eq.m index b75bfa24c422..eef0f2751300 100644 --- a/src/audio/eq_iir/tune/sof_example_iir_eq.m +++ b/src/audio/eq_iir/tune/sof_example_iir_eq.m @@ -2,7 +2,7 @@ % SPDX-License-Identifier: BSD-3-Clause % -% Copyright (c) 2016-2020, Intel Corporation. All rights reserved. +% Copyright (c) 2016-2026, Intel Corporation. % % Author: Seppo Ingalsuo @@ -166,7 +166,7 @@ function sof_example_iir_eq() fs_list = [16e3 48e3]; fc_list = [20 30 40 50 100]; -g_list = [0 20 30 40]; +g_list = [0 16 20 30 40]; for i = 1:length(fs_list) for j = 1:length(fc_list); for k = 1:length(g_list); diff --git a/src/audio/eq_iir/tune/sof_example_lr4.m b/src/audio/eq_iir/tune/sof_example_lr4.m new file mode 100644 index 000000000000..d38111da6b98 --- /dev/null +++ b/src/audio/eq_iir/tune/sof_example_lr4.m @@ -0,0 +1,183 @@ +% sof_example_lr4 - Design 4th order Linkwitz–Riley filter bank +% +% This script is run without arguments. It creates IIR equalizer +% blobs for crossover filter bank for 2-way speaker and four +% channels stream. The exported configurations are Linkwitz-Riley +% 4th order with crossover frequency at 2 kHz. The filters are +% in order: +% - low, high, low, high +% - low, low, high, high +% - high, high, low, low +% + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright (c) 2025, Intel Corporation. +% +% Author: Seppo Ingalsuo + +function sof_example_lr4() + +%% Common definitions +fs = 48e3; +fc = 2e3; +sof_tools = '../../../../tools'; +tpath = fullfile(sof_tools, 'topology/topology2/include/components/eqiir'); +cpath = fullfile(sof_tools, 'ctl/ipc4/eq_iir'); + +sof_eq_paths(1); + +%% -------------------------------------------------- +%% Example: Band-split 2ch to 4ch low and high bands +%% -------------------------------------------------- +design_name = sprintf('xover_lr4_%dhz_lhlh_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); +comment = 'LR4 filter bank coefficients'; +howto = 'cd src/audio/eq_iir/tune; octave sof_example_lr4.m'; + +% Design low-pass and high-pass filters +eq_lo = lo_band_iir(fs, fc); +eq_hi = hi_band_iir(fs, fc); + +% Quantize and pack filter coefficients plus shifts etc. +bq_lo = sof_eq_iir_blob_quant(eq_lo.p_z, eq_lo.p_p, eq_lo.p_k); +bq_hi = sof_eq_iir_blob_quant(eq_hi.p_z, eq_hi.p_p, eq_hi.p_k); + +% Build blob +channels_in_config = 4; % Setup max 4 channels EQ +assign_response = [0 1 0 1]; % Order: lo, hi, lo, hi +num_responses = 2; % Two responses: lo, hi +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% -------------------------------------------------- +%% Example: Same but filters order is lo, lo, hi, hi +%% -------------------------------------------------- + +design_name = sprintf('xover_lr4_%dhz_llhh_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); + +assign_response = [0 0 1 1]; +num_responses = 2; +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% -------------------------------------------------- +%% Example: Same but filters order is hi, hi, lo, lo +%% -------------------------------------------------- + +design_name = sprintf('xover_lr4_%dhz_hhll_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); + +assign_response = [1 1 0 0]; +num_responses = 2; +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% ------------------------------------ +%% Done. +%% ------------------------------------ + +sof_eq_paths(0); +end + +%% ------------------- +%% EQ design functions +%% ------------------- + +function eq = lo_band_iir(fs, fc) + + +%% Get defaults for equalizer design +eq = sof_eq_defaults(); +eq.fs = fs; +eq.enable_iir = 1; +eq.iir_norm_type = 'peak'; +eq.iir_norm_offs_db = 0; + +% Parametric EQs are PEQ_HP1, PEQ_HP2, PEQ_LP1, PEQ_LP2, PEQ_LS1, +% PEQ_LS2, PEQ_HS1, PEQ_HS2 = 8, PEQ_PN2, PEQ_LP4, and PEQ_HP4. +% +% Parametric EQs take as second argument the cutoff frequency in Hz +% and as second argument a dB value (can use 0 for LP2). The +% Third argument is a Q-value (can use 0 for LP2). + +% Two 2nd order butterworth low-pass filters for 4th order Linkwitz–Riley +eq.peq = [ ... + eq.PEQ_LP2 fc 0 0 ; ... + eq.PEQ_LP2 fc 0 0 ; ... + ]; + +%% Design EQ +eq = sof_eq_compute(eq); + +%% Plot +sof_eq_plot(eq); + +end + +function eq = hi_band_iir(fs, fc) + + +%% Get defaults for equalizer design +eq = sof_eq_defaults(); +eq.fs = fs; +eq.enable_iir = 1; +eq.iir_norm_type = 'peak'; +eq.iir_norm_offs_db = 0; + +% Two 2nd order high-pass filters for 4th order Linkwitz–Riley +eq.peq = [ ... + eq.PEQ_HP2 fc 0 0 ; ... + eq.PEQ_HP2 fc 0 0 ; ... + ]; + +%% Design EQ +eq = sof_eq_compute(eq); + +%% Plot +sof_eq_plot(eq); + +end + + + +% Pack and write file common function for all exports +function sof_eq_pack_export(bm, bin_fn, ascii_fn, tplg_fn, note, howto) + +bp = sof_eq_iir_blob_pack(bm, 4); % IPC4 + +if ~isempty(bin_fn) + sof_ucm_blob_write(bin_fn, bp); +end + +if ~isempty(ascii_fn) + sof_alsactl_write(ascii_fn, bp); +end + +if ~isempty(tplg_fn) + sof_tplg2_write(tplg_fn, bp, 'IIR', note, howto); +end + +end diff --git a/src/audio/google/google_ctc_audio_processing.c b/src/audio/google/google_ctc_audio_processing.c index 4b01feea1efa..0ee37abd24d5 100644 --- a/src/audio/google/google_ctc_audio_processing.c +++ b/src/audio/google/google_ctc_audio_processing.c @@ -22,9 +22,6 @@ LOG_MODULE_REGISTER(google_ctc_audio_processing, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(google_ctc_audio_processing); -DECLARE_TR_CTX(google_ctc_audio_processing_tr, SOF_UUID(google_ctc_audio_processing_uuid), - LOG_LEVEL_INFO); - // TODO(eddyhsu): Share these utils function with RTC. static inline float clamp_rescale(float max_val, float x) { @@ -243,13 +240,14 @@ static int ctc_free(struct processing_module *mod) { struct google_ctc_audio_processing_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "ctc_free()"); + comp_info(mod->dev, "entry"); if (cd) { - rfree(cd->input); - rfree(cd->output); + mod_free(mod, cd->input); + mod_free(mod, cd->output); GoogleCtcAudioProcessingFree(cd->state); - rfree(cd); + mod_data_blob_handler_free(mod, cd->tuning_handler); + mod_free(mod, cd); module_set_private_data(mod, NULL); } @@ -262,10 +260,10 @@ static int ctc_init(struct processing_module *mod) struct google_ctc_audio_processing_comp_data *cd; int buf_size; - comp_info(dev, "ctc_init()"); + comp_info(dev, "entry"); /* Create private component data */ - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) { comp_err(dev, "Failed to create component data"); ctc_free(mod); @@ -277,20 +275,20 @@ static int ctc_init(struct processing_module *mod) cd->chunk_frames = kChunkFrames; buf_size = cd->chunk_frames * sizeof(cd->input[0]) * kMaxChannels; - cd->input = rballoc(SOF_MEM_FLAG_USER, buf_size); + cd->input = mod_balloc(mod, buf_size); if (!cd->input) { comp_err(dev, "Failed to allocate input buffer"); ctc_free(mod); return -ENOMEM; } - cd->output = rballoc(SOF_MEM_FLAG_USER, buf_size); + cd->output = mod_balloc(mod, buf_size); if (!cd->output) { comp_err(dev, "Failed to allocate output buffer"); ctc_free(mod); return -ENOMEM; } - cd->tuning_handler = comp_data_blob_handler_new(dev); + cd->tuning_handler = mod_data_blob_handler_new(mod); if (!cd->tuning_handler) { comp_err(dev, "Failed to create tuning handler"); ctc_free(mod); @@ -312,7 +310,7 @@ static int google_ctc_audio_processing_reconfigure(struct processing_module *mod size_t size; int ret; - comp_dbg(dev, "google_ctc_audio_processing_reconfigure()"); + comp_dbg(dev, "entry"); config = comp_get_data_blob(cd->tuning_handler, &size, NULL); if (size == 0) { @@ -352,7 +350,7 @@ static int ctc_prepare(struct processing_module *mod, uint8_t *config; int config_size; - comp_info(mod->dev, "ctc_prepare()"); + comp_info(mod->dev, "entry"); source = comp_dev_get_first_data_producer(dev); if (!source) { @@ -377,13 +375,13 @@ static int ctc_prepare(struct processing_module *mod, break; #endif default: - comp_err(mod->dev, "ctc_prepare(), invalid frame_fmt"); + comp_err(mod->dev, "invalid frame_fmt"); return -EINVAL; } num_channels = audio_stream_get_channels(&source->stream); if (num_channels > kMaxChannels) { - comp_err(mod->dev, "ctc_prepare(), invalid number of channels"); + comp_err(mod->dev, "invalid number of channels"); return -EINVAL; } cd->next_avail_output_samples = cd->chunk_frames * num_channels; @@ -400,7 +398,7 @@ static int ctc_prepare(struct processing_module *mod, config, config_size); if (!cd->state) { - comp_err(mod->dev, "ctc_prepare(), failed to create CTC"); + comp_err(mod->dev, "failed to create CTC"); return -ENOMEM; } @@ -412,7 +410,7 @@ static int ctc_reset(struct processing_module *mod) struct google_ctc_audio_processing_comp_data *cd = module_get_private_data(mod); size_t buf_size = cd->chunk_frames * sizeof(cd->input[0]) * kMaxChannels; - comp_info(mod->dev, "ctc_reset()"); + comp_info(mod->dev, "entry"); GoogleCtcAudioProcessingFree(cd->state); cd->state = NULL; @@ -437,7 +435,7 @@ static int ctc_process(struct processing_module *mod, int ret; - comp_dbg(mod->dev, "ctc_process()"); + comp_dbg(mod->dev, "entry"); if (cd->reconfigure) { ret = google_ctc_audio_processing_reconfigure(mod); @@ -474,6 +472,8 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(google_ctc_audio_processing_tr, SOF_UUID(google_ctc_audio_processing_uuid), + LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(google_ctc_audio_processing_interface, google_ctc_audio_processing_uuid, google_ctc_audio_processing_tr); SOF_MODULE_INIT(google_ctc_audio_processing, diff --git a/src/audio/google/google_ctc_audio_processing_ipc3.c b/src/audio/google/google_ctc_audio_processing_ipc3.c index 96ce45cb72e2..8f6594203420 100644 --- a/src/audio/google/google_ctc_audio_processing_ipc3.c +++ b/src/audio/google/google_ctc_audio_processing_ipc3.c @@ -56,7 +56,7 @@ int ctc_set_config(struct processing_module *mod, uint32_t param_id, case SOF_CTRL_CMD_SWITCH: if (cdata->num_elems == 1) { cd->enabled = cdata->chanv[0].value; - comp_info(mod->dev, "ctc_set_config(), enabled = %d", + comp_info(mod->dev, "enabled = %d", cd->enabled); return 0; } diff --git a/src/audio/google/google_hotword_detect.c b/src/audio/google/google_hotword_detect.c index e625aba57d93..f7cf44f026fd 100644 --- a/src/audio/google/google_hotword_detect.c +++ b/src/audio/google/google_hotword_detect.c @@ -45,7 +45,6 @@ static const struct comp_driver ghd_driver; LOG_MODULE_REGISTER(google_hotword_detect, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(google_hotword); -DECLARE_TR_CTX(ghd_tr, SOF_UUID(ghd_uuid), LOG_LEVEL_INFO); struct comp_data { struct comp_data_blob_handler *model_handler; @@ -63,7 +62,7 @@ static void notify_host(const struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "notify_host()"); + comp_dbg(dev, "entry"); ipc_msg_send(cd->msg, &cd->event, true); } @@ -72,7 +71,7 @@ static void notify_kpb(const struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "notify_kpb()"); + comp_dbg(dev, "entry"); cd->client_data.r_ptr = NULL; cd->client_data.sink = NULL; @@ -135,7 +134,7 @@ static struct comp_dev *ghd_create(const struct comp_driver *drv, ipc_msg_free(cd->msg); rfree(cd); fail: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -143,12 +142,12 @@ static void ghd_free(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "ghd_free()"); + comp_dbg(dev, "entry"); comp_data_blob_handler_free(cd->model_handler); ipc_msg_free(cd->msg); rfree(cd); - rfree(dev); + comp_free_device(dev); } static int ghd_params(struct comp_dev *dev, @@ -394,7 +393,7 @@ static int ghd_copy(struct comp_dev *dev) bytes = audio_stream_get_avail_bytes(stream); - comp_dbg(dev, "ghd_copy() avail_bytes %u", bytes); + comp_dbg(dev, "avail_bytes %u", bytes); comp_dbg(dev, "buffer begin/r_ptr/end [0x%x 0x%x 0x%x]", (uint32_t)audio_stream_get_addr(stream), (uint32_t)audio_stream_get_rptr(stream), @@ -425,7 +424,7 @@ static int ghd_reset(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "ghd_reset()"); + comp_dbg(dev, "entry"); cd->detected = 0; cd->history_bytes = 0; @@ -438,7 +437,7 @@ static int ghd_prepare(struct comp_dev *dev) { int ret; - comp_dbg(dev, "ghd_prepare()"); + comp_dbg(dev, "entry"); ret = ghd_setup_model(dev); if (ret) @@ -447,6 +446,8 @@ static int ghd_prepare(struct comp_dev *dev) return comp_set_state(dev, COMP_TRIGGER_PREPARE); } +DECLARE_TR_CTX(ghd_tr, SOF_UUID(ghd_uuid), LOG_LEVEL_INFO); + static const struct comp_driver ghd_driver = { .type = SOF_COMP_KEYWORD_DETECT, .uid = SOF_RT_UUID(ghd_uuid), diff --git a/src/audio/google/google_rtc_audio_processing.c b/src/audio/google/google_rtc_audio_processing.c index 4e9a55f39516..7c50bca874c5 100644 --- a/src/audio/google/google_rtc_audio_processing.c +++ b/src/audio/google/google_rtc_audio_processing.c @@ -56,10 +56,6 @@ LOG_MODULE_REGISTER(google_rtc_audio_processing, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(google_rtc_audio_processing); -DECLARE_TR_CTX(google_rtc_audio_processing_tr, SOF_UUID(google_rtc_audio_processing_uuid), - LOG_LEVEL_INFO); - - static __aligned(PLATFORM_DCACHE_ALIGN) uint8_t aec_mem_blob[CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_MEMORY_BUFFER_SIZE_KB * 1024]; @@ -247,7 +243,7 @@ static int google_rtc_audio_processing_reconfigure(struct processing_module *mod size_t size; int ret; - comp_dbg(dev, "google_rtc_audio_processing_reconfigure()"); + comp_dbg(dev, "entry"); if (!comp_is_current_data_blob_valid(cd->tuning_handler) && !comp_is_new_data_blob_available(cd->tuning_handler)) { @@ -509,10 +505,10 @@ static int google_rtc_audio_processing_init(struct processing_module *mod) struct google_rtc_audio_processing_comp_data *cd; int ret, i; - comp_info(dev, "google_rtc_audio_processing_init()"); + comp_info(dev, "entry"); /* Create private component data */ - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) { ret = -ENOMEM; goto fail; @@ -520,7 +516,7 @@ static int google_rtc_audio_processing_init(struct processing_module *mod) md->private = cd; - cd->tuning_handler = comp_data_blob_handler_new(dev); + cd->tuning_handler = mod_data_blob_handler_new(mod); if (!cd->tuning_handler) { ret = -ENOMEM; goto fail; @@ -585,8 +581,8 @@ static int google_rtc_audio_processing_init(struct processing_module *mod) GoogleRtcAudioProcessingFree(cd->state); } GoogleRtcAudioProcessingDetachMemoryBuffer(); - comp_data_blob_handler_free(cd->tuning_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->tuning_handler); + mod_free(mod, cd); } return ret; @@ -596,13 +592,13 @@ static int google_rtc_audio_processing_free(struct processing_module *mod) { struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "google_rtc_audio_processing_free()"); + comp_dbg(mod->dev, "entry"); GoogleRtcAudioProcessingFree(cd->state); cd->state = NULL; GoogleRtcAudioProcessingDetachMemoryBuffer(); - comp_data_blob_handler_free(cd->tuning_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->tuning_handler); + mod_free(mod, cd); return 0; } @@ -616,7 +612,7 @@ static int google_rtc_audio_processing_prepare(struct processing_module *mod, struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); int ret = 0; - comp_info(dev, "google_rtc_audio_processing_prepare()"); + comp_info(dev, "entry"); if (num_of_sources != 2 || num_of_sinks != 1) { comp_err(dev, "Invalid source/sink count"); @@ -766,7 +762,7 @@ static int trigger_handler(struct processing_module *mod, int cmd) static int google_rtc_audio_processing_reset(struct processing_module *mod) { - comp_dbg(mod->dev, "google_rtc_audio_processing_reset()"); + comp_dbg(mod->dev, "entry"); return 0; } @@ -864,6 +860,8 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(google_rtc_audio_processing_tr, SOF_UUID(google_rtc_audio_processing_uuid), + LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(google_rtc_audio_processing_interface, google_rtc_audio_processing_uuid, google_rtc_audio_processing_tr); SOF_MODULE_INIT(google_rtc_audio_processing, diff --git a/src/audio/host-legacy.c b/src/audio/host-legacy.c index 75c896cede9d..a16b3f74e1c3 100644 --- a/src/audio/host-legacy.c +++ b/src/audio/host-legacy.c @@ -40,8 +40,6 @@ LOG_MODULE_REGISTER(host, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(host); -DECLARE_TR_CTX(host_tr, SOF_UUID(host_uuid), LOG_LEVEL_INFO); - static inline struct dma_sg_elem *next_buffer(struct hc_buf *hc) { if (!hc->elem_array.elems || !hc->elem_array.count) @@ -129,7 +127,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c uint32_t split_value = 0; int ret = 0; - comp_dbg(dev, "host_copy_one_shot()"); + comp_dbg(dev, "entry"); copy_bytes = host_get_copy_bytes_one_shot(hd, dev); if (!copy_bytes) { @@ -197,7 +195,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c uint32_t copy_bytes = 0; int ret = 0; - comp_dbg(dev, "host_copy_one_shot()"); + comp_dbg(dev, "entry"); copy_bytes = host_get_copy_bytes_one_shot(hd, dev); if (!copy_bytes) { @@ -242,7 +240,7 @@ void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t byt /* assert dma_buffer_copy succeed */ if (ret < 0) - comp_err(dev, "host_common_update() dma buffer copy failed, dir %d bytes %d avail %d free %d", + comp_err(dev, "dma buffer copy failed, dir %d bytes %d avail %d free %d", dev->direction, bytes, audio_stream_get_avail_samples(&source->stream) * audio_stream_frame_bytes(&source->stream), @@ -344,7 +342,7 @@ static void host_dma_cb(void *arg, enum notify_id type, void *data) struct host_data *hd = comp_get_drvdata(dev); uint32_t bytes = next->elem.size; - comp_dbg(dev, "host_dma_cb() %p", &comp_host); + comp_dbg(dev, "%p", &comp_host); /* update position */ host_common_update(hd, dev, bytes); @@ -411,7 +409,7 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal uint32_t flags = 0; int ret; - comp_dbg(dev, "host_copy_normal()"); + comp_dbg(dev, "entry"); if (hd->copy_type == COMP_COPY_BLOCKING) flags |= DMA_COPY_BLOCKING; @@ -515,7 +513,7 @@ static int host_trigger(struct comp_dev *dev, int cmd) struct host_data *hd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "host_trigger()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, cmd); if (ret < 0) @@ -595,7 +593,7 @@ static struct comp_dev *host_new(const struct comp_driver *drv, e_dev: rfree(hd); e_data: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -611,10 +609,10 @@ static void host_free(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); - comp_dbg(dev, "host_free()"); + comp_dbg(dev, "entry"); host_common_free(hd); rfree(hd); - rfree(dev); + comp_free_device(dev); } static int host_elements_reset(struct host_data *hd, struct comp_dev *dev) @@ -655,7 +653,7 @@ static int host_verify_params(struct comp_dev *dev, { int ret; - comp_dbg(dev, "host_verify_params()"); + comp_dbg(dev, "entry"); ret = comp_verify_params(dev, 0, params); if (ret < 0) { @@ -764,7 +762,8 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, goto out; } } else { - hd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, + hd->dma_buffer = buffer_alloc(NULL, buffer_size, + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, addr_align, BUFFER_USAGE_NOT_SHARED); if (!hd->dma_buffer) { comp_err(dev, "failed to alloc dma buffer"); @@ -848,7 +847,7 @@ static int host_params(struct comp_dev *dev, struct host_data *hd = comp_get_drvdata(dev); int err; - comp_dbg(dev, "host_params()"); + comp_dbg(dev, "entry"); err = host_verify_params(dev, params); if (err < 0) { @@ -870,7 +869,7 @@ static int host_prepare(struct comp_dev *dev) struct host_data *hd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "host_prepare()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); if (ret < 0) @@ -933,7 +932,7 @@ static int host_reset(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); - comp_dbg(dev, "host_reset()"); + comp_dbg(dev, "entry"); host_common_reset(hd, dev->state); dev->state = COMP_STATE_READY; @@ -1004,6 +1003,8 @@ static uint64_t host_get_processed_data(struct comp_dev *dev, uint32_t stream_no return ret; } +DECLARE_TR_CTX(host_tr, SOF_UUID(host_uuid), LOG_LEVEL_INFO); + static const struct comp_driver comp_host = { .type = SOF_COMP_HOST, .uid = SOF_RT_UUID(host_uuid), diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index 6bf1fcf78217..30cb465897ba 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -46,8 +46,6 @@ LOG_MODULE_REGISTER(host_comp, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(host); -DECLARE_TR_CTX(host_tr, SOF_UUID(host_uuid), LOG_LEVEL_INFO); - static inline struct dma_sg_elem *next_buffer(struct hc_buf *hc) { if (!hc->elem_array.elems || !hc->elem_array.count) @@ -86,7 +84,7 @@ static int host_dma_set_config_and_copy(struct host_data *hd, struct comp_dev *d local_elem->size = bytes; /* reconfigure transfer */ - ret = dma_config(hd->chan->dma->z_dev, hd->chan->index, &hd->z_config); + ret = sof_dma_config(hd->chan->dma, hd->chan->index, &hd->z_config); if (ret < 0) { comp_err(dev, "dma_config() failed, ret = %d", ret); @@ -95,7 +93,7 @@ static int host_dma_set_config_and_copy(struct host_data *hd, struct comp_dev *d cb(dev, bytes); - ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, bytes); + ret = sof_dma_reload(hd->chan->dma, hd->chan->index, bytes); if (ret < 0) { comp_err(dev, "dma_copy() failed, ret = %d", ret); @@ -139,7 +137,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c uint32_t split_value; int ret = 0; - comp_dbg(dev, "host_copy_one_shot()"); + comp_dbg(dev, "entry"); copy_bytes = host_get_copy_bytes_one_shot(hd); if (!copy_bytes) { @@ -209,7 +207,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c struct dma_sg_elem *local_elem = hd->config.elem_array.elems; int ret = 0; - comp_dbg(dev, "host_copy_one_shot()"); + comp_dbg(dev, "entry"); copy_bytes = host_get_copy_bytes_one_shot(hd); if (!copy_bytes) { @@ -225,7 +223,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c hd->z_config.head_block->block_size = local_elem->size; /* reconfigure transfer */ - ret = dma_config(hd->chan->dma->z_dev, hd->chan->index, &hd->z_config); + ret = sof_dma_config(hd->chan->dma, hd->chan->index, &hd->z_config); if (ret < 0) { comp_err(dev, "dma_config() failed, ret = %u", ret); return ret; @@ -233,7 +231,7 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c cb(dev, copy_bytes); - ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, copy_bytes); + ret = sof_dma_reload(hd->chan->dma, hd->chan->index, copy_bytes); if (ret < 0) comp_err(dev, "dma_copy() failed, ret = %u", ret); @@ -354,7 +352,7 @@ static void host_dma_cb(struct comp_dev *dev, size_t bytes) { struct host_data *hd = comp_get_drvdata(dev); - comp_cl_dbg(&comp_host, "host_dma_cb() %p", &comp_host); + comp_cl_dbg(&comp_host, "%p", &comp_host); /* update position */ host_common_update(hd, dev, bytes); @@ -367,7 +365,7 @@ static void host_dma_cb(struct comp_dev *dev, size_t bytes) /* get status from dma and check for xrun */ static int host_get_status(struct comp_dev *dev, struct host_data *hd, struct dma_status *stat) { - int ret = dma_get_status(hd->chan->dma->z_dev, hd->chan->index, stat); + int ret = sof_dma_get_status(hd->chan->dma, hd->chan->index, stat); #if CONFIG_XRUN_NOTIFICATIONS_ENABLE if (ret == -EPIPE && !hd->xrun_notification_sent) { struct ipc_msg *notify = ipc_notification_pool_get(IPC4_RESOURCE_EVENT_SIZE); @@ -408,7 +406,7 @@ static inline bool host_handle_eos(struct host_data *hd, struct comp_dev *dev, */ if (state != AUDIOBUF_STATE_END_OF_STREAM) { audio_buffer_set_eos(buffer); - comp_info(dev, "host_handle_eos() - EOS detected"); + comp_info(dev, "- EOS detected"); } return true; } @@ -480,27 +478,30 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev * in order to avoid high load spike * if FAST_MODE is enabled, then one period limitation is omitted */ - if (!(hd->ipc_host.feature_mask & BIT(IPC4_COPIER_FAST_MODE))) - dma_copy_bytes = MIN(hd->period_bytes, dma_copy_bytes); + if (!(hd->ipc_host.feature_mask & BIT(IPC4_COPIER_FAST_MODE))) { + const uint64_t now = k_uptime_get(); + const uint64_t delta = now - hd->nobytes_last_logged; + const bool reset_skipped = delta > SOF_MIN_NO_BYTES_INTERVAL_MS; - const uint64_t now = k_uptime_get(); - const uint64_t delta = now - hd->nobytes_last_logged; - const bool reset_skipped = delta > SOF_MIN_NO_BYTES_INTERVAL_MS; - - if (hd->n_skipped > 1 && (dma_copy_bytes || reset_skipped)) { - comp_warn(dev, "Skipped %u no-bytes events in last %llu ms, bytes %u", - hd->n_skipped - 1, delta, dma_copy_bytes); - hd->n_skipped = 0; - } + dma_copy_bytes = MIN(hd->period_bytes, dma_copy_bytes); - if (!dma_copy_bytes) { - if (!hd->n_skipped || reset_skipped) { - hd->nobytes_last_logged = now; + if (hd->n_skipped > 1 && (dma_copy_bytes || reset_skipped)) { + comp_warn(dev, + "Skipped %u no-bytes events in last %llu ms, bytes %u", + hd->n_skipped - 1, delta, dma_copy_bytes); hd->n_skipped = 0; - comp_warn(dev, "no bytes to copy, available samples: %u, free_samples: %u", - avail_samples, free_samples); } - hd->n_skipped++; + + if (!dma_copy_bytes) { + if (!hd->n_skipped || reset_skipped) { + hd->nobytes_last_logged = now; + hd->n_skipped = 0; + comp_warn(dev, + "no bytes to copy, available samples: %u, free_samples: %u", + avail_samples, free_samples); + } + hd->n_skipped++; + } } /* dma_copy_bytes should be aligned to minimum possible chunk of @@ -556,14 +557,14 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal 0; int ret = 0; - comp_dbg(dev, "host_copy_normal()"); + comp_dbg(dev, "entry"); copy_bytes = host_get_copy_bytes_normal(hd, dev); if (!copy_bytes) { if (hd->partial_size != 0) { if (stream_sync(hd, dev)) { - ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, - hd->partial_size); + ret = sof_dma_reload(hd->chan->dma, hd->chan->index, + hd->partial_size); if (ret < 0) comp_err(dev, "dma_reload() failed, ret = %u", ret); @@ -589,8 +590,8 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal hd->dma_buffer_size - hd->partial_size <= (2 + threshold) * hd->period_bytes) { if (stream_sync(hd, dev)) { - ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, - hd->partial_size); + ret = sof_dma_reload(hd->chan->dma, hd->chan->index, + hd->partial_size); if (ret < 0) comp_err(dev, "dma_reload() failed, ret = %u", ret); @@ -665,14 +666,14 @@ int host_common_trigger(struct host_data *hd, struct comp_dev *dev, int cmd) switch (cmd) { case COMP_TRIGGER_START: hd->partial_size = 0; - ret = dma_start(hd->chan->dma->z_dev, hd->chan->index); + ret = sof_dma_start(hd->chan->dma, hd->chan->index); if (ret < 0) comp_err(dev, "dma_start() failed, ret = %u", ret); break; case COMP_TRIGGER_STOP: case COMP_TRIGGER_XRUN: - ret = dma_stop(hd->chan->dma->z_dev, hd->chan->index); + ret = sof_dma_stop(hd->chan->dma, hd->chan->index); if (ret < 0) comp_err(dev, "dma stop failed: %d", ret); @@ -689,7 +690,7 @@ static int host_trigger(struct comp_dev *dev, int cmd) struct host_data *hd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "host_trigger()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, cmd); if (ret < 0) @@ -774,7 +775,7 @@ __cold static struct comp_dev *host_new(const struct comp_driver *drv, e_dev: rfree(hd); e_data: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -794,10 +795,10 @@ __cold static void host_free(struct comp_dev *dev) assert_can_be_cold(); - comp_dbg(dev, "host_free()"); + comp_dbg(dev, "entry"); host_common_free(hd); rfree(hd); - rfree(dev); + comp_free_device(dev); } static int host_elements_reset(struct host_data *hd, int direction) @@ -838,7 +839,7 @@ static int host_verify_params(struct comp_dev *dev, { int ret; - comp_dbg(dev, "host_verify_params()"); + comp_dbg(dev, "entry"); ret = comp_verify_params(dev, 0, params); if (ret < 0) { @@ -875,8 +876,8 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, hd->cont_update_posn = params->cont_update_posn; /* retrieve DMA buffer address alignment */ - err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, - &addr_align); + err = sof_dma_get_attribute(hd->dma, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, + &addr_align); if (err < 0) { comp_err(dev, "could not get dma buffer address alignment, err = %d", err); @@ -884,7 +885,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, } /* retrieve DMA buffer size alignment */ - err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, &align); + err = sof_dma_get_attribute(hd->dma, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, &align); if (err < 0 || !align) { comp_err(dev, "could not get valid dma buffer alignment, err = %d, align = %u", err, align); @@ -954,7 +955,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, } } else { /* allocate not shared buffer */ - hd->dma_buffer = buffer_alloc_range(buffer_size_preferred, buffer_size, + hd->dma_buffer = buffer_alloc_range(NULL, buffer_size_preferred, buffer_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, addr_align, BUFFER_USAGE_NOT_SHARED); if (!hd->dma_buffer) { @@ -999,7 +1000,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, /* get DMA channel from DMAC * note: stream_tag is ignored by dw-dma */ - channel = dma_request_channel(hd->dma->z_dev, &hda_chan); + channel = sof_dma_request_channel(hd->dma, hda_chan); if (channel < 0) { comp_err(dev, "requested channel %d is busy", hda_chan); return -ENODEV; @@ -1061,14 +1062,14 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, break; } - err = dma_config(hd->chan->dma->z_dev, hd->chan->index, dma_cfg); + err = sof_dma_config(hd->chan->dma, hd->chan->index, dma_cfg); if (err < 0) { comp_err(dev, "dma_config() failed"); goto err_free_block_cfg; } - err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_COPY_ALIGNMENT, - &hd->dma_copy_align); + err = sof_dma_get_attribute(hd->dma, DMA_ATTR_COPY_ALIGNMENT, + &hd->dma_copy_align); if (err < 0) { comp_err(dev, "dma_get_attribute() failed"); @@ -1091,7 +1092,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, dma_cfg->head_block = NULL; rfree(dma_block_cfg); err_release_channel: - dma_release_channel(hd->dma->z_dev, hd->chan->index); + sof_dma_release_channel(hd->dma, hd->chan->index); hd->chan = NULL; return err; @@ -1103,7 +1104,7 @@ static int host_params(struct comp_dev *dev, struct host_data *hd = comp_get_drvdata(dev); int err; - comp_dbg(dev, "host_params()"); + comp_dbg(dev, "entry"); err = host_verify_params(dev, params); if (err < 0) { @@ -1125,7 +1126,7 @@ static int host_prepare(struct comp_dev *dev) struct host_data *hd = comp_get_drvdata(dev); int ret; - comp_dbg(dev, "host_prepare()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); if (ret < 0) @@ -1151,8 +1152,8 @@ static int host_position(struct comp_dev *dev, void host_common_reset(struct host_data *hd, uint16_t state) { if (hd->chan) { - dma_stop(hd->chan->dma->z_dev, hd->chan->index); - dma_release_channel(hd->dma->z_dev, hd->chan->index); + sof_dma_stop(hd->chan->dma, hd->chan->index); + sof_dma_release_channel(hd->dma, hd->chan->index); hd->chan = NULL; } @@ -1185,7 +1186,7 @@ static int host_reset(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); - comp_dbg(dev, "host_reset()"); + comp_dbg(dev, "entry"); host_common_reset(hd, dev->state); dev->state = COMP_STATE_READY; @@ -1260,6 +1261,8 @@ static uint64_t host_get_processed_data(struct comp_dev *dev, uint32_t stream_no return ret; } +DECLARE_TR_CTX(host_tr, SOF_UUID(host_uuid), LOG_LEVEL_INFO); + static const struct comp_driver comp_host = { .type = SOF_COMP_HOST, .uid = SOF_RT_UUID(host_uuid), diff --git a/src/audio/igo_nr/igo_nr.c b/src/audio/igo_nr/igo_nr.c index fd6d900eaf82..bde7d2b8fe32 100644 --- a/src/audio/igo_nr/igo_nr.c +++ b/src/audio/igo_nr/igo_nr.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -45,8 +44,6 @@ LOG_MODULE_REGISTER(igo_nr, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(igo_nr); -DECLARE_TR_CTX(igo_nr_tr, SOF_UUID(igo_nr_uuid), LOG_LEVEL_INFO); - static void igo_nr_lib_process(struct comp_data *cd) { /* Pass through the active channel if @@ -380,24 +377,24 @@ static inline int32_t set_capture_func(struct processing_module *mod, struct sof switch (source_get_frm_fmt(source)) { #if CONFIG_FORMAT_S16LE case SOF_IPC_FRAME_S16_LE: - comp_info(dev, "set_capture_func(), SOF_IPC_FRAME_S16_LE"); + comp_info(dev, "SOF_IPC_FRAME_S16_LE"); cd->igo_nr_func = igo_nr_capture_s16; break; #endif #if CONFIG_FORMAT_S24LE case SOF_IPC_FRAME_S24_4LE: - comp_info(dev, "set_capture_func(), SOF_IPC_FRAME_S24_4LE"); + comp_info(dev, "SOF_IPC_FRAME_S24_4LE"); cd->igo_nr_func = igo_nr_capture_s24; break; #endif #if CONFIG_FORMAT_S32LE case SOF_IPC_FRAME_S32_LE: - comp_info(dev, "set_capture_func(), SOF_IPC_FRAME_S32_LE"); + comp_info(dev, "SOF_IPC_FRAME_S32_LE"); cd->igo_nr_func = igo_nr_capture_s32; break; #endif default: - comp_err(dev, "set_capture_func(), invalid frame_fmt"); + comp_err(dev, "invalid frame_fmt"); return -EINVAL; } return 0; @@ -412,16 +409,16 @@ static int igo_nr_init(struct processing_module *mod) size_t bs = cfg->size; int32_t ret; - comp_info(dev, "igo_nr_init()"); + comp_info(dev, "entry"); /* Check first that configuration blob size is sane */ if (bs > SOF_IGO_NR_MAX_SIZE) { - comp_err(dev, "igo_nr_init() error: configuration blob size = %u > %d", + comp_err(dev, "error: configuration blob size = %u > %d", bs, SOF_IGO_NR_MAX_SIZE); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -433,18 +430,18 @@ static int igo_nr_init(struct processing_module *mod) goto cd_fail; } - cd->p_handle = rballoc(SOF_MEM_FLAG_USER, cd->igo_lib_info.handle_size); + cd->p_handle = mod_balloc(mod, cd->igo_lib_info.handle_size); if (!cd->p_handle) { - comp_err(dev, "igo_handle memory rballoc error for size %d", + comp_err(dev, "igo_handle memory mod_balloc error for size %d", cd->igo_lib_info.handle_size); ret = -ENOMEM; goto cd_fail; } /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto cd_fail2; } @@ -463,13 +460,13 @@ static int igo_nr_init(struct processing_module *mod) return 0; cd_fail3: - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); cd_fail2: - rfree(cd->p_handle); + mod_free(mod, cd->p_handle); cd_fail: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -477,12 +474,12 @@ static int igo_nr_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "igo_nr_free()"); + comp_info(mod->dev, "entry"); - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); - rfree(cd->p_handle); - rfree(cd); + mod_free(mod, cd->p_handle); + mod_free(mod, cd); return 0; } @@ -493,30 +490,30 @@ static int32_t igo_nr_check_params(struct processing_module *mod, struct sof_sou struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_info(dev, "igo_nr_check_params()"); + comp_info(dev, "entry"); /* set source/sink_frames/rate */ cd->source_rate = source_get_rate(source); cd->sink_rate = sink_get_rate(sink); if (source_get_channels(source) != sink_get_channels(sink)) { - comp_err(dev, "igo_nr_check_params(), mismatch source/sink stream channels"); + comp_err(dev, "mismatch source/sink stream channels"); cd->invalid_param = true; } if (!cd->sink_rate) { - comp_err(dev, "igo_nr_check_params(), zero sink rate"); + comp_err(dev, "zero sink rate"); return -EINVAL; } /* The igo_nr supports sample rate 48000 only. */ switch (cd->source_rate) { case 48000: - comp_info(dev, "igo_nr_check_params(), sample rate = 48000"); + comp_info(dev, "sample rate = 48000"); cd->invalid_param = false; break; default: - comp_err(dev, "igo_nr_check_params(), invalid sample rate"); + comp_err(dev, "invalid sample rate"); cd->invalid_param = true; } @@ -529,10 +526,10 @@ static int32_t igo_nr_check_config_validity(struct comp_dev *dev, struct sof_igo_nr_config *p_config = comp_get_data_blob(cd->model_handler, NULL, NULL); if (!p_config) { - comp_err(dev, "igo_nr_check_config_validity() error: invalid cd->model_handler"); + comp_err(dev, "error: invalid cd->model_handler"); return -EINVAL; } else if (p_config->active_channel_idx >= SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "igo_nr_check_config_validity() error: invalid active_channel_idxs"); + comp_err(dev, "error: invalid active_channel_idxs"); return -EINVAL; } else { return 0; @@ -566,13 +563,13 @@ static int igo_nr_get_config(struct processing_module *mod, switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: - comp_info(dev, "igo_nr_get_config(), SOF_CTRL_CMD_BINARY"); + comp_info(dev, "SOF_CTRL_CMD_BINARY"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); case SOF_CTRL_CMD_SWITCH: for (j = 0; j < cdata->num_elems; j++) { cdata->chanv[j].channel = j; cdata->chanv[j].value = cd->process_enable[j]; - comp_info(dev, "igo_nr_get_config(), channel = %u, value = %u", + comp_info(dev, "channel = %u, value = %u", cdata->chanv[j].channel, cdata->chanv[j].value); } @@ -629,7 +626,7 @@ static int igo_nr_set_config(struct processing_module *mod, uint32_t param_id, struct comp_dev *dev = mod->dev; int ret; - comp_info(dev, "igo_nr_set_config()"); + comp_info(dev, "entry"); #if CONFIG_IPC_MAJOR_3 struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; @@ -660,7 +657,7 @@ static int igo_nr_set_config(struct processing_module *mod, uint32_t param_id, comp_info(dev, "igo_nr_cmd_set_config(), SOF_IPC4_SWITCH_CONTROL_PARAM_ID"); return igo_nr_set_chan(mod, ctl); case SOF_IPC4_ENUM_CONTROL_PARAM_ID: - comp_err(dev, "igo_nr_set_config(), illegal control."); + comp_err(dev, "illegal control."); return -EINVAL; } @@ -721,7 +718,7 @@ static void igo_nr_set_igo_params(struct processing_module *mod) struct sof_igo_nr_config *p_config = comp_get_data_blob(cd->model_handler, NULL, NULL); struct comp_dev *dev = mod->dev; - comp_info(dev, "igo_nr_set_igo_params()"); + comp_info(dev, "entry"); igo_nr_check_config_validity(dev, cd); if (p_config) { @@ -816,7 +813,7 @@ static int32_t igo_nr_prepare(struct processing_module *mod, struct sof_sink *sink = sinks[0]; int ret; - comp_dbg(dev, "igo_nr_prepare()"); + comp_dbg(dev, "entry"); if (!source || !sink) { comp_err(dev, "no source or sink"); @@ -867,7 +864,7 @@ static int igo_nr_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "igo_nr_reset()"); + comp_info(mod->dev, "entry"); cd->igo_nr_func = NULL; @@ -902,6 +899,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(igo_nr_tr, SOF_UUID(igo_nr_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(igo_nr_interface, igo_nr_uuid, igo_nr_tr); SOF_MODULE_INIT(igo_nr, sys_comp_module_igo_nr_interface_init); diff --git a/src/audio/kpb.c b/src/audio/kpb.c index e8a8bb104818..9dca05630da1 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -70,8 +70,6 @@ SOF_DEFINE_REG_UUID(kpb); #define KPB_UUID kpb_uuid #endif -DECLARE_TR_CTX(kpb_tr, SOF_UUID(KPB_UUID), LOG_LEVEL_INFO); - SOF_DEFINE_REG_UUID(kpb_task); /* KPB private data, runtime data */ @@ -191,7 +189,7 @@ static void kpb_ams_kpd_notification(const struct ams_message_payload *const ams struct kpb_client *cli_data = (struct kpb_client *)ams_message_payload->message; struct comp_dev *dev = ctx; - comp_dbg(dev, "kpb_ams_kpd_notification()"); + comp_dbg(dev, "entry"); kpb_init_draining(dev, cli_data); } @@ -287,7 +285,7 @@ static void kpb_set_params(struct comp_dev *dev, struct comp_data *kpb = comp_get_drvdata(dev); enum sof_ipc_frame frame_fmt, valid_fmt; - comp_dbg(dev, "kpb_set_params()"); + comp_dbg(dev, "entry"); memset_s(params, sizeof(*params), 0, sizeof(*params)); params->channels = kpb->ipc4_cfg.base_cfg.audio_fmt.channels_count; @@ -347,7 +345,7 @@ static int kpb_bind(struct comp_dev *dev, struct bind_info *bind_data) int buf_id; int ret = 0; - comp_dbg(dev, "kpb_bind()"); + comp_dbg(dev, "entry"); bu = bind_data->ipc4_data; buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); @@ -393,7 +391,7 @@ static int kpb_unbind(struct comp_dev *dev, struct bind_info *unbind_data) struct ipc4_module_bind_unbind *bu; int buf_id; - comp_dbg(dev, "kpb_unbind()"); + comp_dbg(dev, "entry"); bu = unbind_data->ipc4_data; buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); @@ -503,7 +501,7 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv, kpb = rzalloc(SOF_MEM_FLAG_USER, sizeof(*kpb)); if (!kpb) { - rfree(dev); + comp_free_device(dev); return NULL; } @@ -511,7 +509,7 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv, ret = kpb_set_verify_ipc_params(dev, ipc_process); if (ret) { - rfree(dev); + comp_free_device(dev); return NULL; } @@ -546,7 +544,7 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv, /* retrieve params from the base config for IPC4 */ ret = kpb_params(dev, ¶ms); if (ret < 0) { - rfree(dev); + comp_free_device(dev); return NULL; } #endif @@ -576,7 +574,7 @@ static size_t kpb_allocate_history_buffer(struct comp_data *kpb, int i = 0; size_t allocated_size = 0; - comp_cl_info(&comp_kpb, "kpb_allocate_history_buffer()"); + comp_cl_info(&comp_kpb, "entry"); /* Initialize history buffer */ kpb->hd.c_hb = rzalloc(SOF_MEM_FLAG_USER, @@ -667,7 +665,7 @@ static void kpb_free_history_buffer(struct history_buffer *buff) struct history_buffer *_buff; struct history_buffer *first_buff = buff; - comp_cl_info(&comp_kpb, "kpb_free_history_buffer()"); + comp_cl_info(&comp_kpb, "entry"); if (!buff) return; @@ -694,7 +692,7 @@ static void kpb_free(struct comp_dev *dev) { struct comp_data *kpb = comp_get_drvdata(dev); - comp_info(dev, "kpb_free()"); + comp_info(dev, "entry"); #if CONFIG_AMS /* Unregister KPB as AMS consumer */ @@ -722,7 +720,7 @@ static void kpb_free(struct comp_dev *dev) /* Free KPB */ rfree(kpb); - rfree(dev); + comp_free_device(dev); } /** @@ -733,7 +731,7 @@ static void kpb_free(struct comp_dev *dev) */ static int kpb_trigger(struct comp_dev *dev, int cmd) { - comp_info(dev, "kpb_trigger()"); + comp_info(dev, "entry"); return comp_set_state(dev, cmd); } @@ -743,7 +741,7 @@ static int kpb_verify_params(struct comp_dev *dev, { int ret; - comp_dbg(dev, "kpb_verify_params()"); + comp_dbg(dev, "entry"); ret = comp_verify_params(dev, 0, params); if (ret < 0) { @@ -806,7 +804,7 @@ static int kpb_prepare(struct comp_dev *dev) int i; size_t hb_size_req = KPB_MAX_BUFFER_SIZE(kpb->config.sampling_width, kpb->config.channels); - comp_dbg(dev, "kpb_prepare()"); + comp_dbg(dev, "entry"); /* retrieve the params from the base_cfg and update the source/sink buffer params */ kpb_set_params(dev, ¶ms); @@ -1211,7 +1209,7 @@ static int kpb_copy(struct comp_dev *dev) uint32_t avail_bytes; uint32_t channels = kpb->config.channels; - comp_dbg(dev, "kpb_copy()"); + comp_dbg(dev, "entry"); if (list_is_empty(&dev->bsource_list)) { comp_err(dev, "no source."); @@ -1411,7 +1409,7 @@ static int kpb_buffer_data(struct comp_dev *dev, enum kpb_state state_preserved = kpb->state; size_t sample_width = kpb->config.sampling_width; - comp_dbg(dev, "kpb_buffer_data()"); + comp_dbg(dev, "entry"); /* We are allowed to buffer data in internal history buffer * only in KPB_STATE_RUN, KPB_STATE_DRAINING or KPB_STATE_INIT_DRAINING @@ -1566,7 +1564,7 @@ static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli) { int ret = 0; - comp_cl_info(&comp_kpb, "kpb_register_client()"); + comp_cl_info(&comp_kpb, "entry"); if (!cli) { comp_cl_err(&comp_kpb, "no client data"); @@ -1720,10 +1718,10 @@ static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli) /* Unlimited draining */ drain_interval = 0; period_bytes_limit = 0; - comp_info(dev, "kpb_init_draining: unlimited draining speed selected."); + comp_info(dev, "unlimited draining speed selected."); } - comp_info(dev, "kpb_init_draining(), schedule draining task"); + comp_info(dev, "schedule draining task"); /* Add one-time draining task into the scheduler. */ kpb->draining_task_data.sink = kpb->host_sink; @@ -1848,7 +1846,7 @@ static enum task_state kpb_draining_task(void *arg) k_sched_lock(); #endif - comp_cl_dbg(&comp_kpb, "kpb_draining_task()"); + comp_cl_dbg(&comp_kpb, "entry"); /* Have we received reset request? */ if (kpb->state == KPB_STATE_RESETTING) { @@ -1968,10 +1966,10 @@ static enum task_state kpb_draining_task(void *arg) draining_time_ms = k_cyc_to_ms_near64(draining_time_end - draining_data->draining_time_start); if (draining_time_ms <= UINT_MAX) - comp_cl_info(&comp_kpb, "KPB: kpb_draining_task(), done. %zu drained in %u ms", + comp_cl_info(&comp_kpb, "KPB: done. %zu drained in %u ms", draining_data->drained, (unsigned int)draining_time_ms); else - comp_cl_info(&comp_kpb, "KPB: kpb_draining_task(), done. %zu drained in > %u ms", + comp_cl_info(&comp_kpb, "KPB: done. %zu drained in > %u ms", draining_data->drained, UINT_MAX); /* Restore original EDF thread priority */ @@ -2212,7 +2210,7 @@ static void kpb_clear_history_buffer(struct history_buffer *buff) void *start_addr; size_t size; - comp_cl_info(&comp_kpb, "kpb_clear_history_buffer()"); + comp_cl_info(&comp_kpb, "entry"); do { start_addr = buff->start_addr; @@ -2363,7 +2361,7 @@ static void kpb_reset_history_buffer(struct history_buffer *buff) { struct history_buffer *first_buff = buff; - comp_cl_info(&comp_kpb, "kpb_reset_history_buffer()"); + comp_cl_info(&comp_kpb, "entry"); if (!buff) return; @@ -2655,7 +2653,7 @@ static int kpb_set_large_config(struct comp_dev *dev, uint32_t param_id, /* We can use extended param id for both extended and standard param id */ union ipc4_extended_param_id extended_param_id; - comp_info(dev, "kpb_set_large_config()"); + comp_info(dev, "entry"); extended_param_id.full = param_id; @@ -2679,6 +2677,8 @@ static int kpb_set_large_config(struct comp_dev *dev, uint32_t param_id, } } +DECLARE_TR_CTX(kpb_tr, SOF_UUID(KPB_UUID), LOG_LEVEL_INFO); + static const struct comp_driver comp_kpb = { .type = SOF_COMP_KPB, .uid = SOF_RT_UUID(KPB_UUID), diff --git a/src/audio/level_multiplier/level_multiplier.c b/src/audio/level_multiplier/level_multiplier.c index 68edff07a96e..4fca482ced72 100644 --- a/src/audio/level_multiplier/level_multiplier.c +++ b/src/audio/level_multiplier/level_multiplier.c @@ -17,11 +17,6 @@ SOF_DEFINE_REG_UUID(level_multiplier); /* Creates logging data for the component */ LOG_MODULE_REGISTER(level_multiplier, CONFIG_SOF_LOG_LEVEL); -/* Creates the component trace. Traces show in trace console the component - * info, warning, and error messages. - */ -DECLARE_TR_CTX(level_multiplier_tr, SOF_UUID(level_multiplier_uuid), LOG_LEVEL_INFO); - /** * level_multiplier_init() - Initialize the level_multiplier component. * @mod: Pointer to module data. @@ -38,7 +33,7 @@ __cold static int level_multiplier_init(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct level_multiplier_comp_data *cd; - comp_info(dev, "level_multiplier_init()"); + comp_info(dev, "entry"); cd = mod_alloc(mod, sizeof(*cd)); if (!cd) @@ -75,7 +70,7 @@ static int level_multiplier_process(struct processing_module *mod, int frames = source_get_data_frames_available(source); int sink_frames = sink_get_free_frames(sink); - comp_dbg(dev, "level_multiplier_process()"); + comp_dbg(dev, "entry"); frames = MIN(frames, sink_frames); frames = MIN(frames, dev->frames); @@ -111,7 +106,7 @@ static int level_multiplier_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; enum sof_ipc_frame source_format; - comp_dbg(dev, "level_multiplier_prepare()"); + comp_dbg(dev, "entry"); /* The processing example in this component supports one input and one * output. Generally there can be more. @@ -147,7 +142,7 @@ static int level_multiplier_reset(struct processing_module *mod) { struct level_multiplier_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "level_multiplier_reset()"); + comp_dbg(mod->dev, "entry"); memset(cd, 0, sizeof(*cd)); cd->gain = LEVEL_MULTIPLIER_GAIN_ONE; @@ -171,7 +166,7 @@ __cold static int level_multiplier_free(struct processing_module *mod) assert_can_be_cold(); - comp_dbg(mod->dev, "level_multiplier_free()"); + comp_dbg(mod->dev, "entry"); mod_free(mod, cd); return 0; } @@ -205,6 +200,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(level_multiplier_tr, SOF_UUID(level_multiplier_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(level_multiplier_interface, level_multiplier_uuid, level_multiplier_tr); SOF_MODULE_INIT(level_multiplier, sys_comp_module_level_multiplier_interface_init); diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index da1fa9f3414e..9a5846edaffd 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -36,8 +36,6 @@ LOG_MODULE_REGISTER(mfcc, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(mfcc); -DECLARE_TR_CTX(mfcc_tr, SOF_UUID(mfcc_uuid), LOG_LEVEL_INFO); - __cold_rodata const struct mfcc_func_map mfcc_fm[] = { #if CONFIG_FORMAT_S16LE {SOF_IPC_FRAME_S16_LE, mfcc_s16_default}, @@ -79,22 +77,22 @@ static int mfcc_init(struct processing_module *mod) size_t bs = cfg->size; int ret; - comp_info(dev, "mfcc_init()"); + comp_info(dev, "entry"); /* Check first that configuration blob size is sane */ if (bs > SOF_MFCC_CONFIG_MAX_SIZE) { - comp_err(dev, "mfcc_init() error: configuration blob size %zu exceeds %d", + comp_err(dev, "error: configuration blob size %zu exceeds %d", bs, SOF_MFCC_CONFIG_MAX_SIZE); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; /* Handler for configuration data */ md->private = cd; - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { comp_err(dev, "comp_data_blob_handler_new() failed."); ret = -ENOMEM; @@ -114,7 +112,7 @@ static int mfcc_init(struct processing_module *mod) comp_data_blob_handler_free(cd->model_handler); err: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -122,10 +120,10 @@ static int mfcc_free(struct processing_module *mod) { struct mfcc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "mfcc_free()"); - comp_data_blob_handler_free(cd->model_handler); - mfcc_free_buffers(cd); - rfree(cd); + comp_info(mod->dev, "entry"); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); + mfcc_free_buffers(mod); return 0; } @@ -136,7 +134,7 @@ static int mfcc_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct mfcc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "mfcc_get_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -148,7 +146,7 @@ static int mfcc_set_config(struct processing_module *mod, uint32_t config_id, { struct mfcc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "mfcc_set_config()"); + comp_info(mod->dev, "entry"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -163,7 +161,7 @@ static int mfcc_process(struct processing_module *mod, struct audio_stream *sink = output_buffers->data; int frames = input_buffers->size; - comp_dbg(mod->dev, "mfcc_process(), start"); + comp_dbg(mod->dev, "start"); frames = MIN(frames, cd->max_frames); cd->mfcc_func(mod, input_buffers, output_buffers, frames); @@ -171,7 +169,7 @@ static int mfcc_process(struct processing_module *mod, /* TODO: use module_update_buffer_position() from #6194 */ input_buffers->consumed += audio_stream_frame_bytes(source) * frames; output_buffers->size += audio_stream_frame_bytes(sink) * frames; - comp_dbg(mod->dev, "mfcc_process(), done"); + comp_dbg(mod->dev, "done"); return 0; } @@ -188,7 +186,7 @@ static int mfcc_prepare(struct processing_module *mod, uint32_t sink_period_bytes; int ret; - comp_info(dev, "mfcc_prepare()"); + comp_info(dev, "entry"); /* MFCC component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); @@ -204,7 +202,7 @@ static int mfcc_prepare(struct processing_module *mod, /* get sink data format and period bytes */ sink_format = audio_stream_get_frm_fmt(&sinkb->stream); sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, dev->frames); - comp_info(dev, "mfcc_prepare(), source_format = %d, sink_format = %d", + comp_info(dev, "source_format = %d, sink_format = %d", source_format, sink_format); if (audio_stream_get_size(&sinkb->stream) < sink_period_bytes) { comp_err(dev, "sink buffer size %d is insufficient < %d", @@ -220,14 +218,14 @@ static int mfcc_prepare(struct processing_module *mod, ret = mfcc_setup(mod, dev->frames + 4, audio_stream_get_rate(&sourceb->stream), audio_stream_get_channels(&sourceb->stream)); if (ret < 0) { - comp_err(dev, "mfcc_prepare(), setup failed."); + comp_err(dev, "setup failed."); goto err; } } cd->mfcc_func = mfcc_find_func(source_format, sink_format, mfcc_fm, ARRAY_SIZE(mfcc_fm)); if (!cd->mfcc_func) { - comp_err(dev, "mfcc_prepare(), No proc func"); + comp_err(dev, "No proc func"); ret = -EINVAL; goto err; } @@ -243,7 +241,7 @@ static int mfcc_reset(struct processing_module *mod) { struct mfcc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "mfcc_reset()"); + comp_info(mod->dev, "entry"); /* Reset to similar state as init() */ cd->mfcc_func = NULL; @@ -274,6 +272,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(mfcc_tr, SOF_UUID(mfcc_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(mfcc_interface, mfcc_uuid, mfcc_tr); SOF_MODULE_INIT(mfcc, sys_comp_module_mfcc_interface_init); diff --git a/src/audio/mfcc/mfcc_common.c b/src/audio/mfcc/mfcc_common.c index 63ab84943669..688c7afac9b2 100644 --- a/src/audio/mfcc/mfcc_common.c +++ b/src/audio/mfcc/mfcc_common.c @@ -50,7 +50,7 @@ static int mfcc_stft_process(const struct comp_dev *dev, struct mfcc_state *stat * first output cepstral coefficients originate from streamed data and not * from buffers with zero data. */ - comp_dbg(dev, "mfcc_stft_process(), avail = %d", buf->s_avail); + comp_dbg(dev, "avail = %d", buf->s_avail); if (state->waiting_fill) { if (buf->s_avail < fft->fft_size) return 0; diff --git a/src/audio/mfcc/mfcc_setup.c b/src/audio/mfcc/mfcc_setup.c index 802ea058bb6f..642b20df66f5 100644 --- a/src/audio/mfcc/mfcc_setup.c +++ b/src/audio/mfcc/mfcc_setup.c @@ -65,7 +65,7 @@ static int mfcc_get_window(struct mfcc_state *state, enum sof_mfcc_fft_window_ty * coef[i] = 1.0 + 0.5 * lifter * sin(pi * i / lifter), i = 0 to num_ceps-1 */ -static int mfcc_get_cepstral_lifter(struct mfcc_cepstral_lifter *cl) +static int mfcc_get_cepstral_lifter(struct processing_module *mod, struct mfcc_cepstral_lifter *cl) { int32_t inv_cepstral_lifter; int32_t val; @@ -75,7 +75,7 @@ static int mfcc_get_cepstral_lifter(struct mfcc_cepstral_lifter *cl) if (cl->num_ceps > DCT_MATRIX_SIZE_MAX) return -EINVAL; - cl->matrix = mat_matrix_alloc_16b(1, cl->num_ceps, 9); /* Use Q7.9 */ + cl->matrix = mod_mat_matrix_alloc_16b(mod, 1, cl->num_ceps, 9); /* Use Q7.9 */ if (!cl->matrix) return -ENOMEM; @@ -108,7 +108,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i struct dct_plan_16 *dct = &state->dct; int ret; - comp_dbg(dev, "mfcc_setup()"); + comp_dbg(dev, "entry"); /* Check size */ if (config->size != sizeof(struct sof_mfcc_config)) { @@ -137,7 +137,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i return -EINVAL; } - comp_info(dev, "mfcc_setup(), source_channel = %d, stream_channels = %d", + comp_info(dev, "source_channel = %d, stream_channels = %d", config->channel, channels); if (config->channel >= channels) { comp_err(dev, "Illegal channel"); @@ -156,7 +156,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i fft->fft_hop_size = config->frame_shift; fft->half_fft_size = (fft->fft_padded_size >> 1) + 1; - comp_info(dev, "mfcc_setup(), emphasis = %d, fft_size = %d, fft_padded_size = %d, fft_hop_size = %d", + comp_info(dev, "emphasis = %d, fft_size = %d, fft_padded_size = %d, fft_hop_size = %d", config->preemphasis_coefficient, fft->fft_size, fft->fft_padded_size, fft->fft_hop_size); @@ -168,11 +168,10 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i state->sample_buffers_size = sizeof(int16_t) * (state->buffer_size + state->prev_data_size + fft->fft_size); - comp_info(dev, "mfcc_setup(), buffer_size = %d, prev_size = %d", + comp_info(dev, "buffer_size = %d, prev_size = %d", state->buffer_size, state->prev_data_size); - state->buffers = rzalloc(SOF_MEM_FLAG_USER, - state->sample_buffers_size); + state->buffers = mod_zalloc(mod, state->sample_buffers_size); if (!state->buffers) { comp_err(dev, "Failed buffer allocate"); ret = -ENOMEM; @@ -189,14 +188,14 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i #else fft->fft_buffer_size = fft->fft_padded_size * sizeof(struct icomplex32); #endif - fft->fft_buf = rzalloc(SOF_MEM_FLAG_USER, fft->fft_buffer_size); + fft->fft_buf = mod_zalloc(mod, fft->fft_buffer_size); if (!fft->fft_buf) { comp_err(dev, "Failed FFT buffer allocate"); ret = -ENOMEM; goto free_buffers; } - fft->fft_out = rzalloc(SOF_MEM_FLAG_USER, fft->fft_buffer_size); + fft->fft_out = mod_zalloc(mod, fft->fft_buffer_size); if (!fft->fft_out) { comp_err(dev, "Failed FFT output allocate"); ret = -ENOMEM; @@ -206,17 +205,17 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i fft->fft_fill_start_idx = 0; /* From config pad_type */ /* Setup FFT */ - fft->fft_plan = fft_plan_new(fft->fft_buf, fft->fft_out, fft->fft_padded_size, - MFCC_FFT_BITS); + fft->fft_plan = mod_fft_plan_new(mod, fft->fft_buf, fft->fft_out, fft->fft_padded_size, + MFCC_FFT_BITS); if (!fft->fft_plan) { comp_err(dev, "Failed FFT init"); ret = -EINVAL; goto free_fft_out; } - comp_info(dev, "mfcc_setup(), window = %d, num_mel_bins = %d, num_ceps = %d, norm = %d", + comp_info(dev, "window = %d, num_mel_bins = %d, num_ceps = %d, norm = %d", config->window, config->num_mel_bins, config->num_ceps, config->norm); - comp_info(dev, "mfcc_setup(), low_freq = %d, high_freq = %d", + comp_info(dev, "low_freq = %d, high_freq = %d", state->low_freq, state->high_freq); /* Setup window */ @@ -242,7 +241,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i fb->scratch_data2 = (int16_t *)fft->fft_out; fb->scratch_length1 = fft->fft_buffer_size / sizeof(int16_t); fb->scratch_length2 = fft->fft_buffer_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(fb); + ret = mod_psy_get_mel_filterbank(mod, fb); if (ret < 0) { comp_err(dev, "Failed Mel filterbank"); goto free_fft_out; @@ -253,7 +252,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i dct->num_out = config->num_ceps; dct->type = (enum dct_type)config->dct; dct->ortho = true; - ret = dct_initialize_16(dct); + ret = mod_dct_initialize_16(mod, dct); if (ret < 0) { comp_err(dev, "Failed DCT init"); goto free_melfb_data; @@ -261,7 +260,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i state->lifter.num_ceps = config->num_ceps; state->lifter.cepstral_lifter = config->cepstral_lifter; /* Q7.9 max 64.0*/ - ret = mfcc_get_cepstral_lifter(&state->lifter); + ret = mfcc_get_cepstral_lifter(mod, &state->lifter); if (ret < 0) { comp_err(dev, "Failed cepstral lifter"); goto free_dct_matrix; @@ -295,7 +294,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i state->waiting_fill = true; state->prev_samples_valid = false; - comp_dbg(dev, "mfcc_setup(), done"); + comp_dbg(dev, "done"); return 0; free_dct_matrix: @@ -317,13 +316,15 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i return ret; } -void mfcc_free_buffers(struct mfcc_comp_data *cd) +void mfcc_free_buffers(struct processing_module *mod) { - fft_plan_free(cd->state.fft.fft_plan); - rfree(cd->state.fft.fft_buf); - rfree(cd->state.fft.fft_out); - rfree(cd->state.buffers); - rfree(cd->state.melfb.data); - rfree(cd->state.dct.matrix); - rfree(cd->state.lifter.matrix); + struct mfcc_comp_data *cd = module_get_private_data(mod); + + mod_fft_plan_free(mod, cd->state.fft.fft_plan); + mod_free(mod, cd->state.fft.fft_buf); + mod_free(mod, cd->state.fft.fft_out); + mod_free(mod, cd->state.buffers); + mod_free(mod, cd->state.melfb.data); + mod_free(mod, cd->state.dct.matrix); + mod_free(mod, cd->state.lifter.matrix); } diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index 703e87ecee43..6300d5b86bc5 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -36,18 +35,15 @@ LOG_MODULE_REGISTER(mixer, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(mixer); -DECLARE_TR_CTX(mixer_tr, SOF_UUID(mixer_uuid), LOG_LEVEL_INFO); - - static int mixer_init(struct processing_module *mod) { struct module_data *mod_data = &mod->priv; struct comp_dev *dev = mod->dev; struct mixer_data *md; - comp_dbg(dev, "mixer_init()"); + comp_dbg(dev, "entry"); - md = rzalloc(SOF_MEM_FLAG_USER, sizeof(*md)); + md = mod_zalloc(mod, sizeof(*md)); if (!md) return -ENOMEM; @@ -64,9 +60,9 @@ static int mixer_free(struct processing_module *mod) struct mixer_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "mixer_free()"); + comp_dbg(dev, "entry"); - rfree(md); + mod_free(mod, md); return 0; } @@ -89,7 +85,7 @@ static int mixer_process(struct processing_module *mod, uint32_t sink_bytes; int active_input_buffers = 0; - comp_dbg(dev, "mixer_process() %d", num_input_buffers); + comp_dbg(dev, "%d", num_input_buffers); /* too many sources ? */ if (num_input_buffers >= PLATFORM_MAX_STREAMS) @@ -129,7 +125,7 @@ static int mixer_process(struct processing_module *mod, sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data); - comp_dbg(dev, "mixer_process(), source_bytes = 0x%x, sink_bytes = 0x%x", + comp_dbg(dev, "source_bytes = 0x%x, sink_bytes = 0x%x", source_bytes, sink_bytes); /* mix streams */ @@ -164,7 +160,7 @@ static int mixer_reset(struct processing_module *mod) struct comp_dev *dev = mod->dev; int dir = dev->pipeline->source_comp->direction; - comp_dbg(dev, "mixer_reset()"); + comp_dbg(dev, "entry"); if (dir == SOF_IPC_STREAM_PLAYBACK) { struct comp_buffer *source; @@ -257,5 +253,6 @@ static const struct module_interface mixer_interface = { .free = mixer_free, }; +DECLARE_TR_CTX(mixer_tr, SOF_UUID(mixer_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(mixer_interface, mixer_uuid, mixer_tr); SOF_MODULE_INIT(mixer, sys_comp_module_mixer_interface_init); diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index ec473baf6e58..1869099feb41 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -36,11 +35,9 @@ LOG_MODULE_REGISTER(mixin_mixout, CONFIG_SOF_LOG_LEVEL); /* mixin 39656eb2-3b71-4049-8d3f-f92cd5c43c09 */ SOF_DEFINE_REG_UUID(mixin); -DECLARE_TR_CTX(mixin_tr, SOF_UUID(mixin_uuid), LOG_LEVEL_INFO); /* mixout 3c56505a-24d7-418f-bddc-c1f5a3ac2ae0 */ SOF_DEFINE_REG_UUID(mixout); -DECLARE_TR_CTX(mixout_tr, SOF_UUID(mixout_uuid), LOG_LEVEL_INFO); #define MIXIN_MAX_SINKS IPC4_MIXIN_MODULE_MAX_OUTPUT_QUEUES #define MIXOUT_MAX_SOURCES IPC4_MIXOUT_MODULE_MAX_INPUT_QUEUES @@ -141,7 +138,7 @@ static int mixin_init(struct processing_module *mod) comp_dbg(dev, "entry"); - md = rzalloc(SOF_MEM_FLAG_USER, sizeof(*md)); + md = mod_zalloc(mod, sizeof(*md)); if (!md) return -ENOMEM; @@ -168,7 +165,7 @@ static int mixout_init(struct processing_module *mod) comp_dbg(dev, "entry"); - mo_data = rzalloc(SOF_MEM_FLAG_USER, sizeof(*mo_data)); + mo_data = mod_zalloc(mod, sizeof(*mo_data)); if (!mo_data) return -ENOMEM; @@ -184,14 +181,14 @@ static int mixin_free(struct processing_module *mod) { struct mixin_data *md = module_get_private_data(mod); - rfree(md); + mod_free(mod, md); return 0; } static int mixout_free(struct processing_module *mod) { - rfree(module_get_private_data(mod)); + mod_free(mod, module_get_private_data(mod)); return 0; } @@ -1051,9 +1048,11 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(mixin_tr, SOF_UUID(mixin_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(mixin_interface, mixin_uuid, mixin_tr); SOF_MODULE_INIT(mixin, sys_comp_module_mixin_interface_init); +DECLARE_TR_CTX(mixout_tr, SOF_UUID(mixout_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(mixout_interface, mixout_uuid, mixout_tr); SOF_MODULE_INIT(mixout, sys_comp_module_mixout_interface_init); diff --git a/src/audio/mixin_mixout/mixin_mixout.toml b/src/audio/mixin_mixout/mixin_mixout.toml index 812505b19fa8..16edc0567aa3 100644 --- a/src/audio/mixin_mixout/mixin_mixout.toml +++ b/src/audio/mixin_mixout/mixin_mixout.toml @@ -32,7 +32,7 @@ 2, 0, 0, 0, 296, 2448000, 512, 512, 0, 2448, 0, 3, 0, 0, 0, 296, 2160000, 128, 128, 0, 2160, 0, 4, 0, 0, 0, 296, 3268000, 1536, 1536, 0, 3268, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 296, 5091000, 384, 384, 0, 5091, 0, 1, 0, 0, 0, 296, 5111000, 384, 384, 0, 5111, 0, 2, 0, 0, 0, 296, 5195000, 512, 512, 0, 5195, 0, @@ -77,7 +77,7 @@ 2, 0, 0, 0, 520, 7631000, 512, 512, 0, 0, 0, 3, 0, 0, 0, 520, 1953000, 128, 128, 0, 0, 0, 4, 0, 0, 0, 520, 2301000, 1536, 1536, 0, 0, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 520, 3999000, 384, 384, 0, 3999, 0, 1, 0, 0, 0, 520, 3999000, 384, 384, 0, 3999, 0, 2, 0, 0, 0, 520, 4055000, 512, 512, 0, 4055, 0, diff --git a/src/audio/module_adapter/CMakeLists.txt b/src/audio/module_adapter/CMakeLists.txt index 0ad91176bfc5..c728ef6d54b8 100644 --- a/src/audio/module_adapter/CMakeLists.txt +++ b/src/audio/module_adapter/CMakeLists.txt @@ -10,13 +10,21 @@ is_zephyr(zephyr) if(zephyr) ### Zephyr ### # modules and codecs in alphabetical order - - zephyr_library_sources_ifdef(CONFIG_CADENCE_CODEC module/cadence.c) +if (CONFIG_IPC_MAJOR_3) + zephyr_library_sources_ifdef(CONFIG_CADENCE_CODEC module/cadence.c module/cadence_ipc3.c) +elseif (CONFIG_IPC_MAJOR_4) + zephyr_include_directories(${sof_top_dir}/src/include/sof/audio/cadence) + zephyr_library_sources_ifdef(CONFIG_CADENCE_CODEC module/cadence.c module/cadence_ipc4.c) +endif() if (CONFIG_CADENCE_CODEC_AAC_DEC) zephyr_library_import(xa_aac_dec ${CONFIG_CADENCE_CODEC_AAC_DEC_LIB}) endif() + if (CONFIG_CADENCE_CODEC_VORBIS_DEC) + zephyr_library_import(xa_vorbis_dec ${CONFIG_CADENCE_CODEC_VORBIS_DEC_LIB}) + endif() + if (CONFIG_CADENCE_CODEC_MP3_DEC) zephyr_library_import(xa_mp3_dec ${CONFIG_CADENCE_CODEC_MP3_DEC_LIB}) endif() @@ -25,6 +33,28 @@ if(zephyr) ### Zephyr ### zephyr_library_import(xa_mp3_enc ${CONFIG_CADENCE_CODEC_MP3_ENC_LIB}) endif() + if (CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING) + if(CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING STREQUAL "m" AND DEFINED CONFIG_LLEXT) + add_subdirectory(module/dolby/llext + ${PROJECT_BINARY_DIR}/dolby_dax_audio_processing_llext) + add_dependencies(app dolby_dax_audio_processing) + else() + zephyr_library_sources( + module/dolby/dax.c + ) + if (CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK) + zephyr_library_sources( + module/dolby/dax_mock.c + ) + else() + target_link_libraries(SOF INTERFACE m) + target_link_libraries(SOF INTERFACE c) + zephyr_library_import(dax_effect + ${sof_top_dir}/third_party/lib/libdax.a) + endif() + endif() + endif() + zephyr_include_directories_ifdef(CONFIG_LIBRARY_MANAGER ${SOF_SRC_PATH}/include/sof/audio/module_adapter/iadk/ ${SOF_SRC_PATH}/include/sof/audio/module_adapter/library/ @@ -42,6 +72,11 @@ if(zephyr) ### Zephyr ### library/native_system_service.c ) + zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_PROXY + library/userspace_proxy.c + library/userspace_proxy_user.c + ) + zephyr_library_sources_ifdef(CONFIG_PASSTHROUGH_CODEC module/passthrough.c ) @@ -112,6 +147,19 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) endif() + if(CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING) + target_include_directories(sof PRIVATE ${PROJECT_SOURCE_DIR}/third_party/include) + add_local_sources(sof module/dolby/dax.c) + if (CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK) + add_local_sources(sof module/dolby/dax_mock.c) + else() + target_link_libraries(sof PRIVATE m) + target_link_libraries(sof PRIVATE c) + sof_add_static_library(dax_effect + ${PROJECT_SOURCE_DIR}/third_party/lib/libdax.a) + endif() + endif() + if(CONFIG_PASSTHROUGH_CODEC) add_local_sources(sof module/passthrough.c) endif() diff --git a/src/audio/module_adapter/Kconfig b/src/audio/module_adapter/Kconfig index 7ed6b859cd64..a9f88dd1f2ad 100644 --- a/src/audio/module_adapter/Kconfig +++ b/src/audio/module_adapter/Kconfig @@ -175,6 +175,22 @@ if CADENCE_CODEC endif # Cadence + config COMP_DOLBY_DAX_AUDIO_PROCESSING + tristate "Dolby DAX audio processing component" + help + Select to include Dolby DAX component. Dolby DAX component implements DAX API. + API definition together with pre-compiled library is shared by Dolby. + If library is not provided, COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK must be true, + then the input will be copied to the output. + + config COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK + bool "Dolby DAX audio processing component mock" + default y if COMP_STUBS + depends on COMP_DOLBY_DAX_AUDIO_PROCESSING + help + Mock DAX audio processing. It allows for compilation check and basic audio + flow checking. + config PASSTHROUGH_CODEC bool "Passthrough codec" help diff --git a/src/audio/module_adapter/iadk/system_agent.cpp b/src/audio/module_adapter/iadk/system_agent.cpp index 860d5b1b279b..caed8cf65860 100644 --- a/src/audio/module_adapter/iadk/system_agent.cpp +++ b/src/audio/module_adapter/iadk/system_agent.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include using namespace intel_adsp; using namespace intel_adsp::system; @@ -37,7 +39,7 @@ namespace system { /* Structure storing handles to system service operations */ -const AdspSystemService SystemAgent::system_service_ = { +const APP_TASK_DATA AdspSystemService SystemAgent::system_service_ = { native_system_service_log_message, native_system_service_safe_memcpy, native_system_service_safe_memmove, @@ -124,16 +126,17 @@ int SystemAgent::CheckIn(ProcessingModuleFactoryInterface& module_factory, typedef int (*create_instance_f)(uint32_t module_id, uint32_t instance_id, uint32_t core_id, void *mod_cfg, void *parent_ppl, void **mod_ptr); -int system_agent_start(uintptr_t entry_point, uint32_t module_id, uint32_t instance_id, - uint32_t core_id, uint32_t log_handle, void* mod_cfg, +int system_agent_start(const struct system_agent_params *params, const void **adapter) { uint32_t ret; - SystemAgent system_agent(module_id, instance_id, core_id, log_handle); + SystemAgent system_agent(params->module_id, params->instance_id, params->core_id, + params->log_handle); void* system_agent_p = reinterpret_cast(&system_agent); - create_instance_f ci = (create_instance_f)(entry_point); - ret = ci(module_id, instance_id, core_id, mod_cfg, NULL, &system_agent_p); + create_instance_f ci = (create_instance_f)(params->entry_point); + ret = ci(params->module_id, params->instance_id, params->core_id, params->mod_cfg, NULL, + &system_agent_p); IadkModuleAdapter* module_adapter = reinterpret_cast(system_agent_p); *adapter = module_adapter; diff --git a/src/audio/module_adapter/library/native_system_agent.c b/src/audio/module_adapter/library/native_system_agent.c index 9a93af6f3565..b93405b8bd27 100644 --- a/src/audio/module_adapter/library/native_system_agent.c +++ b/src/audio/module_adapter/library/native_system_agent.c @@ -19,21 +19,20 @@ typedef void* (*native_create_instance_f)(void *mod_cfg, void *parent_ppl, struct native_system_agent native_sys_agent; -int native_system_agent_start(uintptr_t entry_point, uint32_t module_id, uint32_t instance_id, - uint32_t core_id, uint32_t log_handle, void *mod_cfg, +int native_system_agent_start(const struct system_agent_params *params, const void **iface) { - native_sys_agent.module_id = module_id; - native_sys_agent.instance_id = instance_id; - native_sys_agent.core_id = core_id; - native_sys_agent.log_handle = log_handle; + native_sys_agent.module_id = params->module_id; + native_sys_agent.instance_id = params->instance_id; + native_sys_agent.core_id = params->core_id; + native_sys_agent.log_handle = params->log_handle; const void *ret; void *system_agent_p = &native_sys_agent; - native_create_instance_f ci = (native_create_instance_f)entry_point; + native_create_instance_f ci = (native_create_instance_f)params->entry_point; - ret = ci(mod_cfg, NULL, &system_agent_p); + ret = ci(params->mod_cfg, NULL, &system_agent_p); if (!ret) return -EINVAL; diff --git a/src/audio/module_adapter/library/native_system_service.c b/src/audio/module_adapter/library/native_system_service.c index 5126fa5ff12b..1c4688e885d0 100644 --- a/src/audio/module_adapter/library/native_system_service.c +++ b/src/audio/module_adapter/library/native_system_service.c @@ -19,6 +19,7 @@ #include #include #include +#include #define RSIZE_MAX 0x7FFFFFFF @@ -162,7 +163,7 @@ AdspErrorCode native_system_service_get_interface(enum interface_id id, return ADSP_NO_ERROR; } -const struct native_system_service native_system_service = { +const APP_TASK_DATA struct native_system_service native_system_service = { .basic = { .log_message = native_system_service_log_message, .safe_memcpy = native_system_service_safe_memcpy, diff --git a/src/audio/module_adapter/library/userspace_proxy.c b/src/audio/module_adapter/library/userspace_proxy.c new file mode 100644 index 000000000000..9e3927a12e6c --- /dev/null +++ b/src/audio/module_adapter/library/userspace_proxy.c @@ -0,0 +1,837 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Jaroslaw Stelter +// Author: Adrian Warecki + +/** + * \file audio/module_adapter/library/userspace_proxy.c + * \brief Userspace proxy. Acts as an intermediary between SOF and a userspace module. + * \brief Responsible for preparing the memory domain required for userspace execution + * \brief and forwarding API calls. The proxy invokes corresponding module methods + * \brief in userspace context. Enables execution of any module implementing module_interface + * \brief as a userspace module. + * \authors Adrian Warecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + /* Assume that all the code runs in supervisor mode and don't make system calls. */ +#define __ZEPHYR_SUPERVISOR__ + +LOG_MODULE_REGISTER(userspace_proxy, CONFIG_SOF_LOG_LEVEL); + +/* 6f6b6f4b-6f73-7466-20e1e62b9779f003 */ +SOF_DEFINE_REG_UUID(userspace_proxy); + +DECLARE_TR_CTX(userspace_proxy_tr, SOF_UUID(userspace_proxy_uuid), LOG_LEVEL_INFO); + +static const struct module_interface userspace_proxy_interface; + +/* IPC requests targeting userspace modules are handled through a user work queue. + * Each userspace module provides its own work item that carries the IPC request parameters. + * The worker thread is switched into the module's memory domain and receives the work item. + * It invokes the appropriate module function in userspace context and writes the operation + * result back into the work item. + * + * There is only a single work queue, which is shared by all userspace modules. It is created + * dynamically when needed. Because SOF uses a single dedicated thread for handling IPC, there + * is no need to perform any additional serialization when accessing the worker. + */ +struct user_worker { + k_tid_t thread_id; /* ipc worker thread ID */ + uint32_t reference_count; /* module reference count */ + void *stack_ptr; /* pointer to worker stack */ + struct k_work_user_q work_queue; + struct k_event event; +}; + +static struct user_worker worker; + +static int user_worker_get(void) +{ + if (worker.reference_count) { + worker.reference_count++; + return 0; + } + + worker.stack_ptr = user_stack_allocate(CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE, + K_USER); + if (!worker.stack_ptr) { + tr_err(&userspace_proxy_tr, "Userspace worker stack allocation failed."); + return -ENOMEM; + } + + k_event_init(&worker.event); + k_work_user_queue_start(&worker.work_queue, worker.stack_ptr, + CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE, 0, NULL); + + worker.thread_id = k_work_user_queue_thread_get(&worker.work_queue); + + k_thread_access_grant(worker.thread_id, &worker.event); + + worker.reference_count++; + return 0; +} + +static void user_worker_put(void) +{ + /* Module removed so decrement counter */ + worker.reference_count--; + + /* Free worker resources if no more active user space modules */ + if (worker.reference_count == 0) { + k_thread_abort(worker.thread_id); + user_stack_free(worker.stack_ptr); + } +} + +static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap *user_heap) +{ + struct user_work_item *work_item = NULL; + int ret; + + ret = user_worker_get(); + if (ret) + return ret; + + /* We have only a single userspace IPC worker. It handles requests for all userspace + * modules, which may run on different cores. Because the worker processes work items + * coming from any core, the work item must be allocated in coherent memory. + */ + work_item = sof_heap_alloc(user_heap, SOF_MEM_FLAG_COHERENT, sizeof(*work_item), 0); + if (!work_item) { + user_worker_put(); + return -ENOMEM; + } + + k_work_user_init(&work_item->work_item, userspace_proxy_worker_handler); + + work_item->event = &worker.event; + work_item->params.context = user_ctx; + user_ctx->work_item = work_item; + + return 0; +} + +static void user_work_item_free(struct userspace_context *user_ctx, struct k_heap *user_heap) +{ + sof_heap_free(user_heap, user_ctx->work_item); + user_worker_put(); +} + +static inline struct module_params *user_work_get_params(struct userspace_context *user_ctx) +{ + return &user_ctx->work_item->params; +} + +BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_BASE, CONFIG_MMU_PAGE_SIZE), + "MAILBOX_HOSTBOX_BASE is not page aligned"); + +BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE), + "MAILBOX_HOSTBOX_SIZE is not page aligned"); + +static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t cmd, + bool ipc_payload_access) +{ + struct module_params *params = user_work_get_params(user_ctx); + const uintptr_t ipc_req_buf = (uintptr_t)MAILBOX_HOSTBOX_BASE; + struct k_mem_partition ipc_part = { + .start = ipc_req_buf, + .size = MAILBOX_HOSTBOX_SIZE, + .attr = user_get_partition_attr(ipc_req_buf) | K_MEM_PARTITION_P_RO_U_RO, + }; + int ret, ret2; + + params->cmd = cmd; + + if (ipc_payload_access) { + ret = k_mem_domain_add_partition(user_ctx->comp_dom, &ipc_part); + if (ret < 0) { + tr_err(&userspace_proxy_tr, "Add mailbox to domain error: %d", ret); + return ret; + } + } + + /* Switch worker thread to module memory domain */ + ret = k_mem_domain_add_thread(user_ctx->comp_dom, worker.thread_id); + if (ret < 0) { + tr_err(&userspace_proxy_tr, "Failed to switch memory domain, error: %d", ret); + goto done; + } + + /* Pin worker thread to the same core as the module */ + ret = k_thread_cpu_pin(worker.thread_id, cpu_get_id()); + if (ret < 0) { + tr_err(&userspace_proxy_tr, "Failed to pin cpu, error: %d", ret); + goto done; + } + + ret = k_work_user_submit_to_queue(&worker.work_queue, &user_ctx->work_item->work_item); + if (ret < 0) { + tr_err(&userspace_proxy_tr, "Submit to queue error: %d", ret); + goto done; + } + + /* Timeout value is aligned with the ipc_wait_for_compound_msg function */ + if (!k_event_wait_safe(&worker.event, DP_TASK_EVENT_IPC_DONE, false, + Z_TIMEOUT_US(250 * 20))) { + tr_err(&userspace_proxy_tr, "IPC processing timedout."); + ret = -ETIMEDOUT; + } + +done: + if (ipc_payload_access) { + ret2 = k_mem_domain_remove_partition(user_ctx->comp_dom, &ipc_part); + if (ret2 < 0) { + tr_err(&userspace_proxy_tr, "Mailbox remove from domain error: %d", ret); + + if (!ret) + ret = ret2; + } + } + + return ret; +} + +extern struct k_mem_partition common_partition; + +static int userspace_proxy_memory_init(struct userspace_context *user_ctx, + const struct comp_driver *drv) +{ + /* Add module private heap to memory partitions */ + struct k_mem_partition heap_part = { .attr = K_MEM_PARTITION_P_RW_U_RW }; + struct sys_heap *heap = &drv->user_heap->heap; + + k_mem_region_align(&heap_part.start, &heap_part.size, + POINTER_TO_UINT(heap->init_mem), + heap->init_bytes, CONFIG_MM_DRV_PAGE_SIZE); + + tr_dbg(&userspace_proxy_tr, "Heap partition %#lx + %zx, attr = %u", + heap_part.start, heap_part.size, heap_part.attr); + +#if !defined(CONFIG_XTENSA_MMU_DOUBLE_MAP) && defined(CONFIG_SOF_ZEPHYR_HEAP_CACHED) +#define HEAP_PART_CACHED + /* Add cached module private heap to memory partitions */ + struct k_mem_partition heap_cached_part = { + .attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB + }; + + k_mem_region_align(&heap_cached_part.start, &heap_cached_part.size, + POINTER_TO_UINT(sys_cache_cached_ptr_get(heap->init_mem)), + heap->init_bytes, CONFIG_MM_DRV_PAGE_SIZE); + + tr_dbg(&userspace_proxy_tr, "Cached heap partition %#lx + %zx, attr = %u", + heap_cached_part.start, heap_cached_part.size, heap_cached_part.attr); +#endif + + struct k_mem_partition *parts_ptr[] = { + /* The common partition contains sof components accessible to the userspace module. + * These include ops structures marked with APP_TASK_DATA. + */ + &common_partition, +#ifdef HEAP_PART_CACHED + &heap_cached_part, +#endif + &heap_part + }; + + tr_dbg(&userspace_proxy_tr, "Common partition %#lx + %zx, attr = %u", + common_partition.start, common_partition.size, common_partition.attr); + + return k_mem_domain_init(user_ctx->comp_dom, ARRAY_SIZE(parts_ptr), parts_ptr); +} + +static int userspace_proxy_add_sections(struct userspace_context *user_ctx, uint32_t instance_id, + const struct sof_man_module *const mod) +{ + struct k_mem_partition mem_partition; + void *va_base; + int idx, ret; + + for (idx = 0; idx < ARRAY_SIZE(mod->segment); ++idx) { + if (!mod->segment[idx].flags.r.load) + continue; + + if (mod->segment[idx].flags.r.code) + mem_partition.attr = K_MEM_PARTITION_P_RX_U_RX; + else if (!mod->segment[idx].flags.r.readonly) + mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW; + else + mem_partition.attr = K_MEM_PARTITION_P_RO_U_RO; + + mem_partition.start = mod->segment[idx].v_base_addr; + mem_partition.size = mod->segment[idx].flags.r.length * CONFIG_MM_DRV_PAGE_SIZE; + mem_partition.attr |= user_get_partition_attr(mem_partition.start); + + ret = k_mem_domain_add_partition(user_ctx->comp_dom, &mem_partition); + + tr_dbg(&userspace_proxy_tr, "Add mod partition %#lx + %zx, attr = %u, ret = %d", + mem_partition.start, mem_partition.size, mem_partition.attr, ret); + + if (ret < 0) + return ret; + } + + lib_manager_get_instance_bss_address(instance_id, mod, &va_base, &mem_partition.size); + mem_partition.start = POINTER_TO_UINT(va_base); + mem_partition.attr = user_get_partition_attr(mem_partition.start) | + K_MEM_PARTITION_P_RW_U_RW; + ret = k_mem_domain_add_partition(user_ctx->comp_dom, &mem_partition); + + tr_dbg(&userspace_proxy_tr, "Add bss partition %#lx + %zx, attr = %u, ret = %d", + mem_partition.start, mem_partition.size, mem_partition.attr, ret); + + return ret; +} + +static int userspace_proxy_start_agent(struct userspace_context *user_ctx, + system_agent_start_fn start_fn, + const struct system_agent_params *agent_params, + const void **agent_interface) +{ + const byte_array_t * const mod_cfg = (byte_array_t *)agent_params->mod_cfg; + struct module_params *params = user_work_get_params(user_ctx); + int ret; + + params->ext.agent.start_fn = start_fn; + params->ext.agent.params = *agent_params; + params->ext.agent.mod_cfg = *mod_cfg; + + ret = userspace_proxy_invoke(user_ctx, USER_PROXY_MOD_CMD_AGENT_START, true); + if (ret) + return ret; + + *agent_interface = params->ext.agent.out_interface; + return params->status; +} + +int userspace_proxy_create(struct userspace_context **user_ctx, const struct comp_driver *drv, + const struct sof_man_module *manifest, system_agent_start_fn start_fn, + const struct system_agent_params *agent_params, + const void **agent_interface, const struct module_interface **ops) +{ + struct userspace_context *context; + struct k_mem_domain *domain; + int ret; + + tr_dbg(&userspace_proxy_tr, "userspace create"); + + context = k_heap_alloc(drv->user_heap, sizeof(struct userspace_context), K_FOREVER); + if (!context) + return -ENOMEM; + + /* Allocate memory domain struct */ + domain = rzalloc(SOF_MEM_FLAG_KERNEL, sizeof(*domain)); + if (!domain) { + ret = -ENOMEM; + goto error; + } + context->comp_dom = domain; + + ret = userspace_proxy_memory_init(context, drv); + if (ret) + goto error_dom; + + ret = userspace_proxy_add_sections(context, agent_params->instance_id, manifest); + if (ret) + goto error_dom; + + ret = user_work_item_init(context, drv->user_heap); + if (ret) + goto error_dom; + + /* Start the system agent, if provided. */ + + if (start_fn) { + ret = userspace_proxy_start_agent(context, start_fn, agent_params, agent_interface); + if (ret) { + tr_err(&userspace_proxy_tr, "System agent failed with error %d.", ret); + goto error_work_item; + } + } + + *user_ctx = context; + + /* Store a pointer to the module's interface. For the LMDK modules, the agent places a + * pointer to the module interface at the address specified by agent_interface. Since this + * points to ops, the assignment of the module interface used by this proxy must occur + * after the agent has been started. For other module types, the ops parameter points to a + * valid module interface. + */ + context->interface = *ops; + + /* All calls to the module interface must pass through the proxy. Set up our own interface. + */ + *ops = &userspace_proxy_interface; + + return 0; + +error_work_item: + user_work_item_free(context, drv->user_heap); +error_dom: + rfree(domain); +error: + k_heap_free(drv->user_heap, context); + return ret; +} + +void userspace_proxy_destroy(const struct comp_driver *drv, struct userspace_context *user_ctx) +{ + tr_dbg(&userspace_proxy_tr, "userspace proxy destroy"); + user_work_item_free(user_ctx, drv->user_heap); + rfree(user_ctx->comp_dom); + k_heap_free(drv->user_heap, user_ctx); +} + +/** + * Copy parameters to user worker accessible space. + * Queue module init() operation and return its result. + * Module init() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_init(struct processing_module *mod) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + params->mod = mod; + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_INIT, true); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module prepare() operation and return its result. + * Module prepare() code is performed in user workqueue. + * + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->prepare) + return 0; + + params->ext.proc.sources = sources; + params->ext.proc.num_of_sources = num_of_sources; + params->ext.proc.sinks = sinks; + params->ext.proc.num_of_sinks = num_of_sinks; + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_PREPARE, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Forward processing request to the module's process() implementation. + * + * It is invoked by the DP thread running in userspace, so no + * additional queuing or context switching is performed here. + * + * @param mod Pointer to the processing module instance. + * @param sources Array of input sources for the module. + * @param num_of_sources Number of input sources. + * @param sinks Array of output sinks for the module. + * @param num_of_sinks Number of output sinks. + * + * @return 0 on success, negative error code on failure. + */ +static int userspace_proxy_process(struct processing_module *mod, struct sof_source **sources, + int num_of_sources, struct sof_sink **sinks, int num_of_sinks) +{ + return mod->user_ctx->interface->process(mod, sources, num_of_sources, sinks, num_of_sinks); +} + +/** + * Copy parameters to user worker accessible space. + * Queue module reset() operation and return its result. + * Module reset() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_reset(struct processing_module *mod) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + if (!mod->user_ctx->interface->reset) + return 0; + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_RESET, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module free() operation and return its result. + * Module free() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_free(struct processing_module *mod) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret = 0; + + comp_dbg(mod->dev, "start"); + + if (mod->user_ctx->interface->free) { + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_FREE, false); + if (ret) + return ret; + ret = params->status; + } + + /* Destroy workqueue if this was last active userspace module */ + userspace_proxy_destroy(mod->dev->drv, mod->user_ctx); + mod->user_ctx = NULL; + + /* Return status from module code operation. */ + return ret; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module set_configuration() operation and return its result. + * Module set_configuration() code is performed in user workqueue. + * + * @param[in] mod - struct processing_module pointer + * @param[in] config_id - Configuration ID + * @param[in] pos - position of the fragment in the large message + * @param[in] data_offset_size: size of the whole configuration if it is the first fragment or the + * only fragment. Otherwise, it is the offset of the fragment in the whole + * configuration. + * @param[in] fragment: configuration fragment buffer + * @param[in] fragment_size: size of @fragment + * @params[in] response: optional response buffer to fill + * @params[in] response_size: size of @response + * + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_set_configuration(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, const uint8_t *fragment, + size_t fragment_size, uint8_t *response, + size_t response_size) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->set_configuration) + return 0; + + params->ext.set_conf.config_id = config_id; + params->ext.set_conf.pos = pos; + params->ext.set_conf.data_off_size = data_offset_size; + params->ext.set_conf.fragment = fragment; + params->ext.set_conf.fragment_size = fragment_size; + params->ext.set_conf.response = response; + params->ext.set_conf.response_size = response_size; + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_SET_CONF, true); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module get_configuration() operation and return its result. + * Module get_configuration() code is performed in user workqueue. + * + * @param[in] mod - struct processing_module pointer + * @param[in] config_id - Configuration ID + * @param[in] data_offset_size: size of the whole configuration if it is the first fragment or the + * only fragment. Otherwise, it is the offset of the fragment in the whole + * configuration. + * @param[in] fragment: configuration fragment buffer + * @param[in] fragment_size: size of @fragment + * + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_get_configuration(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, + size_t fragment_size) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + struct k_mem_domain *domain = mod->user_ctx->comp_dom; + const uintptr_t ipc_resp_buf = POINTER_TO_UINT(ipc_get()->comp_data); + + /* Memory partition exposing the IPC response buffer. This buffer is allocated + * by the IPC driver and contains the payload of IPC replies sent to the host. + */ + struct k_mem_partition ipc_resp_part = { + .start = ipc_resp_buf, + .size = SOF_IPC_MSG_MAX_SIZE, + .attr = user_get_partition_attr(ipc_resp_buf) | K_MEM_PARTITION_P_RW_U_RW, + }; + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->get_configuration) + return -EIO; + + params->ext.get_conf.config_id = config_id; + params->ext.get_conf.data_off_size = data_offset_size; + params->ext.get_conf.fragment = fragment; + params->ext.get_conf.fragment_size = fragment_size; + + ret = k_mem_domain_add_partition(domain, &ipc_resp_part); + if (ret < 0) { + comp_err(mod->dev, "add response buffer to domain error: %d", ret); + return ret; + } + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_GET_CONF, true); + + k_mem_domain_remove_partition(domain, &ipc_resp_part); + + /* Return status from module code operation. */ + return ret ? ret : params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module set_processing_mode() operation and return its result. + * Module set_processing_mode() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @param mode - processing mode to be set. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_set_processing_mode(struct processing_module *mod, + enum module_processing_mode mode) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->set_processing_mode) + return 0; + + params->ext.proc_mode.mode = mode; + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_SET_PROCMOD, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module get_processing_mode() operation and return its result. + * Module get_processing_mode() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return processing mode. + */ +static +enum module_processing_mode userspace_proxy_get_processing_mode(struct processing_module *mod) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->get_processing_mode) + return -EIO; + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_GET_PROCMOD, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->ext.proc_mode.mode; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module is_ready_to_process() operation and return its result. + * Module is_ready_to_process() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return true if the module is ready to process + */ +static bool userspace_proxy_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, + int num_of_sources, + struct sof_sink **sinks, + int num_of_sinks) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->is_ready_to_process) + return generic_module_is_ready_to_process(mod, sources, num_of_sources, sinks, + num_of_sinks); + + params->ext.proc.sources = sources; + params->ext.proc.num_of_sources = num_of_sources; + params->ext.proc.sinks = sinks; + params->ext.proc.num_of_sinks = num_of_sinks; + + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_PROC_READY, false); + if (ret) + return generic_module_is_ready_to_process(mod, sources, num_of_sources, sinks, + num_of_sinks); + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module bind() operation and return its result. + * Module bind() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @param bind_data - pointer to bind_info structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_bind(struct processing_module *mod, struct bind_info *bind_data) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->bind) + return 0; + + params->ext.bind_data = bind_data; + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_BIND, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module unbind() operation and return its result. + * Module unbind() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @param unbind_data - pointer to bind_info structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_unbind(struct processing_module *mod, struct bind_info *unbind_data) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret; + + comp_dbg(mod->dev, "start"); + + if (!mod->user_ctx->interface->unbind) + return 0; + + params->ext.bind_data = unbind_data; + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_UNBIND, false); + if (ret) + return ret; + + /* Return status from module code operation. */ + return params->status; +} + +/** + * Copy parameters to user worker accessible space. + * Queue module trigger() operation and return its result. + * Module trigger() code is performed in user workqueue. + * + * @param mod - pointer to processing module structure. + * @return 0 for success, error otherwise. + */ +static int userspace_proxy_trigger(struct processing_module *mod, int cmd) +{ + struct module_params *params = user_work_get_params(mod->user_ctx); + int ret = 0; + + comp_dbg(mod->dev, "start"); + + if (mod->user_ctx->interface->trigger) { + params->ext.trigger_data = cmd; + ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_TRIGGER, false); + if (ret) + return ret; + ret = params->status; + } + + if (!ret) + ret = module_adapter_set_state(mod, mod->dev, cmd); + + /* Return status from module code operation. */ + return ret; +} + +/* Userspace Proxy Module API */ +APP_TASK_DATA static const struct module_interface userspace_proxy_interface = { + .init = userspace_proxy_init, + .is_ready_to_process = userspace_proxy_is_ready_to_process, + .prepare = userspace_proxy_prepare, + .process = userspace_proxy_process, + .set_configuration = userspace_proxy_set_configuration, + .get_configuration = userspace_proxy_get_configuration, + .set_processing_mode = userspace_proxy_set_processing_mode, + .get_processing_mode = userspace_proxy_get_processing_mode, + .reset = userspace_proxy_reset, + .free = userspace_proxy_free, + .bind = userspace_proxy_bind, + .unbind = userspace_proxy_unbind, + .trigger = userspace_proxy_trigger, +}; diff --git a/src/audio/module_adapter/library/userspace_proxy_user.c b/src/audio/module_adapter/library/userspace_proxy_user.c new file mode 100644 index 000000000000..722a790e66fb --- /dev/null +++ b/src/audio/module_adapter/library/userspace_proxy_user.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// Author: Adrian Warecki + +/** + * \file audio/module_adapter/library/userspace_proxy_user.c + * \brief Userspace proxy functions executed only in userspace context. + * \authors Adrian Warecki + */ + +/* Assume that all the code runs in user mode and unconditionally makes system calls. */ +#define __ZEPHYR_USER__ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +void userspace_proxy_handle_request(struct processing_module *mod, struct module_params *params) +{ + const struct module_interface *ops = params->context->interface; + + switch (params->cmd) { + case USER_PROXY_MOD_CMD_AGENT_START: + /* Set pointer to user accessible mod_cfg structure. */ + params->ext.agent.params.mod_cfg = ¶ms->ext.agent.mod_cfg; + + params->status = params->ext.agent.start_fn(¶ms->ext.agent.params, + ¶ms->ext.agent.out_interface); + break; + + case USER_PROXY_MOD_CMD_INIT: + params->status = ops->init(params->mod); + break; + + case USER_PROXY_MOD_CMD_PREPARE: + params->status = ops->prepare(params->mod, params->ext.proc.sources, + params->ext.proc.num_of_sources, + params->ext.proc.sinks, + params->ext.proc.num_of_sinks); + break; + + case USER_PROXY_MOD_CMD_PROC_READY: + params->status = ops->is_ready_to_process(params->mod, + params->ext.proc.sources, + params->ext.proc.num_of_sources, + params->ext.proc.sinks, + params->ext.proc.num_of_sinks); + break; + + case USER_PROXY_MOD_CMD_BIND: + params->status = ops->bind(params->mod, params->ext.bind_data); + break; + + case USER_PROXY_MOD_CMD_UNBIND: + params->status = ops->unbind(params->mod, params->ext.bind_data); + break; + + case USER_PROXY_MOD_CMD_RESET: + params->status = ops->reset(params->mod); + break; + + case USER_PROXY_MOD_CMD_FREE: + params->status = ops->free(params->mod); + break; + + case USER_PROXY_MOD_CMD_SET_CONF: + params->status = ops->set_configuration(params->mod, + params->ext.set_conf.config_id, + params->ext.set_conf.pos, + params->ext.set_conf.data_off_size, + params->ext.set_conf.fragment, + params->ext.set_conf.fragment_size, + params->ext.set_conf.response, + params->ext.set_conf.response_size); + break; + + case USER_PROXY_MOD_CMD_GET_CONF: + params->status = ops->get_configuration(params->mod, + params->ext.get_conf.config_id, + params->ext.get_conf.data_off_size, + params->ext.get_conf.fragment, + params->ext.get_conf.fragment_size); + break; + + case USER_PROXY_MOD_CMD_SET_PROCMOD: + params->status = ops->set_processing_mode(params->mod, + params->ext.proc_mode.mode); + break; + + case USER_PROXY_MOD_CMD_GET_PROCMOD: + params->ext.proc_mode.mode = ops->get_processing_mode(params->mod); + break; + + case USER_PROXY_MOD_CMD_TRIGGER: + params->status = ops->trigger(params->mod, params->ext.trigger_data); + break; + + default: + params->status = -EINVAL; + break; + } +} + +void userspace_proxy_worker_handler(struct k_work_user *work_item) +{ + struct user_work_item *user_work_item = CONTAINER_OF(work_item, struct user_work_item, + work_item); + struct module_params *params = &user_work_item->params; + + userspace_proxy_handle_request(params->mod, params); + k_event_post(user_work_item->event, DP_TASK_EVENT_IPC_DONE); +} diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 05717eab6932..fbec980ccef9 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -1,15 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause // -// Copyright(c) 2020 Intel Corporation. All rights reserved. +// Copyright(c) 2020 - 2026 Intel Corporation. All rights reserved. // -// Author: Marcin Rajwa - -/* - * \file cadence.c - * \brief Cadence Codec API - * \author Marcin Rajwa - * - */ #include #include @@ -18,29 +10,10 @@ LOG_MODULE_REGISTER(cadence_codec, CONFIG_SOF_LOG_LEVEL); -SOF_DEFINE_REG_UUID(cadence_codec); - -DECLARE_TR_CTX(cadence_codec_tr, SOF_UUID(cadence_codec_uuid), LOG_LEVEL_INFO); - -enum cadence_api_id { - CADENCE_CODEC_WRAPPER_ID = 0x01, - CADENCE_CODEC_AAC_DEC_ID = 0x02, - CADENCE_CODEC_BSAC_DEC_ID = 0x03, - CADENCE_CODEC_DAB_DEC_ID = 0x04, - CADENCE_CODEC_DRM_DEC_ID = 0x05, - CADENCE_CODEC_MP3_DEC_ID = 0x06, - CADENCE_CODEC_SBC_DEC_ID = 0x07, - CADENCE_CODEC_VORBIS_DEC_ID = 0x08, - CADENCE_CODEC_SRC_PP_ID = 0x09, - CADENCE_CODEC_MP3_ENC_ID = 0x0A, -}; - -#define DEFAULT_CODEC_ID CADENCE_CODEC_WRAPPER_ID - /*****************************************************************************/ /* Cadence API functions array */ /*****************************************************************************/ -static struct cadence_api cadence_api_table[] = { +struct cadence_api cadence_api_table[] = { #ifdef CONFIG_CADENCE_CODEC_WRAPPER { .id = CADENCE_CODEC_WRAPPER_ID, @@ -103,52 +76,15 @@ static struct cadence_api cadence_api_table[] = { #endif }; -#if CONFIG_IPC_MAJOR_4 -static int cadence_codec_resolve_api(struct processing_module *mod) -{ - struct comp_dev *dev = mod->dev; - struct cadence_codec_data *cd = module_get_private_data(mod); - uint32_t api_id = CODEC_GET_API_ID(DEFAULT_CODEC_ID); - uint32_t n_apis = ARRAY_SIZE(cadence_api_table); - struct module_data *codec = &mod->priv; - struct module_param *param; - int i; - xa_codec_func_t *api = NULL; - - /* For ipc4 protocol codec parameters has to be retrieved from configuration */ - if (!codec->cfg.data) { - comp_err(dev, "could not find cadence config"); - return -EINVAL; - } - param = codec->cfg.data; - api_id = param->id >> 16; - - /* Find and assign API function */ - for (i = 0; i < n_apis; i++) { - if (cadence_api_table[i].id == api_id) { - api = cadence_api_table[i].api; - break; - } - } - - /* Verify API assignment */ - if (!api) { - comp_err(dev, "could not find API function for id %x", - api_id); - return -EINVAL; - } - cd->api = api; - cd->api_id = api_id; - - return 0; -} -#elif CONFIG_IPC_MAJOR_3 -static int cadence_code_get_api_id(uint32_t compress_id) +static int cadence_codec_get_api_id(uint32_t compress_id, uint32_t direction) { /* convert compress id to SOF cadence SOF id */ switch (compress_id) { case SND_AUDIOCODEC_MP3: - return CADENCE_CODEC_MP3_DEC_ID; + if (direction == SOF_IPC_STREAM_PLAYBACK) + return CADENCE_CODEC_MP3_DEC_ID; + + return CADENCE_CODEC_MP3_ENC_ID; case SND_AUDIOCODEC_AAC: return CADENCE_CODEC_AAC_DEC_ID; case SND_AUDIOCODEC_VORBIS: @@ -158,314 +94,21 @@ static int cadence_code_get_api_id(uint32_t compress_id) } } -static int cadence_codec_resolve_api(struct processing_module *mod) +void cadence_codec_free_memory_tables(struct processing_module *mod) { - int ret; - struct snd_codec codec_params; - struct comp_dev *dev = mod->dev; struct cadence_codec_data *cd = module_get_private_data(mod); - uint32_t api_id = CODEC_GET_API_ID(DEFAULT_CODEC_ID); - uint32_t n_apis = ARRAY_SIZE(cadence_api_table); int i; - xa_codec_func_t *api = NULL; - - if (mod->stream_params->ext_data_length) { - ret = memcpy_s(&codec_params, mod->stream_params->ext_data_length, - (uint8_t *)mod->stream_params + sizeof(*mod->stream_params), - mod->stream_params->ext_data_length); - if (ret < 0) - return ret; - - ret = cadence_code_get_api_id(codec_params.id); - if (ret < 0) - return ret; - - api_id = ret; - } - - /* Find and assign API function */ - for (i = 0; i < n_apis; i++) { - if (cadence_api_table[i].id == api_id) { - api = cadence_api_table[i].api; - break; - } - } - - /* Verify API assignment */ - if (!api) { - comp_err(dev, "could not find API function for id %x", - api_id); - return -EINVAL; - } - cd->api = api; - cd->api_id = api_id; - - return 0; -} -#else -#error Unknown IPC major version -#endif - -static int cadence_codec_post_init(struct processing_module *mod) -{ - int ret; - struct comp_dev *dev = mod->dev; - struct cadence_codec_data *cd = module_get_private_data(mod); - uint32_t obj_size; - - comp_dbg(dev, "cadence_codec_post_init() start"); - - ret = cadence_codec_resolve_api(mod); - if (ret < 0) - return ret; - - /* Obtain codec name */ - API_CALL(cd, XA_API_CMD_GET_LIB_ID_STRINGS, - XA_CMD_TYPE_LIB_NAME, cd->name, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init() error %x: failed to get lib name", - ret); - return ret; - } - /* Get codec object size */ - API_CALL(cd, XA_API_CMD_GET_API_SIZE, 0, &obj_size, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init() error %x: failed to get lib object size", - ret); - return ret; - } - /* Allocate space for codec object */ - cd->self = rballoc(SOF_MEM_FLAG_USER, obj_size); - if (!cd->self) { - comp_err(dev, "failed to allocate space for lib object"); - return -ENOMEM; - } - - comp_dbg(dev, "allocated %d bytes for lib object", obj_size); - - /* Set all params to their default values */ - API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, - NULL, ret); - if (ret != LIB_NO_ERROR) { - rfree(cd->self); - return ret; - } - comp_dbg(dev, "cadence_codec_post_init() done"); + if (cd->mem_to_be_freed) + for (i = 0; i < cd->mem_to_be_freed_len; i++) + mod_free(mod, cd->mem_to_be_freed[i]); - return 0; + mod_free(mod, cd->mem_to_be_freed); + cd->mem_to_be_freed = NULL; + cd->mem_to_be_freed_len = 0; } -#if CONFIG_IPC_MAJOR_4 -static int cadence_codec_init(struct processing_module *mod) -{ - const struct ipc4_cadence_module_cfg *cfg; - struct module_data *codec = &mod->priv; - struct cadence_codec_data *cd; - struct module_config *setup_cfg; - struct comp_dev *dev = mod->dev; - int ret; - - comp_dbg(dev, "cadence_codec_init() start"); - - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct cadence_codec_data)); - if (!cd) { - comp_err(dev, "failed to allocate memory for cadence codec data"); - return -ENOMEM; - } - - codec->private = cd; - codec->mpd.init_done = 0; - - /* copy the setup config only for the first init */ - if (codec->state == MODULE_DISABLED && codec->cfg.avail) { - setup_cfg = &cd->setup_cfg; - - cfg = (const struct ipc4_cadence_module_cfg *)codec->cfg.init_data; - - /* allocate memory for set up config */ - setup_cfg->data = rmalloc(SOF_MEM_FLAG_USER, - cfg->param_size); - if (!setup_cfg->data) { - comp_err(dev, "failed to alloc setup config"); - ret = -ENOMEM; - goto free; - } - - /* allocate memory for runtime set up config */ - codec->cfg.data = rmalloc(SOF_MEM_FLAG_USER, - cfg->param_size); - if (!codec->cfg.data) { - comp_err(dev, "failed to alloc runtime setup config"); - ret = -ENOMEM; - goto free_cfg; - } - - codec->cfg.size = cfg->param_size; - ret = memcpy_s(codec->cfg.data, codec->cfg.size, - cfg->param, cfg->param_size); - if (ret) { - comp_err(dev, "failed to init runtime config %d", - ret); - goto free_cfg2; - } - codec->cfg.avail = true; - - setup_cfg->size = cfg->param_size; - ret = memcpy_s(setup_cfg->data, setup_cfg->size, - cfg->param, cfg->param_size); - if (ret) { - comp_err(dev, "failed to copy setup config %d", ret); - goto free_cfg2; - } - setup_cfg->avail = true; - } - - comp_dbg(dev, "cadence_codec_init() done"); - - return 0; - -free_cfg2: - rfree(codec->cfg.data); -free_cfg: - rfree(setup_cfg->data); -free: - rfree(cd); - return ret; -} - -#elif CONFIG_IPC_MAJOR_3 -static int cadence_codec_init(struct processing_module *mod) -{ - struct module_data *codec = &mod->priv; - struct cadence_codec_data *cd; - struct comp_dev *dev = mod->dev; - struct module_config *setup_cfg; - int ret; - - comp_dbg(dev, "cadence_codec_init() start"); - - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct cadence_codec_data)); - if (!cd) { - comp_err(dev, "failed to allocate memory for cadence codec data"); - return -ENOMEM; - } - - codec->private = cd; - codec->mpd.init_done = 0; - - /* copy the setup config only for the first init */ - if (codec->state == MODULE_DISABLED && codec->cfg.avail) { - setup_cfg = &cd->setup_cfg; - - /* allocate memory for set up config */ - setup_cfg->data = rmalloc(SOF_MEM_FLAG_USER, - codec->cfg.size); - if (!setup_cfg->data) { - comp_err(dev, "failed to alloc setup config"); - ret = -ENOMEM; - goto free; - } - - /* copy the setup config */ - setup_cfg->size = codec->cfg.size; - ret = memcpy_s(setup_cfg->data, setup_cfg->size, - codec->cfg.init_data, setup_cfg->size); - if (ret) { - comp_err(dev, "failed to copy setup config %d", ret); - goto free_cfg; - } - setup_cfg->avail = true; - } - - comp_dbg(dev, "cadence_codec_init() done"); - - return 0; - -free_cfg: - rfree(setup_cfg->data); -free: - rfree(cd); - return ret; -} - -#else -#error Unknown IPC major version -#endif - -static int cadence_codec_apply_config(struct processing_module *mod) -{ - int ret = 0; - int size; - uint16_t param_id; - uint16_t codec_id; - struct module_config *cfg; - void *data; - struct module_param *param; - struct comp_dev *dev = mod->dev; - struct module_data *codec = &mod->priv; - struct cadence_codec_data *cd = codec->private; - - comp_dbg(dev, "cadence_codec_apply_config() start"); - - cfg = &codec->cfg; - - /* use setup config if no runtime config available. This will be true during reset */ - if (!cfg->avail) - cfg = &cd->setup_cfg; - - data = cfg->data; - size = cfg->size; - - if (!cfg->avail || !size) { - comp_err(dev, "cadence_codec_apply_config() error: no config available"); - return -EIO; - } - - /* Read parameters stored in `data` - it may keep plenty of - * parameters. The `size` variable is equal to param->size * count, - * where count is number of parameters stored in `data`. - */ - while (size > 0) { - param = data; - comp_dbg(dev, "cadence_codec_apply_config() applying param %d value %d", - param->id, param->data[0]); - - param_id = param->id & 0xFF; - codec_id = param->id >> 16; - - /* if the parameter is not for current codec skip it! */ - if (codec_id && codec_id != cd->api_id) { - /* Obtain next parameter */ - data = (char *)data + param->size; - size -= param->size; - continue; - } - - /* Set read parameter */ - API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, param_id, - param->data, ret); - if (ret != LIB_NO_ERROR) { - if (LIB_IS_FATAL_ERROR(ret)) { - comp_err(dev, "failed to apply parameter: %d value: %d error: %#x", - param->id, *(int32_t *)param->data, ret); - - return ret; - } - comp_warn(dev, "applied parameter %d value %d with return code: %#x", - param->id, *(int32_t *)param->data, ret); - } - /* Obtain next parameter, it starts right after the preceding one */ - data = (char *)data + param->size; - size -= param->size; - } - - comp_dbg(dev, "cadence_codec_apply_config() done"); - - return 0; -} - -static int init_memory_tables(struct processing_module *mod) +int cadence_codec_init_memory_tables(struct processing_module *mod) { int ret, no_mem_tables, i, mem_type, mem_size, mem_alignment; void *ptr, *scratch, *persistent; @@ -480,7 +123,7 @@ static int init_memory_tables(struct processing_module *mod) API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to calculate memory blocks size", + comp_err(dev, "error %x: failed to calculate memory blocks size", ret); return ret; } @@ -488,17 +131,22 @@ static int init_memory_tables(struct processing_module *mod) /* Get number of memory tables */ API_CALL(cd, XA_API_CMD_GET_N_MEMTABS, 0, &no_mem_tables, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to get number of memory tables", + comp_err(dev, "error %x: failed to get number of memory tables", ret); return ret; } + cd->mem_to_be_freed = mod_zalloc(mod, no_mem_tables * sizeof(*cd->mem_to_be_freed)); + if (!cd->mem_to_be_freed) + return -ENOMEM; + cd->mem_to_be_freed_len = no_mem_tables; + /* Initialize each memory table */ for (i = 0; i < no_mem_tables; i++) { /* Get type of memory - it specifies how the memory will be used */ API_CALL(cd, XA_API_CMD_GET_MEM_INFO_TYPE, i, &mem_type, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to get mem. type info of id %d out of %d", + comp_err(dev, "error %x: failed to get mem. type info of id %d out of %d", ret, i, no_mem_tables); goto err; } @@ -507,29 +155,30 @@ static int init_memory_tables(struct processing_module *mod) */ API_CALL(cd, XA_API_CMD_GET_MEM_INFO_SIZE, i, &mem_size, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to get mem. size for mem. type %d", + comp_err(dev, "error %x: failed to get mem. size for mem. type %d", ret, mem_type); goto err; } /* Get alignment constrains */ API_CALL(cd, XA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &mem_alignment, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to get mem. alignment of mem. type %d", + comp_err(dev, "error %x: failed to get mem. alignment of mem. type %d", ret, mem_type); goto err; } /* Allocate memory for this type, taking alignment into account */ ptr = mod_alloc_align(mod, mem_size, mem_alignment); if (!ptr) { - comp_err(dev, "init_memory_tables() error %x: failed to allocate memory for %d", + comp_err(dev, "error %x: failed to allocate memory for %d", ret, mem_type); ret = -EINVAL; goto err; } + cd->mem_to_be_freed[i] = ptr; /* Finally, provide this memory for codec */ API_CALL(cd, XA_API_CMD_SET_MEM_PTR, i, ptr, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "init_memory_tables() error %x: failed to set memory pointer for %d", + comp_err(dev, "error %x: failed to set memory pointer for %d", ret, mem_type); goto err; } @@ -550,35 +199,34 @@ static int init_memory_tables(struct processing_module *mod) codec->mpd.out_buff_size = mem_size; break; default: - comp_err(dev, "init_memory_tables() error %x: unrecognized memory type!", + comp_err(dev, "error %x: unrecognized memory type!", mem_type); ret = -EINVAL; goto err; } - comp_dbg(dev, "init_memory_tables: allocated memory of %d bytes and alignment %d for mem. type %d", + comp_dbg(dev, "allocated memory of %d bytes and alignment %d for mem. type %d", mem_size, mem_alignment, mem_type); } return 0; err: - if (scratch) - mod_free(mod, scratch); - if (persistent) - mod_free(mod, persistent); - if (codec->mpd.in_buff) - mod_free(mod, codec->mpd.in_buff); - if (codec->mpd.out_buff) - mod_free(mod, codec->mpd.out_buff); + cadence_codec_free_memory_tables(mod); + return ret; } -static int cadence_codec_get_samples(struct processing_module *mod) +size_t cadence_api_table_size(void) +{ + return ARRAY_SIZE(cadence_api_table); +} + +int cadence_codec_get_samples(struct processing_module *mod) { struct cadence_codec_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "cadence_codec_get_samples() start"); + comp_dbg(dev, "start"); switch (cd->api_id) { case CADENCE_CODEC_WRAPPER_ID: @@ -595,35 +243,26 @@ static int cadence_codec_get_samples(struct processing_module *mod) return 0; } -static int cadence_codec_deep_buff_allowed(struct processing_module *mod) -{ - struct cadence_codec_data *cd = module_get_private_data(mod); - - switch (cd->api_id) { - case CADENCE_CODEC_MP3_ENC_ID: - return 0; - default: - return 1; - } -} - -static int cadence_codec_init_process(struct processing_module *mod) +int cadence_codec_init_process(struct processing_module *mod) { int ret; struct module_data *codec = &mod->priv; struct cadence_codec_data *cd = codec->private; struct comp_dev *dev = mod->dev; + codec->mpd.eos_reached = false; + codec->mpd.eos_notification_sent = false; + API_CALL(cd, XA_API_CMD_SET_INPUT_BYTES, 0, &codec->mpd.avail, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init_process() error %x: failed to set size of input data", + comp_err(dev, "error %x: failed to set size of input data", ret); return ret; } API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_PROCESS, NULL, ret); if (LIB_IS_FATAL_ERROR(ret)) { - comp_err(dev, "cadence_codec_init_process() error %x: failed to initialize codec", + comp_err(dev, "error %x: failed to initialize codec", ret); return ret; } else if (ret != LIB_NO_ERROR) { @@ -636,21 +275,21 @@ static int cadence_codec_init_process(struct processing_module *mod) * a non-fatal error and let the init process continue. Next * chunk will contain the useful data. */ - comp_warn(dev, "cadence_codec_init_process() returned non-fatal error: 0x%x", + comp_warn(dev, "returned non-fatal error: 0x%x", ret); } API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, &codec->mpd.init_done, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init_process() error %x: failed to get lib init status", + comp_err(dev, "error %x: failed to get lib init status", ret); return ret; } API_CALL(cd, XA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &codec->mpd.consumed, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init_process() error %x: could not get consumed bytes", + comp_err(dev, "error %x: could not get consumed bytes", ret); return ret; } @@ -658,262 +297,255 @@ static int cadence_codec_init_process(struct processing_module *mod) return 0; } -static int cadence_codec_prepare(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks) +int cadence_codec_free(struct processing_module *mod) { - int ret = 0, mem_tabs_size; - struct comp_dev *dev = mod->dev; - struct module_data *codec = &mod->priv; - struct cadence_codec_data *cd = codec->private; + struct cadence_codec_data *cd = module_get_private_data(mod); + + mod_free(mod, cd->setup_cfg.data); + + cadence_codec_free_memory_tables(mod); + mod_free(mod, cd->mem_tabs); + + mod_free(mod, cd->self); + mod_free(mod, cd); + return 0; +} - comp_dbg(dev, "cadence_codec_prepare() start"); +int cadence_codec_set_configuration(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, const uint8_t *fragment, + size_t fragment_size, uint8_t *response, size_t response_size) +{ + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + int ret; - ret = cadence_codec_post_init(mod); - if (ret) + ret = module_set_configuration(mod, config_id, pos, data_offset_size, fragment, + fragment_size, response, response_size); + if (ret < 0) return ret; + /* return if more fragments are expected or if the module is not prepared */ + if ((pos != MODULE_CFG_FRAGMENT_LAST && pos != MODULE_CFG_FRAGMENT_SINGLE) || + md->state < MODULE_IDLE) + return 0; + + /* whole configuration received, apply it now */ ret = cadence_codec_apply_config(mod); if (ret) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to apply config", - ret); + comp_err(dev, "runtime config apply failed with error %x: ", ret); return ret; } - /* Allocate memory for the codec */ - API_CALL(cd, XA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_tabs_size, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to get memtabs size", - ret); - return ret; - } - - cd->mem_tabs = mod_alloc(mod, mem_tabs_size); - if (!cd->mem_tabs) { - comp_err(dev, "cadence_codec_prepare() error: failed to allocate space for memtabs"); - return -ENOMEM; - } - - comp_dbg(dev, "allocated %d bytes for memtabs", mem_tabs_size); - - API_CALL(cd, XA_API_CMD_SET_MEMTABS_PTR, 0, cd->mem_tabs, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to set memtabs", - ret); - goto free; - } + comp_dbg(dev, "config applied"); - ret = init_memory_tables(mod); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to init memory tables", - ret); - goto free; - } - /* Check init done status. Note, it may happen that init_done flag will return - * false value, this is normal since some codec variants needs input in order to - * fully finish initialization. That's why at codec_adapter_copy() we call - * codec_init_process() base on result obtained below. - */ -#ifdef CONFIG_CADENCE_CODEC_WRAPPER - /* TODO: remove the "#ifdef CONFIG_CADENCE_CODEC_WRAPPER" once cadence fixes the bug - * in the init/prepare sequence. Basically below API_CALL shall return 1 for - * PCM streams and 0 for compress ones. As it turns out currently it returns 1 - * in both cases so in turn compress stream won't finish its prepare during first copy - * in codec_adapter_copy(). - */ - API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, - &codec->mpd.init_done, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_init_process() error %x: failed to get lib init status", - ret); - return ret; - } -#endif - comp_dbg(dev, "cadence_codec_prepare() done"); return 0; -free: - mod_free(mod, cd->mem_tabs); - return ret; } -static int -cadence_codec_process(struct processing_module *mod, - struct input_stream_buffer *input_buffers, int num_input_buffers, - struct output_stream_buffer *output_buffers, int num_output_buffers) +int cadence_codec_apply_params(struct processing_module *mod, int size, void *data) { - struct comp_buffer *local_buff; - struct comp_dev *dev = mod->dev; struct module_data *codec = &mod->priv; + struct comp_dev *dev = mod->dev; struct cadence_codec_data *cd = codec->private; - int free_bytes, output_bytes = cadence_codec_get_samples(mod) * - mod->stream_params->sample_container_bytes * - mod->stream_params->channels; - uint32_t remaining = input_buffers[0].size; + struct module_param *param; + uint16_t param_id; + uint16_t codec_id; int ret; - if (!cadence_codec_deep_buff_allowed(mod)) { - mod->deep_buff_bytes = 0; - } + /* Read parameters stored in `data` - it may keep plenty of + * parameters. The `size` variable is equal to param->size * count, + * where count is number of parameters stored in `data`. + */ + while (size > 0) { + param = data; + comp_dbg(dev, "cadence_codec_apply_config() applying param %d value %d", + param->id, param->data[0]); - /* Proceed only if we have enough data to fill the module buffer completely */ - if (input_buffers[0].size < codec->mpd.in_buff_size) { - comp_dbg(dev, "not enough data to process"); - return -ENODATA; - } + param_id = param->id & 0xFF; + codec_id = param->id >> 16; - if (!codec->mpd.init_done) { - memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size, input_buffers[0].data, - codec->mpd.in_buff_size); - codec->mpd.avail = codec->mpd.in_buff_size; + /* if the parameter is not for current codec skip it! */ + if (codec_id && codec_id != cd->api_id) { + /* Obtain next parameter */ + data = (char *)data + param->size; + size -= param->size; + continue; + } - ret = cadence_codec_init_process(mod); - if (ret) - return ret; + /* Set read parameter */ + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, param_id, + param->data, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply parameter: %d value: %d error: %#x", + param->id, *(int32_t *)param->data, ret); - remaining -= codec->mpd.consumed; - input_buffers[0].consumed = codec->mpd.consumed; + return ret; + } + comp_warn(dev, "applied parameter %d value %d with return code: %#x", + param->id, *(int32_t *)param->data, ret); + } + /* Obtain next parameter, it starts right after the preceding one */ + data = (char *)data + param->size; + size -= param->size; } - /* do not proceed with processing if not enough free space left in the local buffer */ - local_buff = list_first_item(&mod->raw_data_buffers_list, struct comp_buffer, buffers_list); - free_bytes = audio_stream_get_free(&local_buff->stream); - if (free_bytes < output_bytes) - return -ENOSPC; - - /* Proceed only if we have enough data to fill the module buffer completely */ - if (remaining < codec->mpd.in_buff_size) - return -ENODATA; - - memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size, - (uint8_t *)input_buffers[0].data + input_buffers[0].consumed, - codec->mpd.in_buff_size); - codec->mpd.avail = codec->mpd.in_buff_size; + return 0; +} - comp_dbg(dev, "cadence_codec_process() start"); +int cadence_init_codec_object(struct processing_module *mod) +{ + int ret; + struct comp_dev *dev = mod->dev; + struct cadence_codec_data *cd = module_get_private_data(mod); + uint32_t obj_size; - API_CALL(cd, XA_API_CMD_SET_INPUT_BYTES, 0, &codec->mpd.avail, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_process() error %x: failed to set size of input data", - ret); + ret = cadence_codec_resolve_api(mod); + if (ret < 0) return ret; - } - API_CALL(cd, XA_API_CMD_EXECUTE, XA_CMD_TYPE_DO_EXECUTE, NULL, ret); + /* Obtain codec name */ + API_CALL(cd, XA_API_CMD_GET_LIB_ID_STRINGS, + XA_CMD_TYPE_LIB_NAME, cd->name, ret); if (ret != LIB_NO_ERROR) { - if (LIB_IS_FATAL_ERROR(ret)) { - comp_err(dev, "cadence_codec_process() error %x: processing failed", - ret); - return ret; - } - comp_warn(dev, "cadence_codec_process() nonfatal error %x", ret); + comp_err(dev, "failed to get lib name error: %x: ", ret); + return ret; } - - API_CALL(cd, XA_API_CMD_GET_OUTPUT_BYTES, 0, &codec->mpd.produced, ret); + /* Get codec object size */ + API_CALL(cd, XA_API_CMD_GET_API_SIZE, 0, &obj_size, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_process() error %x: could not get produced bytes", - ret); + comp_err(dev, "failed to get lib object size error %x:", ret); return ret; } + /* Allocate space for codec object */ + cd->self = mod_balloc(mod, obj_size); + if (!cd->self) { + comp_err(dev, "failed to allocate space for lib object"); + return -ENOMEM; + } - API_CALL(cd, XA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &codec->mpd.consumed, ret); + comp_dbg(dev, "allocated %d bytes for lib object", obj_size); + + /* Set all params to their default values */ + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, + NULL, ret); if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_process() error %x: could not get consumed bytes", - ret); + mod_free(mod, cd->self); return ret; } - /* update consumed with the number of samples consumed during init */ - input_buffers[0].consumed += codec->mpd.consumed; - codec->mpd.consumed = input_buffers[0].consumed; - - /* copy the produced samples into the output buffer */ - memcpy_s(output_buffers[0].data, codec->mpd.produced, codec->mpd.out_buff, - codec->mpd.produced); - output_buffers[0].size = codec->mpd.produced; - - comp_dbg(dev, "cadence_codec_process() done"); - return 0; } -static int cadence_codec_reset(struct processing_module *mod) +int cadence_codec_resolve_api_with_id(struct processing_module *mod, uint32_t codec_id, + uint32_t direction) { - struct module_data *codec = &mod->priv; - struct cadence_codec_data *cd = codec->private; - int ret; - - /* - * Current CADENCE API doesn't support reset of codec's runtime parameters. - * So, free all memory associated with runtime params. These will be reallocated during - * prepare. - */ - mod_free_all(mod); - - /* reset to default params */ - API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL, ret); - if (ret != LIB_NO_ERROR) - return ret; - - codec->mpd.init_done = 0; + struct cadence_codec_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + uint32_t api_id; + uint32_t n_apis = cadence_api_table_size(); + xa_codec_func_t *api = NULL; + int i; - rfree(cd->self); - cd->self = NULL; + api_id = cadence_codec_get_api_id(codec_id, direction); + if (api_id < 0) + return api_id; - return ret; -} + /* Find and assign API function */ + for (i = 0; i < n_apis; i++) { + if (cadence_api_table[i].id == api_id) { + api = cadence_api_table[i].api; + break; + } + } -static int cadence_codec_free(struct processing_module *mod) -{ - struct cadence_codec_data *cd = module_get_private_data(mod); + /* Verify API assignment */ + if (!api) { + comp_err(dev, "could not find API function for id %x", + api_id); + return -EINVAL; + } + cd->api = api; + cd->api_id = api_id; - rfree(cd->setup_cfg.data); - mod_free_all(mod); - rfree(cd->self); - rfree(cd); return 0; } -static int -cadence_codec_set_configuration(struct processing_module *mod, uint32_t config_id, - enum module_cfg_fragment_position pos, uint32_t data_offset_size, - const uint8_t *fragment, size_t fragment_size, uint8_t *response, - size_t response_size) +int cadence_codec_process_data(struct processing_module *mod) { - struct module_data *md = &mod->priv; + struct cadence_codec_data *cd = module_get_private_data(mod); + struct module_data *codec = &mod->priv; struct comp_dev *dev = mod->dev; + uint32_t done = 0; int ret; - ret = module_set_configuration(mod, config_id, pos, data_offset_size, fragment, - fragment_size, response, response_size); - if (ret < 0) - return ret; + if (codec->mpd.eos_reached) { + codec->mpd.produced = 0; + codec->mpd.consumed = 0; - /* return if more fragments are expected or if the module is not prepared */ - if ((pos != MODULE_CFG_FRAGMENT_LAST && pos != MODULE_CFG_FRAGMENT_SINGLE) || - md->state < MODULE_IDLE) return 0; + } - /* whole configuration received, apply it now */ - ret = cadence_codec_apply_config(mod); - if (ret) { - comp_err(dev, "error %x: runtime config apply failed", + if (dev->pipeline->expect_eos) { + /* Signal that the stream is expected to end anytime soon */ + API_CALL(cd, XA_API_CMD_INPUT_OVER, 0, NULL, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "input_over failed with error: %x", ret); + return ret; + } + comp_warn(dev, "input_over failed with nonfatal error: %x", ret); + } + } + + API_CALL(cd, XA_API_CMD_SET_INPUT_BYTES, 0, &codec->mpd.avail, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "failed to set size of input data with error: %x:", ret); + return ret; + } + + API_CALL(cd, XA_API_CMD_EXECUTE, XA_CMD_TYPE_DO_EXECUTE, NULL, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "processing failed with error: %x", ret); + return ret; + } + comp_warn(dev, "processing failed with nonfatal error: %x", ret); + } + + API_CALL(cd, XA_API_CMD_EXECUTE, XA_CMD_TYPE_DONE_QUERY, &done, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "done query failed with error: %x", ret); + return ret; + } + comp_warn(dev, "done query failed with nonfatal error: %x", ret); + } + + API_CALL(cd, XA_API_CMD_GET_OUTPUT_BYTES, 0, &codec->mpd.produced, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "could not get produced bytes, error %x:", ret); return ret; } - comp_dbg(dev, "config applied"); + API_CALL(cd, XA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &codec->mpd.consumed, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "could not get consumed bytes, error: %x", ret); + return ret; + } - return 0; -} + if (dev->pipeline->expect_eos) { + /* + * AAC decoder cannot signal DONE, check if it stopped + * producing data when EOS is expected + */ + if (cd->api_id == CADENCE_CODEC_AAC_DEC_ID && !codec->mpd.produced) + done = true; -static const struct module_interface cadence_codec_interface = { - .init = cadence_codec_init, - .prepare = cadence_codec_prepare, - .process_raw_data = cadence_codec_process, - .set_configuration = cadence_codec_set_configuration, - .reset = cadence_codec_reset, - .free = cadence_codec_free -}; + if (done) + codec->mpd.eos_reached = true; + } -DECLARE_MODULE_ADAPTER(cadence_codec_interface, cadence_codec_uuid, cadence_codec_tr); -SOF_MODULE_INIT(cadence_codec, sys_comp_module_cadence_codec_interface_init); + return 0; +} diff --git a/src/audio/module_adapter/module/cadence_ipc3.c b/src/audio/module_adapter/module/cadence_ipc3.c new file mode 100644 index 000000000000..77b5b02762bb --- /dev/null +++ b/src/audio/module_adapter/module/cadence_ipc3.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Marcin Rajwa + +/* + * \file cadence.c + * \brief Cadence Codec API + * \author Marcin Rajwa + * + */ + +#include +#include +#include +#include + +SOF_DEFINE_REG_UUID(cadence_codec); +LOG_MODULE_DECLARE(cadence_codec, CONFIG_SOF_LOG_LEVEL); +DECLARE_TR_CTX(cadence_codec_tr, SOF_UUID(cadence_codec_uuid), LOG_LEVEL_INFO); + +int cadence_codec_resolve_api(struct processing_module *mod) +{ + int ret; + struct snd_codec codec_params; + uint32_t codec_id = DEFAULT_CODEC_ID; + + if (mod->stream_params->ext_data_length) { + ret = memcpy_s(&codec_params, mod->stream_params->ext_data_length, + (uint8_t *)mod->stream_params + sizeof(*mod->stream_params), + mod->stream_params->ext_data_length); + if (ret < 0) + return ret; + + codec_id = codec_params.id; + } + + /* IPC3 only supports playback */ + return cadence_codec_resolve_api_with_id(mod, codec_id, mod->stream_params->direction); +} + +static int cadence_codec_init(struct processing_module *mod) +{ + struct module_data *codec = &mod->priv; + struct cadence_codec_data *cd; + struct comp_dev *dev = mod->dev; + struct module_config *setup_cfg; + int ret; + + comp_dbg(dev, "cadence_codec_init() start"); + + cd = mod_zalloc(mod, sizeof(struct cadence_codec_data)); + if (!cd) { + comp_err(dev, "failed to allocate memory for cadence codec data"); + return -ENOMEM; + } + + codec->private = cd; + codec->mpd.init_done = 0; + + /* copy the setup config only for the first init */ + if (codec->state == MODULE_DISABLED && codec->cfg.avail) { + setup_cfg = &cd->setup_cfg; + + /* allocate memory for set up config */ + setup_cfg->data = mod_alloc(mod, codec->cfg.size); + if (!setup_cfg->data) { + comp_err(dev, "failed to alloc setup config"); + ret = -ENOMEM; + goto free; + } + + /* copy the setup config */ + setup_cfg->size = codec->cfg.size; + ret = memcpy_s(setup_cfg->data, setup_cfg->size, + codec->cfg.init_data, setup_cfg->size); + if (ret) { + comp_err(dev, "failed to copy setup config %d", ret); + goto free_cfg; + } + setup_cfg->avail = true; + } + + comp_dbg(dev, "cadence_codec_init() done"); + + return 0; + +free_cfg: + mod_free(mod, setup_cfg->data); +free: + mod_free(mod, cd); + return ret; +} + +int cadence_codec_apply_config(struct processing_module *mod) +{ + int size; + struct module_config *cfg; + void *data; + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + struct cadence_codec_data *cd = codec->private; + + comp_dbg(dev, "cadence_codec_apply_config() start"); + + cfg = &codec->cfg; + + /* use setup config if no runtime config available. This will be true during reset */ + if (!cfg->avail) + cfg = &cd->setup_cfg; + + data = cfg->data; + size = cfg->size; + + if (!cfg->avail || !size) { + comp_err(dev, "cadence_codec_apply_config() error: no config available"); + return -EIO; + } + + return cadence_codec_apply_params(mod, size, data); +} + +static int cadence_codec_deep_buff_allowed(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + + switch (cd->api_id) { + case CADENCE_CODEC_MP3_ENC_ID: + return 0; + default: + return 1; + } +} + +static int cadence_codec_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + int ret = 0, mem_tabs_size; + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + struct cadence_codec_data *cd = codec->private; + + comp_dbg(dev, "cadence_codec_prepare() start"); + + ret = cadence_init_codec_object(mod); + if (ret) + return ret; + + ret = cadence_codec_apply_config(mod); + if (ret) { + comp_err(dev, "cadence_codec_prepare() error %x: failed to apply config", + ret); + return ret; + } + + /* Allocate memory for the codec */ + API_CALL(cd, XA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_tabs_size, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_prepare() error %x: failed to get memtabs size", + ret); + return ret; + } + + cd->mem_tabs = mod_alloc(mod, mem_tabs_size); + if (!cd->mem_tabs) { + comp_err(dev, "cadence_codec_prepare() error: failed to allocate space for memtabs"); + return -ENOMEM; + } + + comp_dbg(dev, "allocated %d bytes for memtabs", mem_tabs_size); + + API_CALL(cd, XA_API_CMD_SET_MEMTABS_PTR, 0, cd->mem_tabs, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_prepare() error %x: failed to set memtabs", + ret); + goto free; + } + + ret = cadence_codec_init_memory_tables(mod); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_prepare() error %x: failed to init memory tables", + ret); + goto free; + } + /* Check init done status. Note, it may happen that init_done flag will return + * false value, this is normal since some codec variants needs input in order to + * fully finish initialization. That's why at codec_adapter_copy() we call + * codec_init_process() base on result obtained below. + */ +#ifdef CONFIG_CADENCE_CODEC_WRAPPER + /* TODO: remove the "#ifdef CONFIG_CADENCE_CODEC_WRAPPER" once cadence fixes the bug + * in the init/prepare sequence. Basically below API_CALL shall return 1 for + * PCM streams and 0 for compress ones. As it turns out currently it returns 1 + * in both cases so in turn compress stream won't finish its prepare during first copy + * in codec_adapter_copy(). + */ + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, + &codec->mpd.init_done, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_init_process() error %x: failed to get lib init status", + ret); + return ret; + } +#endif + comp_dbg(dev, "cadence_codec_prepare() done"); + return 0; +free: + mod_free(mod, cd->mem_tabs); + return ret; +} + +static int +cadence_codec_process(struct processing_module *mod, + struct input_stream_buffer *input_buffers, int num_input_buffers, + struct output_stream_buffer *output_buffers, int num_output_buffers) +{ + struct comp_buffer *local_buff; + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + int free_bytes, output_bytes = cadence_codec_get_samples(mod) * + mod->stream_params->sample_container_bytes * + mod->stream_params->channels; + uint32_t remaining = input_buffers[0].size; + int ret; + + if (!cadence_codec_deep_buff_allowed(mod)) + mod->deep_buff_bytes = 0; + + /* Proceed only if we have enough data to fill the module buffer completely */ + if (input_buffers[0].size < codec->mpd.in_buff_size) { + comp_dbg(dev, "not enough data to process"); + return -ENODATA; + } + + if (!codec->mpd.init_done) { + memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size, input_buffers[0].data, + codec->mpd.in_buff_size); + codec->mpd.avail = codec->mpd.in_buff_size; + + ret = cadence_codec_init_process(mod); + if (ret) + return ret; + + remaining -= codec->mpd.consumed; + input_buffers[0].consumed = codec->mpd.consumed; + } + + /* do not proceed with processing if not enough free space left in the local buffer */ + local_buff = list_first_item(&mod->raw_data_buffers_list, struct comp_buffer, buffers_list); + free_bytes = audio_stream_get_free(&local_buff->stream); + if (free_bytes < output_bytes) + return -ENOSPC; + + /* Proceed only if we have enough data to fill the module buffer completely */ + if (remaining < codec->mpd.in_buff_size) + return -ENODATA; + + memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size, + (uint8_t *)input_buffers[0].data + input_buffers[0].consumed, + codec->mpd.in_buff_size); + codec->mpd.avail = codec->mpd.in_buff_size; + + comp_dbg(dev, "cadence_codec_process() start"); + + ret = cadence_codec_process_data(mod); + if (ret) + return ret; + + /* update consumed with the number of samples consumed during init */ + input_buffers[0].consumed += codec->mpd.consumed; + codec->mpd.consumed = input_buffers[0].consumed; + + /* copy the produced samples into the output buffer */ + memcpy_s(output_buffers[0].data, codec->mpd.produced, codec->mpd.out_buff, + codec->mpd.produced); + output_buffers[0].size = codec->mpd.produced; + + comp_dbg(dev, "cadence_codec_process() done"); + + return 0; +} + +static int cadence_codec_reset(struct processing_module *mod) +{ + struct module_data *codec = &mod->priv; + struct cadence_codec_data *cd = codec->private; + int ret; + + cadence_codec_free_memory_tables(mod); + mod_free(mod, cd->mem_tabs); + + /* reset to default params */ + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL, ret); + if (ret != LIB_NO_ERROR) + return ret; + + codec->mpd.init_done = 0; + + mod_free(mod, cd->self); + cd->self = NULL; + + return ret; +} + +static const struct module_interface cadence_codec_interface = { + .init = cadence_codec_init, + .prepare = cadence_codec_prepare, + .process_raw_data = cadence_codec_process, + .set_configuration = cadence_codec_set_configuration, + .reset = cadence_codec_reset, + .free = cadence_codec_free +}; + +DECLARE_MODULE_ADAPTER(cadence_codec_interface, cadence_codec_uuid, cadence_codec_tr); +SOF_MODULE_INIT(cadence_codec, sys_comp_module_cadence_codec_interface_init); diff --git a/src/audio/module_adapter/module/cadence_ipc4.c b/src/audio/module_adapter/module/cadence_ipc4.c new file mode 100644 index 000000000000..845283a208c3 --- /dev/null +++ b/src/audio/module_adapter/module/cadence_ipc4.c @@ -0,0 +1,582 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025-2026 Intel Corporation. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SOF_DEFINE_REG_UUID(cadence_codec); +LOG_MODULE_DECLARE(cadence_codec, CONFIG_SOF_LOG_LEVEL); +DECLARE_TR_CTX(cadence_codec_tr, SOF_UUID(cadence_codec_uuid), LOG_LEVEL_INFO); + +int cadence_codec_resolve_api(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + struct module_config *setup_cfg = &cd->setup_cfg; + struct snd_codec *codec_params; + uint32_t codec_id = DEFAULT_CODEC_ID; + + /* update codec_id if setup_cfg is available */ + if (setup_cfg->avail) { + codec_params = (struct snd_codec *)cd->setup_cfg.data; + codec_id = codec_params->id; + } + + return cadence_codec_resolve_api_with_id(mod, codec_id, cd->direction); +} + +static int cadence_configure_mp3_dec_params(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + int word_size; + int ret; + + /* Cadence module only supports 16bit or 24 bits for word size */ + switch (cd->base_cfg.audio_fmt.depth) { + case IPC4_DEPTH_16BIT: + word_size = 16; + break; + case IPC4_DEPTH_24BIT: + case IPC4_DEPTH_32BIT: + word_size = 24; + break; + default: + comp_err(dev, "Unsupported bit depth: %d", cd->base_cfg.audio_fmt.depth); + return -EINVAL; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_MP3DEC_CONFIG_PARAM_PCM_WDSZ, + (void *)&word_size, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config param word size: error: %#x", ret); + return ret; + } + comp_warn(dev, "applied param word size return code: %#x", ret); + } + + return 0; +} + +static int cadence_configure_mp3_enc_params(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + int word_size = 16; + int ret; + + /* + * Cadence encoder only supports 16-bit word size. Make sure the topology is set up + * correctly + */ + switch (cd->base_cfg.audio_fmt.depth) { + case IPC4_DEPTH_24BIT: + case IPC4_DEPTH_32BIT: + comp_err(dev, "Unsupported bit depth: %d for MP3 encoder", + cd->base_cfg.audio_fmt.depth); + return -EINVAL; + default: + break; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_MP3ENC_CONFIG_PARAM_PCM_WDSZ, + (void *)&word_size, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config param word size: error: %#x", ret); + return ret; + } + comp_warn(dev, "applied param word size return code: %#x", ret); + } + + int num_channels = cd->base_cfg.audio_fmt.channels_count; + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_MP3ENC_CONFIG_PARAM_NUM_CHANNELS, + (void *)&num_channels, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config num_channels: error: %#x", ret); + return ret; + } + } + + int sampling_freq = cd->base_cfg.audio_fmt.sampling_frequency; + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_MP3ENC_CONFIG_PARAM_SAMP_FREQ, + (void *)&sampling_freq, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config sampling_frequency: error: %#x", ret); + return ret; + } + } + + int bitrate = CADENCE_MP3_ENCODER_DEFAULT_BITRATE; + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_MP3ENC_CONFIG_PARAM_BITRATE, + (void *)&bitrate, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config bitrate: error: %#x", ret); + return ret; + } + } + + return 0; +} + +static int cadence_configure_aac_dec_params(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + struct module_config *setup_cfg = &cd->setup_cfg; + struct comp_dev *dev = mod->dev; + struct snd_codec *codec_params; + int bitstream_format = XA_AACDEC_EBITSTREAM_TYPE_AAC_ADTS; + int word_size; + int ret; + + /* check bitstream format. Only MPEG-4 ADTS supported for now */ + if (setup_cfg->avail) { + codec_params = (struct snd_codec *)cd->setup_cfg.data; + if (codec_params->format != SND_AUDIOSTREAMFORMAT_MP4ADTS) { + comp_err(dev, "Unsupported AAC format: %d", codec_params->format); + return -EINVAL; + } + } else { + comp_err(dev, "No setup config available for AAC decoder"); + return -EINVAL; + } + + /* AAC decoder module only supports 16bit or 24 bits for word size */ + switch (cd->base_cfg.audio_fmt.depth) { + case IPC4_DEPTH_16BIT: + word_size = 16; + break; + case IPC4_DEPTH_24BIT: + case IPC4_DEPTH_32BIT: + word_size = 24; + break; + default: + comp_err(dev, "Unsupported bit depth: %d", cd->base_cfg.audio_fmt.depth); + return -EINVAL; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_AACDEC_CONFIG_PARAM_PCM_WDSZ, + (void *)&word_size, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config param word size: error: %#x", ret); + return ret; + } + comp_warn(dev, "applied param word size return code: %#x", ret); + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, XA_AACDEC_CONFIG_PARAM_EXTERNALBSFORMAT, + (void *)&bitstream_format, ret); + if (ret != LIB_NO_ERROR) { + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "failed to apply config param bitstream format: error: %#x", + ret); + return ret; + } + comp_warn(dev, "applied param bitstream format return code: %#x", ret); + } + + return 0; +} + +static int cadence_configure_codec_params(struct processing_module *mod) +{ + struct cadence_codec_data *cd = module_get_private_data(mod); + + switch (cd->api_id) { + case CADENCE_CODEC_MP3_DEC_ID: + return cadence_configure_mp3_dec_params(mod); + case CADENCE_CODEC_MP3_ENC_ID: + return cadence_configure_mp3_enc_params(mod); + case CADENCE_CODEC_AAC_DEC_ID: + return cadence_configure_aac_dec_params(mod); + case CADENCE_CODEC_VORBIS_DEC_ID: + /* No configuration needed for Vorbis */ + return 0; + default: + break; + } + + comp_err(mod->dev, "Unsupported codec API ID: %u", cd->api_id); + return -EINVAL; +} + +static int cadence_codec_init(struct processing_module *mod) +{ + struct module_data *codec = &mod->priv; + struct module_config *cfg = &codec->cfg; + struct module_ext_init_data *ext_data = cfg->ext_data; + struct module_config *setup_cfg = NULL; + struct cadence_codec_data *cd; + struct comp_dev *dev = mod->dev; + int mem_tabs_size; + int ret; + + comp_dbg(dev, "cadence_codec_init() start"); + + cd = mod_zalloc(mod, sizeof(struct cadence_codec_data)); + if (!cd) { + comp_err(dev, "failed to allocate memory for cadence codec data"); + return -ENOMEM; + } + + codec->private = cd; + memcpy_s(&cd->base_cfg, sizeof(cd->base_cfg), &cfg->base_cfg, sizeof(cd->base_cfg)); + + codec->mpd.init_done = 0; + + /* copy the setup config only for the first init */ + if (codec->state == MODULE_DISABLED && ext_data->module_data_size > 0) { + int size = ext_data->module_data_size; + uint8_t *init_bytes; + + setup_cfg = &cd->setup_cfg; + + /* allocate memory for set up config (codec params) */ + setup_cfg->data = mod_alloc(mod, size); + if (!setup_cfg->data) { + comp_err(dev, "failed to alloc setup config"); + ret = -ENOMEM; + goto free_cd; + } + + setup_cfg->size = size; + ret = memcpy_s(setup_cfg->data, size, ext_data->module_data, size); + if (ret) { + comp_err(dev, "failed to copy setup config %d", ret); + goto free_cfg; + } + setup_cfg->avail = true; + codec->cfg.avail = false; + + /* direction follows the codec params in init data */ + init_bytes = (uint8_t *)ext_data->module_data; + cd->direction = *(uint32_t *)(init_bytes + sizeof(struct snd_codec)); + + comp_info(dev, "codec direction set to %u", cd->direction); + } + + ret = cadence_init_codec_object(mod); + if (ret) + goto free_cfg; + + ret = cadence_configure_codec_params(mod); + if (ret) + goto free_cfg; + + /* Allocate memory for the codec */ + API_CALL(cd, XA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_tabs_size, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "error %x: failed to get memtabs size", ret); + goto free_cfg; + } + + cd->mem_tabs = mod_alloc(mod, mem_tabs_size); + if (!cd->mem_tabs) { + comp_err(dev, "failed to allocate space for memtabs"); + goto free_cfg; + } + + comp_dbg(dev, "allocated %d bytes for memtabs", mem_tabs_size); + + API_CALL(cd, XA_API_CMD_SET_MEMTABS_PTR, 0, cd->mem_tabs, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "error %x: failed to set memtabs", ret); + goto free; + } + + ret = cadence_codec_init_memory_tables(mod); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "error %x: failed to init memory tables", ret); + goto free; + } + + comp_dbg(dev, "cadence_codec_init() done"); + + return 0; +free: + mod_free(mod, cd->mem_tabs); +free_cfg: + if (setup_cfg) + mod_free(mod, setup_cfg->data); +free_cd: + mod_free(mod, cd); + + return ret; +} + +int cadence_codec_apply_config(struct processing_module *mod) +{ + int size; + struct module_config *cfg; + void *data; + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + + cfg = &codec->cfg; + + /* this will be true during prepare if there's no config available after init */ + if (!cfg->avail) + return 0; + + data = cfg->data; + size = cfg->size; + + if (!size) { + comp_err(dev, "error: no data available in config to apply"); + return -EIO; + } + + return cadence_codec_apply_params(mod, size, data); +} + +static int cadence_codec_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + int ret = 0; + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + + comp_dbg(dev, "cadence_codec_prepare() start"); + + ret = cadence_codec_apply_config(mod); + if (ret) { + comp_err(dev, "failed to apply config error %x:", ret); + return ret; + } + + /* Check init done status. Note, it may happen that init_done flag will return + * false value, this is normal since some codec variants needs input in order to + * fully finish initialization. That's why at codec_adapter_copy() we call + * codec_init_process() base on result obtained below. + */ +#ifdef CONFIG_CADENCE_CODEC_WRAPPER + /* TODO: remove the "#ifdef CONFIG_CADENCE_CODEC_WRAPPER" once cadence fixes the bug + * in the init/prepare sequence. Basically below API_CALL shall return 1 for + * PCM streams and 0 for compress ones. As it turns out currently it returns 1 + * in both cases so in turn compress stream won't finish its prepare during first copy + * in codec_adapter_copy(). + */ + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, + &codec->mpd.init_done, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "failed to get lib init status error %x:", ret); + return ret; + } +#endif + + /* set the period based on the minimum required input data size */ + dev->period = 1000000ULL * codec->mpd.in_buff_size / + (source_get_frame_bytes(sources[0]) * source_get_rate(sources[0])); + comp_dbg(dev, "period set to %u usec", dev->period); + + /* align down period to LL cycle time */ + dev->period /= LL_TIMER_PERIOD_US; + dev->period *= LL_TIMER_PERIOD_US; + + comp_dbg(dev, "cadence_codec_prepare() done"); + return 0; +} + +static void cadence_copy_data_from_buffer(void *dest, const void *buffer_ptr, size_t bytes_to_copy, + size_t buffer_size, uint8_t const *buffer_start) +{ + size_t bytes_to_end = (size_t)((uint8_t *)buffer_start + + buffer_size - (uint8_t *)buffer_ptr); + + if (bytes_to_end >= bytes_to_copy) { + /* No wrap, copy directly */ + memcpy_s(dest, bytes_to_copy, buffer_ptr, bytes_to_copy); + return; + } + + /* Wrap occurs, copy in two parts */ + memcpy_s(dest, bytes_to_end, buffer_ptr, bytes_to_end); + memcpy_s((uint8_t *)dest + bytes_to_end, bytes_to_copy - bytes_to_end, + buffer_start, bytes_to_copy - bytes_to_end); +} + +static int cadence_codec_process(struct processing_module *mod, struct sof_source **sources, + int num_of_sources, struct sof_sink **sinks, int num_of_sinks) +{ + struct comp_dev *dev = mod->dev; + struct module_data *codec = &mod->priv; + size_t in_size = source_get_data_available(sources[0]); + size_t out_space = sink_get_free_size(sinks[0]); + uint8_t const *source_buffer_start; + int consumed_during_init = 0; + uint32_t remaining = in_size; + const void *src_ptr; + size_t src_bytes; + int ret; + + if (!codec->mpd.init_done) { + /* Acquire data from the source buffer */ + ret = source_get_data(sources[0], codec->mpd.in_buff_size, &src_ptr, + (const void **)&source_buffer_start, &src_bytes); + if (ret) { + comp_err(dev, "cannot get data from source buffer"); + return ret; + } + + cadence_copy_data_from_buffer(codec->mpd.in_buff, src_ptr, codec->mpd.in_buff_size, + src_bytes, source_buffer_start); + + codec->mpd.avail = codec->mpd.in_buff_size; + ret = cadence_codec_init_process(mod); + if (ret) + return ret; + + remaining -= codec->mpd.consumed; + source_release_data(sources[0], codec->mpd.consumed); + consumed_during_init = codec->mpd.consumed; + } + + codec->mpd.consumed = 0; + + /* Proceed only if we have enough data to fill the module buffer completely */ + if (remaining < codec->mpd.in_buff_size) + return -ENODATA; + + /* Acquire data from the source buffer */ + ret = source_get_data(sources[0], codec->mpd.in_buff_size, &src_ptr, + (const void **)&source_buffer_start, &src_bytes); + + cadence_copy_data_from_buffer(codec->mpd.in_buff, src_ptr, codec->mpd.in_buff_size, + src_bytes, source_buffer_start); + codec->mpd.avail = codec->mpd.in_buff_size; + + comp_dbg(dev, "cadence_codec_process() start"); + + ret = cadence_codec_process_data(mod); + if (ret) { + source_release_data(sources[0], 0); + return ret; + } + + if (codec->mpd.eos_reached && !codec->mpd.eos_notification_sent) { + struct ipc_msg msg_proto; + struct comp_ipc_config *ipc_config = &dev->ipc_config; + union ipc4_notification_header *primary = + (union ipc4_notification_header *)&msg_proto.header; + struct sof_ipc4_notify_module_data *msg_module_data; + struct ipc_msg *msg; + + memset_s(&msg_proto, sizeof(msg_proto), 0, sizeof(msg_proto)); + primary->r.notif_type = SOF_IPC4_MODULE_NOTIFICATION; + primary->r.type = SOF_IPC4_GLB_NOTIFICATION; + primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension, + sizeof(*msg_module_data)); + if (msg) { + msg_module_data = (struct sof_ipc4_notify_module_data *)msg->tx_data; + msg_module_data->instance_id = IPC4_INST_ID(ipc_config->id); + msg_module_data->module_id = IPC4_MOD_ID(ipc_config->id); + msg_module_data->event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL; + msg_module_data->event_data_size = 0; + + ipc_msg_send(msg, NULL, false); + codec->mpd.eos_notification_sent = true; + } + + /* Set EOS for the sink as we are not going to produce more data */ + audio_buffer_set_eos(sof_audio_buffer_from_sink(sinks[0])); + } + + /* do not proceed if not enough free space left */ + if (out_space < codec->mpd.produced) { + source_release_data(sources[0], 0); + return -ENOSPC; + } + + void *sink_ptr; + size_t sink_bytes; + uint8_t const *sink_buffer_start; + + ret = sink_get_buffer(sinks[0], codec->mpd.produced, &sink_ptr, + (void **)&sink_buffer_start, &sink_bytes); + if (ret) { + comp_err(dev, "cannot get sink buffer"); + return ret; + } + + /* Copy the produced samples into the output buffer */ + size_t bytes_to_end = (size_t)((uint8_t *)sink_buffer_start + + sink_bytes - (uint8_t *)sink_ptr); + + if (bytes_to_end >= codec->mpd.produced) { + /* No wrap, copy directly */ + memcpy_s(sink_ptr, codec->mpd.produced, codec->mpd.out_buff, + codec->mpd.produced); + } else { + /* Wrap occurs, copy in two parts */ + memcpy_s(sink_ptr, bytes_to_end, codec->mpd.out_buff, bytes_to_end); + memcpy_s((uint8_t *)sink_buffer_start, codec->mpd.produced - bytes_to_end, + (uint8_t *)codec->mpd.out_buff + bytes_to_end, + codec->mpd.produced - bytes_to_end); + } + + source_release_data(sources[0], codec->mpd.consumed); + sink_commit_buffer(sinks[0], codec->mpd.produced); + + /* reset produced and consumed */ + codec->mpd.consumed = 0; + codec->mpd.produced = 0; + + comp_dbg(dev, "cadence_codec_process() done"); + + return 0; +} + +static int cadence_codec_reset(struct processing_module *mod) +{ + struct module_data *codec = &mod->priv; + + codec->mpd.init_done = 0; + + return 0; +} + +static bool cadence_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + struct module_data *codec = &mod->priv; + + if (source_get_data_available(sources[0]) < codec->mpd.in_buff_size || + sink_get_free_size(sinks[0]) < codec->mpd.out_buff_size) + return false; + + return true; +} + +static const struct module_interface cadence_codec_interface = { + .init = cadence_codec_init, + .prepare = cadence_codec_prepare, + .process = cadence_codec_process, + .set_configuration = cadence_codec_set_configuration, + .reset = cadence_codec_reset, + .free = cadence_codec_free, + .is_ready_to_process = cadence_is_ready_to_process, +}; + +DECLARE_MODULE_ADAPTER(cadence_codec_interface, cadence_codec_uuid, cadence_codec_tr); +SOF_MODULE_INIT(cadence_codec, sys_comp_module_cadence_codec_interface_init); diff --git a/src/audio/module_adapter/module/dolby/dax.c b/src/audio/module_adapter/module/dolby/dax.c new file mode 100644 index 000000000000..c027f7985932 --- /dev/null +++ b/src/audio/module_adapter/module/dolby/dax.c @@ -0,0 +1,893 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE +// +// Copyright(c) 2025 Dolby Laboratories. All rights reserved. +// +// Author: Jun Lai +// + +#include + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(dolby_dax_audio_processing, CONFIG_SOF_LOG_LEVEL); +SOF_DEFINE_REG_UUID(dolby_dax_audio_processing); + +#define MAX_PARAMS_STR_BUFFER_SIZE 1536 +#define DAX_ENABLE_MASK 0x1 +#define DAX_PROFILE_MASK 0x2 +#define DAX_DEVICE_MASK 0x4 +#define DAX_CP_MASK 0x8 +#define DAX_VOLUME_MASK 0x10 +#define DAX_CTC_MASK 0x20 + +#define DAX_SWITCH_ENABLE_CONTROL_ID 0 +#define DAX_SWITCH_CP_CONTROL_ID 1 +#define DAX_SWITCH_CTC_CONTROL_ID 2 +#define DAX_ENUM_PROFILE_CONTROL_ID 0 +#define DAX_ENUM_DEVICE_CONTROL_ID 1 + +static int itostr(int num, char *str) +{ + int index = 0, digit_count = 0; + int temp; + + if (num < 0) { + str[0] = '-'; + index = 1; + num = -num; + } + + if (num == 0) { + str[index] = '0'; + str[index + 1] = '\0'; + return index + 1; + } + + temp = num; + while (temp > 0) { + temp /= 10; + digit_count++; + } + + temp = index + digit_count - 1; + while (num > 0) { + str[temp] = (num % 10) + '0'; + num /= 10; + temp--; + } + + str[index + digit_count] = '\0'; + return index + digit_count; +} + +static const char *get_params_str(const void *val, uint32_t val_sz) +{ + static char params_str[MAX_PARAMS_STR_BUFFER_SIZE + 16]; + const int32_t *param_val = (const int32_t *)val; + const uint32_t param_sz = val_sz >> 2; + uint32_t offset = 0; + + for (uint32_t i = 0; i < param_sz && offset < MAX_PARAMS_STR_BUFFER_SIZE; i++) { + offset += itostr(param_val[i], params_str + offset); + params_str[offset] = ','; + offset++; + params_str[offset] = '\0'; + } + return ¶ms_str[0]; +} + +static int sof_to_dax_frame_fmt(enum sof_ipc_frame sof_frame_fmt) +{ + switch (sof_frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + return DAX_FMT_SHORT_16; + case SOF_IPC_FRAME_S32_LE: + return DAX_FMT_INT; + case SOF_IPC_FRAME_FLOAT: + return DAX_FMT_FLOAT; + default: + return DAX_FMT_UNSUPPORTED; + } +} + +static int sof_to_dax_sample_rate(uint32_t rate) +{ + switch (rate) { + case 48000: + return rate; + default: + return DAX_RATE_UNSUPPORTED; + } +} + +static int sof_to_dax_channels(uint32_t channels) +{ + switch (channels) { + case 2: + case 6 /* 5.1 */: + case 8 /* 7.1 */: + return channels; + default: + return DAX_CHANNLES_UNSUPPORTED; + } +} + +static int sof_to_dax_buffer_layout(enum sof_ipc_buffer_format sof_buf_fmt) +{ + switch (sof_buf_fmt) { + case SOF_IPC_BUFFER_INTERLEAVED: + return DAX_BUFFER_LAYOUT_INTERLEAVED; + case SOF_IPC_BUFFER_NONINTERLEAVED: + return DAX_BUFFER_LAYOUT_NONINTERLEAVED; + default: + return DAX_BUFFER_LAYOUT_UNSUPPORTED; + } +} + +static void dax_buffer_release(struct processing_module *mod, struct dax_buffer *dax_buff) +{ + if (dax_buff->addr) { + mod_free(mod, dax_buff->addr); + dax_buff->addr = NULL; + } + dax_buff->size = 0; + dax_buff->avail = 0; + dax_buff->free = 0; +} + +static int dax_buffer_alloc(struct processing_module *mod, + struct dax_buffer *dax_buff, uint32_t bytes) +{ + dax_buffer_release(mod, dax_buff); + dax_buff->addr = mod_balloc(mod, bytes); + if (!dax_buff->addr) + dax_buff->addr = mod_zalloc(mod, bytes); + if (!dax_buff->addr) + return -ENOMEM; + + dax_buff->size = bytes; + dax_buff->avail = 0; + dax_buff->free = bytes; + return 0; +} + +/* After reading from buffer */ +static void dax_buffer_consume(struct dax_buffer *dax_buff, uint32_t bytes) +{ + uint8_t *buf = (uint8_t *)dax_buff->addr; + uint32_t copy_bytes; + + bytes = MIN(bytes, dax_buff->avail); + copy_bytes = dax_buff->avail - bytes; + for (int i = 0; i < copy_bytes; i++) + buf[i] = buf[bytes + i]; + dax_buff->avail = copy_bytes; + dax_buff->free = dax_buff->size - dax_buff->avail; +} + +/* After writing to buffer */ +static void dax_buffer_produce(struct dax_buffer *dax_buff, uint32_t bytes) +{ + dax_buff->avail += bytes; + dax_buff->avail = MIN(dax_buff->avail, dax_buff->size); + dax_buff->free = dax_buff->size - dax_buff->avail; +} + +static int set_tuning_file(struct processing_module *mod, void *value, uint32_t size) +{ + int ret = 0; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + if (dax_buffer_alloc(mod, &dax_ctx->tuning_file_buffer, size) != 0) { + comp_err(dev, "allocate %u bytes failed for tuning file", size); + ret = -ENOMEM; + } else { + memcpy_s(dax_ctx->tuning_file_buffer.addr, + dax_ctx->tuning_file_buffer.free, + value, + size); + } + + comp_info(dev, "allocated: tuning %u, ret %d", dax_ctx->tuning_file_buffer.size, ret); + return ret; +} + +static int set_enable(struct processing_module *mod, int32_t enable) +{ + int ret = 0; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + if (enable) { + ret = dax_set_enable(1, dax_ctx); + dax_ctx->enable = (ret == 0 ? 1 : 0); + } else { + dax_ctx->enable = 0; + dax_set_enable(0, dax_ctx); + } + + comp_info(mod->dev, "set dax enable %d, ret %d", enable, ret); + return ret; +} + +static int set_volume(struct processing_module *mod, int32_t abs_volume) +{ + int ret; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + dax_ctx->volume = abs_volume; + if (!dax_ctx->enable) + return 0; + + ret = dax_set_volume(abs_volume, dax_ctx); + comp_info(mod->dev, "set volume %d, ret %d", abs_volume, ret); + return ret; +} + +static int set_device(struct processing_module *mod, int32_t out_device) +{ + int ret; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + dax_ctx->out_device = out_device; + ret = dax_set_device(out_device, dax_ctx); + + comp_info(mod->dev, "set device %d, ret %d", out_device, ret); + return ret; +} + +static int set_crosstalk_cancellation_enable(struct processing_module *mod, int32_t enable) +{ + int ret; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + dax_ctx->ctc_enable = enable; + ret = dax_set_ctc_enable(enable, dax_ctx); + + comp_info(mod->dev, "set ctc enable %d, ret %d", enable, ret); + return ret; +} + +static int update_params_from_buffer(struct processing_module *mod, void *params, uint32_t size); + +static int set_profile(struct processing_module *mod, int32_t profile_id) +{ + int ret = -EINVAL; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + uint32_t params_sz = 0; + void *params; + + dax_ctx->profile = profile_id; + if (!dax_ctx->enable) + return 0; + + params = dax_find_params(DAX_PARAM_ID_PROFILE, profile_id, ¶ms_sz, dax_ctx); + if (params) + ret = update_params_from_buffer(mod, params, params_sz); + + comp_info(dev, "switched to profile %d, ret %d", profile_id, ret); + return ret; +} + +static int set_tuning_device(struct processing_module *mod, int32_t tuning_device) +{ + int ret = -EINVAL; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + uint32_t params_sz = 0; + void *params; + + dax_ctx->tuning_device = tuning_device; + if (!dax_ctx->enable) + return 0; + + params = dax_find_params(DAX_PARAM_ID_TUNING_DEVICE, tuning_device, ¶ms_sz, dax_ctx); + if (params) + ret = update_params_from_buffer(mod, params, params_sz); + + comp_info(dev, "switched to tuning device %d, ret %d", tuning_device, ret); + return ret; +} + +static int set_content_processing_enable(struct processing_module *mod, int32_t enable) +{ + int ret = -EINVAL; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + uint32_t params_sz = 0; + void *params; + + dax_ctx->content_processing_enable = enable; + if (!dax_ctx->enable) + return 0; + + params = dax_find_params(DAX_PARAM_ID_CP_ENABLE, enable, ¶ms_sz, dax_ctx); + if (params) + ret = update_params_from_buffer(mod, params, params_sz); + + comp_info(dev, "set content processing enable %d, ret %d", enable, ret); + return ret; +} + +static int dax_set_param_wrapper(struct processing_module *mod, + uint32_t id, void *value, uint32_t size) +{ + int ret = 0; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + int32_t tmp_val; + + switch (id) { + case DAX_PARAM_ID_TUNING_FILE: + set_tuning_file(mod, value, size); + break; + case DAX_PARAM_ID_ENABLE: + tmp_val = *((int32_t *)value); + tmp_val = !!tmp_val; + if (dax_ctx->enable != tmp_val) { + dax_ctx->enable = tmp_val; + dax_ctx->update_flags |= DAX_ENABLE_MASK; + } + break; + case DAX_PARAM_ID_ABSOLUTE_VOLUME: + dax_ctx->volume = *((int32_t *)value); + dax_ctx->update_flags |= DAX_VOLUME_MASK; + break; + case DAX_PARAM_ID_OUT_DEVICE: + tmp_val = *((int32_t *)value); + if (dax_ctx->out_device != tmp_val) { + dax_ctx->out_device = tmp_val; + dax_ctx->update_flags |= DAX_DEVICE_MASK; + } + break; + case DAX_PARAM_ID_PROFILE: + tmp_val = *((int32_t *)value); + if (dax_ctx->profile != tmp_val) { + dax_ctx->profile = tmp_val; + dax_ctx->update_flags |= DAX_PROFILE_MASK; + } + break; + case DAX_PARAM_ID_CP_ENABLE: + tmp_val = *((int32_t *)value); + tmp_val = !!tmp_val; + if (dax_ctx->content_processing_enable != tmp_val) { + dax_ctx->content_processing_enable = tmp_val; + dax_ctx->update_flags |= DAX_CP_MASK; + } + break; + case DAX_PARAM_ID_CTC_ENABLE: + tmp_val = *((int32_t *)value); + tmp_val = !!tmp_val; + if (dax_ctx->ctc_enable != tmp_val) { + dax_ctx->ctc_enable = tmp_val; + dax_ctx->update_flags |= DAX_CTC_MASK; + } + break; + case DAX_PARAM_ID_ENDPOINT: + if (dax_ctx->endpoint == *((int32_t *)value)) { + ret = update_params_from_buffer(mod, (uint8_t *)value + 4, size - 4); + comp_info(dev, "switched to endpoint %d, ret %d", dax_ctx->endpoint, ret); + } + break; + default: + ret = dax_set_param(id, (void *)(value), size, dax_ctx); + comp_info(dev, "dax_set_param: ret %d, id %#x, size %u, value %s", + ret, id, size >> 2, get_params_str(value, size)); + break; + } + + return ret; +} + +static int update_params_from_buffer(struct processing_module *mod, void *data, uint32_t data_size) +{ + struct comp_dev *dev = mod->dev; + struct module_param *param; + void *pos = data; + const uint32_t param_header_size = 8; + uint32_t param_data_size; + + for (uint32_t i = 0; i < data_size;) { + param = (struct module_param *)(pos); + if (param->size < param_header_size || + param->size > data_size - i || + (param->size & 0x03) != 0) { + comp_err(dev, "invalid param %#x, param size %u, pos %u", + param->id, param->size, i); + return -EINVAL; + } + + if (param->size > param_header_size) { + param_data_size = param->size - param_header_size; + dax_set_param_wrapper(mod, param->id, (void *)(param->data), + param_data_size); + } + + pos = (void *)((uint8_t *)(pos) + param->size); + i += param->size; + } + + return 0; +} + +static void check_and_update_settings(struct processing_module *mod) +{ + struct sof_dax *dax_ctx = module_get_private_data(mod); + + if (dax_ctx->update_flags & DAX_ENABLE_MASK) { + set_enable(mod, dax_ctx->enable); + if (dax_ctx->enable) { + dax_ctx->update_flags |= DAX_DEVICE_MASK; + dax_ctx->update_flags |= DAX_VOLUME_MASK; + } + dax_ctx->update_flags &= ~DAX_ENABLE_MASK; + return; + } + if (dax_ctx->update_flags & DAX_DEVICE_MASK) { + set_device(mod, dax_ctx->out_device); + set_tuning_device(mod, dax_ctx->tuning_device); + dax_ctx->update_flags |= DAX_PROFILE_MASK; + dax_ctx->update_flags &= ~DAX_DEVICE_MASK; + return; + } + if (dax_ctx->update_flags & DAX_CTC_MASK) { + set_crosstalk_cancellation_enable(mod, dax_ctx->ctc_enable); + dax_ctx->update_flags |= DAX_PROFILE_MASK; + dax_ctx->update_flags &= ~DAX_CTC_MASK; + return; + } + if (dax_ctx->update_flags & DAX_PROFILE_MASK) { + set_profile(mod, dax_ctx->profile); + if (!dax_ctx->content_processing_enable) + dax_ctx->update_flags |= DAX_CP_MASK; + dax_ctx->update_flags &= ~DAX_PROFILE_MASK; + return; + } + if (dax_ctx->update_flags & DAX_CP_MASK) { + set_content_processing_enable(mod, dax_ctx->content_processing_enable); + dax_ctx->update_flags &= ~DAX_CP_MASK; + return; + } + if (dax_ctx->update_flags & DAX_VOLUME_MASK) { + set_volume(mod, dax_ctx->volume); + dax_ctx->update_flags &= ~DAX_VOLUME_MASK; + } +} + +static int sof_dax_free(struct processing_module *mod) +{ + struct sof_dax *dax_ctx = module_get_private_data(mod); + + if (dax_ctx) { + dax_free(dax_ctx); + dax_buffer_release(mod, &dax_ctx->persist_buffer); + dax_buffer_release(mod, &dax_ctx->scratch_buffer); + dax_buffer_release(mod, &dax_ctx->tuning_file_buffer); + dax_buffer_release(mod, &dax_ctx->input_buffer); + dax_buffer_release(mod, &dax_ctx->output_buffer); + mod_data_blob_handler_free(mod, dax_ctx->blob_handler); + dax_ctx->blob_handler = NULL; + mod_free(mod, dax_ctx); + module_set_private_data(mod, NULL); + } + return 0; +} + +static int sof_dax_init(struct processing_module *mod) +{ + int ret; + struct comp_dev *dev = mod->dev; + struct module_data *md = &mod->priv; + struct sof_dax *dax_ctx; + uint32_t persist_sz; + uint32_t scratch_sz; + + md->private = mod_zalloc(mod, sizeof(struct sof_dax)); + if (!md->private) { + comp_err(dev, "failed to allocate %u bytes for initialization", + sizeof(struct sof_dax)); + return -ENOMEM; + } + dax_ctx = module_get_private_data(mod); + dax_ctx->enable = 0; + dax_ctx->profile = 0; + dax_ctx->out_device = 0; + dax_ctx->ctc_enable = 1; + dax_ctx->content_processing_enable = 1; + dax_ctx->volume = 1 << 23; + dax_ctx->update_flags = 0; + + dax_ctx->blob_handler = mod_data_blob_handler_new(mod); + if (!dax_ctx->blob_handler) { + comp_err(dev, "create blob handler failed"); + ret = -ENOMEM; + goto err; + } + + persist_sz = dax_query_persist_memory(dax_ctx); + if (dax_buffer_alloc(mod, &dax_ctx->persist_buffer, persist_sz) != 0) { + comp_err(dev, "allocate %u bytes failed for persist", persist_sz); + ret = -ENOMEM; + goto err; + } + scratch_sz = dax_query_scratch_memory(dax_ctx); + if (dax_buffer_alloc(mod, &dax_ctx->scratch_buffer, scratch_sz) != 0) { + comp_err(dev, "allocate %u bytes failed for scratch", scratch_sz); + ret = -ENOMEM; + goto err; + } + ret = dax_init(dax_ctx); + if (ret != 0) { + comp_err(dev, "dax instance initialization failed, ret %d", ret); + goto err; + } + + comp_info(dev, "allocated: persist %u, scratch %u. version: %s", + persist_sz, scratch_sz, dax_get_version()); + return 0; + +err: + sof_dax_free(mod); + return ret; +} + +static int check_media_format(struct processing_module *mod) +{ + int ret = 0; + struct comp_dev *dev = mod->dev; + struct comp_buffer *source = comp_dev_get_first_data_producer(dev); + struct comp_buffer *sink = comp_dev_get_first_data_consumer(dev); + const struct audio_stream *src_stream = &source->stream; + const struct audio_stream *sink_stream = &sink->stream; + struct sof_dax *dax_ctx = module_get_private_data(mod); + + if (audio_stream_get_frm_fmt(src_stream) != audio_stream_get_frm_fmt(sink_stream) || + sof_to_dax_frame_fmt(audio_stream_get_frm_fmt(src_stream)) == DAX_FMT_UNSUPPORTED) { + comp_err(dev, "unsupported format, source %d, sink %d", + audio_stream_get_frm_fmt(src_stream), + audio_stream_get_frm_fmt(sink_stream)); + ret = -EINVAL; + } + + if (audio_stream_get_rate(src_stream) != audio_stream_get_rate(sink_stream) || + sof_to_dax_sample_rate(audio_stream_get_rate(src_stream)) == DAX_RATE_UNSUPPORTED) { + comp_err(dev, "unsupported sample rate, source %d, sink %d", + audio_stream_get_rate(src_stream), audio_stream_get_rate(sink_stream)); + ret = -EINVAL; + } + + if (audio_stream_get_channels(sink_stream) != 2 || + sof_to_dax_channels(audio_stream_get_channels(src_stream)) == + DAX_CHANNLES_UNSUPPORTED) { + comp_err(dev, "unsupported number of channels, source %d, sink %d", + audio_stream_get_channels(src_stream), + audio_stream_get_channels(sink_stream)); + ret = -EINVAL; + } + + if (audio_stream_get_buffer_fmt(src_stream) != audio_stream_get_buffer_fmt(sink_stream) || + sof_to_dax_buffer_layout(audio_stream_get_buffer_fmt(src_stream)) == + DAX_BUFFER_LAYOUT_UNSUPPORTED) { + comp_err(dev, "unsupported buffer layout %d", + audio_stream_get_buffer_fmt(src_stream)); + ret = -EINVAL; + } + + if (ret != 0) + return ret; + + dax_ctx->input_media_format.data_format = + sof_to_dax_frame_fmt(audio_stream_get_frm_fmt(src_stream)); + dax_ctx->input_media_format.sampling_rate = + sof_to_dax_sample_rate(audio_stream_get_rate(src_stream)); + dax_ctx->input_media_format.num_channels = + sof_to_dax_channels(audio_stream_get_channels(src_stream)); + dax_ctx->input_media_format.layout = + sof_to_dax_buffer_layout(audio_stream_get_buffer_fmt(src_stream)); + dax_ctx->input_media_format.bytes_per_sample = audio_stream_sample_bytes(src_stream); + + dax_ctx->output_media_format.data_format = + sof_to_dax_frame_fmt(audio_stream_get_frm_fmt(sink_stream)); + dax_ctx->output_media_format.sampling_rate = + sof_to_dax_sample_rate(audio_stream_get_rate(sink_stream)); + dax_ctx->output_media_format.num_channels = + sof_to_dax_channels(audio_stream_get_channels(sink_stream)); + dax_ctx->output_media_format.layout = + sof_to_dax_buffer_layout(audio_stream_get_buffer_fmt(sink_stream)); + dax_ctx->output_media_format.bytes_per_sample = audio_stream_sample_bytes(sink_stream); + + comp_info(dev, "format %d, sample rate %d, channels %d, data format %d", + dax_ctx->input_media_format.data_format, + dax_ctx->input_media_format.sampling_rate, + dax_ctx->input_media_format.num_channels, + dax_ctx->input_media_format.data_format); + return 0; +} + +static int sof_dax_prepare(struct processing_module *mod, struct sof_source **sources, + int num_of_sources, struct sof_sink **sinks, int num_of_sinks) +{ + int ret; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + uint32_t ibs, obs; + + if (num_of_sources != 1 || num_of_sinks != 1) { + comp_err(dev, "unsupported number of buffers, in %d, out %d", + num_of_sources, num_of_sinks); + return -EINVAL; + } + + ret = check_media_format(mod); + if (ret != 0) + return ret; + + dax_ctx->sof_period_bytes = dev->frames * + dax_ctx->output_media_format.num_channels * + dax_ctx->output_media_format.bytes_per_sample; + dax_ctx->period_bytes = dax_query_period_frames(dax_ctx) * + dax_ctx->output_media_format.num_channels * + dax_ctx->output_media_format.bytes_per_sample; + dax_ctx->period_us = 1000000 * dax_ctx->period_bytes / + (dax_ctx->output_media_format.bytes_per_sample * + dax_ctx->output_media_format.num_channels * + dax_ctx->output_media_format.sampling_rate); + + ibs = (dax_query_period_frames(dax_ctx) + dev->frames) * + dax_ctx->input_media_format.num_channels * + dax_ctx->input_media_format.bytes_per_sample; + obs = dax_ctx->period_bytes + dax_ctx->sof_period_bytes; + if (dax_buffer_alloc(mod, &dax_ctx->input_buffer, ibs) != 0) { + comp_err(dev, "allocate %u bytes failed for input", ibs); + ret = -ENOMEM; + goto err; + } + if (dax_buffer_alloc(mod, &dax_ctx->output_buffer, obs) != 0) { + comp_err(dev, "allocate %u bytes failed for output", obs); + ret = -ENOMEM; + goto err; + } + memset(dax_ctx->output_buffer.addr, 0, dax_ctx->output_buffer.size); + dax_buffer_produce(&dax_ctx->output_buffer, dax_ctx->output_buffer.size); + comp_info(dev, "allocated: ibs %u, obs %u", ibs, obs); + + return 0; + +err: + dax_buffer_release(mod, &dax_ctx->input_buffer); + dax_buffer_release(mod, &dax_ctx->output_buffer); + return ret; +} + +static int sof_dax_process(struct processing_module *mod, struct sof_source **sources, + int num_of_sources, struct sof_sink **sinks, int num_of_sinks) +{ + struct sof_dax *dax_ctx = module_get_private_data(mod); + struct sof_source *source = sources[0]; + struct sof_sink *sink = sinks[0]; + uint8_t *buf, *bufstart, *bufend, *dax_buf; + size_t bufsz; + struct dax_buffer *dax_input_buffer = &dax_ctx->input_buffer; + struct dax_buffer *dax_output_buffer = &dax_ctx->output_buffer; + uint32_t consumed_bytes, processed_bytes, produced_bytes; + + /* source stream -> internal input buffer */ + consumed_bytes = MIN(source_get_data_available(source), dax_input_buffer->free); + source_get_data(source, consumed_bytes, (void *)&buf, (void *)&bufstart, &bufsz); + bufend = &bufstart[bufsz]; + dax_buf = (uint8_t *)(dax_input_buffer->addr); + cir_buf_copy(buf, bufstart, bufend, + dax_buf + dax_input_buffer->avail, + dax_buf, + dax_buf + dax_input_buffer->size, + consumed_bytes); + dax_buffer_produce(dax_input_buffer, consumed_bytes); + source_release_data(source, consumed_bytes); + + check_and_update_settings(mod); + + /* internal input buffer -> internal output buffer */ + processed_bytes = dax_process(dax_ctx); + dax_buffer_consume(dax_input_buffer, processed_bytes); + dax_buffer_produce(dax_output_buffer, processed_bytes); + + /* internal output buffer -> sink stream */ + produced_bytes = MIN(dax_output_buffer->avail, sink_get_free_size(sink)); + if (produced_bytes > 0) { + sink_get_buffer(sink, produced_bytes, (void *)&buf, (void *)&bufstart, &bufsz); + bufend = &bufstart[bufsz]; + dax_buf = (uint8_t *)(dax_output_buffer->addr); + cir_buf_copy(dax_buf, dax_buf, dax_buf + dax_output_buffer->size, + buf, bufstart, bufend, produced_bytes); + dax_buffer_consume(dax_output_buffer, produced_bytes); + sink_commit_buffer(sink, produced_bytes); + } + + return 0; +} + +static int sof_dax_set_configuration(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, const uint8_t *fragment, + size_t fragment_size, + uint8_t *response, size_t response_size) +{ + int ret; + struct comp_dev *dev = mod->dev; + struct sof_dax *dax_ctx = module_get_private_data(mod); + int32_t dax_param_id = 0; + int32_t val; + + if (fragment_size == 0) + return 0; + +#if CONFIG_IPC_MAJOR_4 + const struct sof_ipc4_control_msg_payload *ctl = NULL; + + switch (config_id) { + case 0: /* IPC4_VOLUME */ + /* ipc4_peak_volume_config::target_volume */ + val = ((const int32_t *)fragment)[1]; + val = sat_int32(Q_SHIFT_RND((int64_t)val, 31, 23)); + dax_param_id = DAX_PARAM_ID_ABSOLUTE_VOLUME; + break; + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + ctl = (const struct sof_ipc4_control_msg_payload *)fragment; + if (ctl->num_elems != 1) + return -EINVAL; + + val = ctl->chanv[0].value; + switch (ctl->id) { + case DAX_SWITCH_ENABLE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_ENABLE; + break; + case DAX_SWITCH_CP_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_CP_ENABLE; + break; + case DAX_SWITCH_CTC_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_CTC_ENABLE; + break; + default: + comp_err(dev, "unknown switch control %d", ctl->id); + return -EINVAL; + } + break; + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + ctl = (const struct sof_ipc4_control_msg_payload *)fragment; + if (ctl->num_elems != 1) + return -EINVAL; + + val = ctl->chanv[0].value; + switch (ctl->id) { + case DAX_ENUM_PROFILE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_PROFILE; + break; + case DAX_ENUM_DEVICE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_OUT_DEVICE; + break; + default: + comp_err(dev, "unknown enum control %d", ctl->id); + return -EINVAL; + } + break; + default: + break; + } +#else + struct sof_ipc_ctrl_data *ctl = (struct sof_ipc_ctrl_data *)fragment; + + switch (ctl->cmd) { + case SOF_CTRL_CMD_VOLUME: + val = ctl->chanv[0].value; + dax_param_id = DAX_PARAM_ID_ABSOLUTE_VOLUME; + break; + case SOF_CTRL_CMD_SWITCH: + if (ctl->num_elems != 1) + return -EINVAL; + + val = ctl->chanv[0].value; + switch (ctl->index) { + case DAX_SWITCH_ENABLE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_ENABLE; + break; + case DAX_SWITCH_CP_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_CP_ENABLE; + break; + case DAX_SWITCH_CTC_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_CTC_ENABLE; + break; + default: + comp_err(dev, "unknown switch control %d", ctl->index); + return -EINVAL; + } + break; + case SOF_CTRL_CMD_ENUM: + if (ctl->num_elems != 1) + return -EINVAL; + + val = ctl->chanv[0].value; + switch (ctl->index) { + case DAX_ENUM_PROFILE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_PROFILE; + break; + case DAX_ENUM_DEVICE_CONTROL_ID: + dax_param_id = DAX_PARAM_ID_OUT_DEVICE; + break; + default: + comp_err(dev, "unknown enum control %d", ctl->index); + return -EINVAL; + } + break; + default: + break; + } +#endif + + if (dax_param_id == 0) { + ret = comp_data_blob_set(dax_ctx->blob_handler, pos, + data_offset_size, fragment, fragment_size); + if (ret == 0 && (pos == MODULE_CFG_FRAGMENT_LAST || + pos == MODULE_CFG_FRAGMENT_SINGLE)) { + void *data = NULL; + size_t data_size = 0; + + data = comp_get_data_blob(dax_ctx->blob_handler, &data_size, NULL); + if (data && data_size > 0) + update_params_from_buffer(mod, data, data_size); + } + } else { + ret = dax_set_param_wrapper(mod, dax_param_id, &val, sizeof(val)); + } + return ret; +} + +static const struct module_interface dolby_dax_audio_processing_interface = { + .init = sof_dax_init, + .prepare = sof_dax_prepare, + .process = sof_dax_process, + .set_configuration = sof_dax_set_configuration, + .free = sof_dax_free, +}; + +#if CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MODULE +/* modular: llext dynamic link */ + +#include +#include +#include + +static const struct sof_man_module_manifest main_manifest __section(".module") __used = { + .module = { + .name = "DAX", + .uuid = SOF_REG_UUID(dolby_dax_audio_processing), + .entry_point = (uint32_t)(&dolby_dax_audio_processing_interface), + .instance_max_count = 1, + .type = { + .load_type = SOF_MAN_MOD_TYPE_LLEXT, + .domain_dp = 1, + }, + .affinity_mask = 7, + } +}; + +SOF_LLEXT_BUILDINFO; + +#else + +DECLARE_TR_CTX(dolby_dax_audio_processing_tr, SOF_UUID(dolby_dax_audio_processing_uuid), + LOG_LEVEL_INFO); +DECLARE_MODULE_ADAPTER(dolby_dax_audio_processing_interface, dolby_dax_audio_processing_uuid, + dolby_dax_audio_processing_tr); +SOF_MODULE_INIT(dolby_dax_audio_processing, + sys_comp_module_dolby_dax_audio_processing_interface_init); + +#endif diff --git a/src/audio/module_adapter/module/dolby/dax.toml b/src/audio/module_adapter/module/dolby/dax.toml new file mode 100644 index 000000000000..c53911a3b33e --- /dev/null +++ b/src/audio/module_adapter/module/dolby/dax.toml @@ -0,0 +1,25 @@ +#ifndef LOAD_TYPE +#define LOAD_TYPE "0" +#endif + + REM # DAX module config + [[module.entry]] + name = "DAX" + uuid = "40F66C8B-5AA5-4345-8919-53EC431AAA98" + affinity_mask = "0x7" + instance_count = "1" + domain_types = "1" + load_type = LOAD_TYPE + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + REM # see struct fw_pin_description + REM # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0x400, 0x8, 0x8, 0x4404] + + REM # see struct sof_man_mod_config + REM # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 135000000, 1024, 1024, 0, 675000, 0] + + index = __COUNTER__ diff --git a/src/audio/module_adapter/module/dolby/dax_mock.c b/src/audio/module_adapter/module/dolby/dax_mock.c new file mode 100644 index 000000000000..c8889699a7e8 --- /dev/null +++ b/src/audio/module_adapter/module/dolby/dax_mock.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE +// +// Copyright(c) 2025 Dolby Laboratories. All rights reserved. +// +// Author: Jun Lai +// + +#include +#include + +#define PLACEHOLDER_BUF_SZ 8 + +uint32_t dax_query_persist_memory(struct sof_dax *dax_ctx) +{ + return PLACEHOLDER_BUF_SZ; +} + +uint32_t dax_query_scratch_memory(struct sof_dax *dax_ctx) +{ + return PLACEHOLDER_BUF_SZ; +} + +uint32_t dax_query_period_frames(struct sof_dax *dax_ctx) +{ + return 256; +} + +int dax_free(struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_init(struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_process(struct sof_dax *dax_ctx) +{ + uint32_t peroid_bytes = dax_query_period_frames(dax_ctx) * + dax_ctx->input_media_format.num_channels * + dax_ctx->input_media_format.bytes_per_sample; + + if (dax_ctx->input_buffer.avail < peroid_bytes || + dax_ctx->output_buffer.free < peroid_bytes) { + return 0; + } + memcpy_s((uint8_t *)dax_ctx->output_buffer.addr + dax_ctx->output_buffer.avail, + dax_ctx->output_buffer.free, + dax_ctx->input_buffer.addr, + peroid_bytes); + return peroid_bytes; +} + +int dax_set_param(uint32_t id, const void *val, uint32_t val_sz, struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_set_enable(int32_t enable, struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_set_volume(int32_t pregain, struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_set_device(int32_t out_device, struct sof_dax *dax_ctx) +{ + return 0; +} + +int dax_set_ctc_enable(int32_t enable, struct sof_dax *dax_ctx) +{ + return 0; +} + +const char *dax_get_version(void) +{ + return ""; +} + +void *dax_find_params(uint32_t query_id, + int32_t query_val, + uint32_t *query_sz, + struct sof_dax *dax_ctx) +{ + return NULL; +} diff --git a/src/audio/module_adapter/module/dolby/llext-wrap.c b/src/audio/module_adapter/module/dolby/llext-wrap.c new file mode 100644 index 000000000000..30c7be24e22b --- /dev/null +++ b/src/audio/module_adapter/module/dolby/llext-wrap.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. + +#include +#include +#include +#include + +/* + * Stubs that are needed for linkage of some applications or libraries + * that come from porting userspace code. Anyone porting should + * make sure that any code does not depend on working copies of these + * reentrant functions. We will fail for any caller. + */ + +struct stat; +struct _reent; + +size_t _read_r(struct _reent *ptr, int fd, char *buf, size_t cnt) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +size_t _write_r(struct _reent *ptr, int fd, char *buf, size_t cnt) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + errno = -ENOTSUP; + return NULL; +} + +int _lseek_r(struct _reent *ptr, int fd, int pos, int whence) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +int _kill_r(struct _reent *ptr, int pid, int sig) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +int _getpid_r(struct _reent *ptr) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +int _close_r(struct _reent *ptr, int fd) +{ + errno = -ENOTSUP; + return -ENOTSUP; +} + +void _exit(int status) +{ + assert(0); + while (1) { + /* spin forever */ + } + /* NOTREACHED */ +} diff --git a/src/audio/module_adapter/module/dolby/llext/CMakeLists.txt b/src/audio/module_adapter/module/dolby/llext/CMakeLists.txt new file mode 100644 index 000000000000..fe8a965d8c87 --- /dev/null +++ b/src/audio/module_adapter/module/dolby/llext/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright(c) 2025 Dolby Laboratories. +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK) + sof_llext_build("dolby_dax_audio_processing" + SOURCES ../dax.c + ../dax_mock.c + INCLUDES ${sof_top_dir}/third_party/include + ) +else() + sof_llext_build("dolby_dax_audio_processing" + SOURCES ../dax.c ../llext-wrap.c + INCLUDES ${sof_top_dir}/third_party/include + LIBS_PATH ${sof_top_dir}/third_party/lib/ + LIBS dax m c gcc + ) +endif() diff --git a/src/audio/module_adapter/module/dolby/llext/llext.toml.h b/src/audio/module_adapter/module/dolby/llext/llext.toml.h new file mode 100644 index 000000000000..74f92b85fb81 --- /dev/null +++ b/src/audio/module_adapter/module/dolby/llext/llext.toml.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Dolby Laboratories. All rights reserved. + */ +#include +#define LOAD_TYPE "2" +#include "../dax.toml" + +[module] +count = __COUNTER__ diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f95299f952d8..6c8feccd8a6d 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -12,15 +12,24 @@ */ #include - +#include +#include #include #include #include +#include +#if CONFIG_IPC_MAJOR_4 +#include +#include +#include +#endif /* The __ZEPHYR__ condition is to keep cmocka tests working */ #if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__) -#define MEM_API_CHECK_THREAD(res) __ASSERT((res)->rsrc_mngr == k_current_get(), \ - "Module memory API operation from wrong thread") +#define MEM_API_CHECK_THREAD(res) do { \ + if ((res)->rsrc_mngr != k_current_get()) \ + LOG_WRN("mngr %p != cur %p", (res)->rsrc_mngr, k_current_get()); \ +} while (0) #else #define MEM_API_CHECK_THREAD(res) #endif @@ -71,10 +80,20 @@ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size) return ret; } +void mod_resource_init(struct processing_module *mod) +{ + struct module_data *md = &mod->priv; + + /* Init memory list */ + list_init(&md->resources.objpool.list); + md->resources.objpool.heap = md->resources.heap; + md->resources.heap_usage = 0; + md->resources.heap_high_water_mark = 0; +} + int module_init(struct processing_module *mod) { int ret; - struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; const struct module_interface *const interface = dev->drv->adapter_ops; @@ -99,82 +118,73 @@ int module_init(struct processing_module *mod) return -EIO; } - /* Init memory list */ - list_init(&md->resources.res_list); - list_init(&md->resources.free_cont_list); - list_init(&md->resources.cont_chunk_list); - md->resources.heap_usage = 0; - md->resources.heap_high_water_mark = 0; #if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__) - md->resources.rsrc_mngr = k_current_get(); + mod->priv.resources.rsrc_mngr = k_current_get(); #endif /* Now we can proceed with module specific initialization */ - ret = interface->init(mod); +#if CONFIG_SOF_USERSPACE_APPLICATION + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + ret = scheduler_dp_thread_ipc(mod, SOF_IPC4_MOD_INIT_INSTANCE, NULL); + else +#endif + ret = interface->init(mod); + if (ret) { comp_err(dev, "error %d: module specific init failed", ret); + mod_free_all(mod); return ret; } comp_dbg(dev, "done"); #if CONFIG_IPC_MAJOR_3 - md->state = MODULE_INITIALIZED; + mod->priv.state = MODULE_INITIALIZED; #endif return 0; } -struct container_chunk { - struct list_item chunk_list; - struct module_resource containers[CONFIG_MODULE_MEMORY_API_CONTAINER_CHUNK_SIZE]; -}; - static struct module_resource *container_get(struct processing_module *mod) { - struct module_resources *res = &mod->priv.resources; - struct module_resource *container; - - if (list_is_empty(&res->free_cont_list)) { - struct container_chunk *chunk = rzalloc(SOF_MEM_FLAG_USER, sizeof(*chunk)); - int i; - - if (!chunk) { - comp_err(mod->dev, "allocating more containers failed"); - return NULL; - } - - list_item_append(&chunk->chunk_list, &res->cont_chunk_list); - for (i = 0; i < ARRAY_SIZE(chunk->containers); i++) - list_item_append(&chunk->containers[i].list, &res->free_cont_list); - } - - container = list_first_item(&res->free_cont_list, struct module_resource, list); - list_item_del(&container->list); - return container; + return objpool_alloc(&mod->priv.resources.objpool, sizeof(struct module_resource), 0); } static void container_put(struct processing_module *mod, struct module_resource *container) +{ + objpool_free(&mod->priv.resources.objpool, container); +} + +#if CONFIG_USERSPACE +void mod_heap_info(struct processing_module *mod, size_t *size, uintptr_t *start) { struct module_resources *res = &mod->priv.resources; - list_item_append(&container->list, &res->free_cont_list); + if (size) + *size = res->heap->heap.init_bytes; + + if (start) + *start = (uintptr_t)container_of(res->heap, struct dp_heap_user, heap); } +#endif /** - * Allocates aligned memory block for module. - * @param mod Pointer to the module this memory block is allocatd for. + * Allocates aligned buffer memory block for module. + * @param mod Pointer to the module this memory block is allocated for. * @param bytes Size in bytes. * @param alignment Alignment in bytes. * @return Pointer to the allocated memory or NULL if failed. * - * The allocated memory is automatically freed when the module is unloaded. + * The allocated memory is automatically freed when the module is + * unloaded. The back-end, rballoc(), always aligns the memory to + * PLATFORM_DCACHE_ALIGN at the minimum. */ -void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment) +void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment) { - struct module_resource *container = container_get(mod); struct module_resources *res = &mod->priv.resources; - void *ptr; + struct module_resource *container; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; @@ -184,14 +194,13 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali return NULL; } - /* Allocate memory for module */ - if (alignment) - ptr = rballoc_align(SOF_MEM_FLAG_USER, size, alignment); - else - ptr = rballoc(SOF_MEM_FLAG_USER, size); + /* Allocate buffer memory for module */ + void *ptr = sof_heap_alloc(res->heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_LARGE_BUFFER, + size, alignment); if (!ptr) { - comp_err(mod->dev, "failed to allocate memory."); + comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.", + size, alignment, dev_comp_id(mod->dev)); container_put(mod, container); return NULL; } @@ -199,7 +208,6 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali container->ptr = ptr; container->size = size; container->type = MOD_RES_HEAP; - list_item_prepend(&container->list, &res->res_list); res->heap_usage += size; if (res->heap_usage > res->heap_high_water_mark) @@ -207,41 +215,57 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali return ptr; } -EXPORT_SYMBOL(mod_alloc_align); +EXPORT_SYMBOL(mod_balloc_align); /** - * Allocates memory block for module. - * @param mod Pointer to module this memory block is allocated for. - * @param bytes Size in bytes. + * Allocates aligned memory block with flags for module. + * @param mod Pointer to the module this memory block is allocated for. + * @param flags Allocator flags. + * @param bytes Size in bytes. + * @param alignment Alignment in bytes. * @return Pointer to the allocated memory or NULL if failed. * - * Like mod_alloc_align() but the alignment can not be specified. However, - * rballoc() will always aligns the memory to PLATFORM_DCACHE_ALIGN. + * The allocated memory is automatically freed when the module is unloaded. */ -void *mod_alloc(struct processing_module *mod, uint32_t size) +void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, + size_t alignment) { - return mod_alloc_align(mod, size, 0); -} -EXPORT_SYMBOL(mod_alloc); + struct module_resources *res = &mod->priv.resources; + struct module_resource *container; -/** - * Allocates memory block for module and initializes it to zero. - * @param mod Pointer to module this memory block is allocated for. - * @param bytes Size in bytes. - * @return Pointer to the allocated memory or NULL if failed. - * - * Like mod_alloc() but the allocated memory is initialized to zero. - */ -void *mod_zalloc(struct processing_module *mod, uint32_t size) -{ - void *ret = mod_alloc(mod, size); + MEM_API_CHECK_THREAD(res); - if (ret) - memset(ret, 0, size); + container = container_get(mod); + if (!container) + return NULL; - return ret; + if (!size) { + comp_err(mod->dev, "requested allocation of 0 bytes."); + container_put(mod, container); + return NULL; + } + + /* Allocate memory for module */ + void *ptr = sof_heap_alloc(res->heap, flags, size, alignment); + + if (!ptr) { + comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.", + size, alignment, dev_comp_id(mod->dev)); + container_put(mod, container); + return NULL; + } + /* Store reference to allocated memory */ + container->ptr = ptr; + container->size = size; + container->type = MOD_RES_HEAP; + + res->heap_usage += size; + if (res->heap_usage > res->heap_high_water_mark) + res->heap_high_water_mark = res->heap_usage; + + return ptr; } -EXPORT_SYMBOL(mod_zalloc); +EXPORT_SYMBOL(z_impl_mod_alloc_ext); /** * Creates a blob handler and releases it when the module is unloaded @@ -251,14 +275,15 @@ EXPORT_SYMBOL(mod_zalloc); * Like comp_data_blob_handler_new() but the handler is automatically freed. */ #if CONFIG_COMP_BLOB -struct comp_data_blob_handler * -mod_data_blob_handler_new(struct processing_module *mod) +struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_module *mod) { - struct module_resources *res = &mod->priv.resources; - struct module_resource *container = container_get(mod); + struct module_resources * __maybe_unused res = &mod->priv.resources; struct comp_data_blob_handler *bhp; + struct module_resource *container; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; @@ -271,7 +296,6 @@ mod_data_blob_handler_new(struct processing_module *mod) container->bhp = bhp; container->size = 0; container->type = MOD_RES_BLOB_HANDLER; - list_item_prepend(&container->list, &res->res_list); return bhp; } @@ -286,17 +310,20 @@ EXPORT_SYMBOL(mod_data_blob_handler_new); * Like fast_get() but the handler is automatically freed. */ #if CONFIG_FAST_GET -const void *mod_fast_get(struct processing_module *mod, const void * const dram_ptr, size_t size) +const void *z_impl_mod_fast_get(struct processing_module *mod, const void * const dram_ptr, + size_t size) { struct module_resources *res = &mod->priv.resources; - struct module_resource *container = container_get(mod); + struct module_resource *container; const void *ptr; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; - ptr = fast_get(dram_ptr, size); + ptr = fast_get(res->heap, dram_ptr, size); if (!ptr) { container_put(mod, container); return NULL; @@ -305,11 +332,10 @@ const void *mod_fast_get(struct processing_module *mod, const void * const dram_ container->sram_ptr = ptr; container->size = 0; container->type = MOD_RES_FAST_GET; - list_item_prepend(&container->list, &res->res_list); return ptr; } -EXPORT_SYMBOL(mod_fast_get); +EXPORT_SYMBOL(z_impl_mod_fast_get); #endif static int free_contents(struct processing_module *mod, struct module_resource *container) @@ -318,7 +344,7 @@ static int free_contents(struct processing_module *mod, struct module_resource * switch (container->type) { case MOD_RES_HEAP: - rfree(container->ptr); + sof_heap_free(res->heap, container->ptr); res->heap_usage -= container->size; return 0; #if CONFIG_COMP_BLOB @@ -328,7 +354,7 @@ static int free_contents(struct processing_module *mod, struct module_resource * #endif #if CONFIG_FAST_GET case MOD_RES_FAST_GET: - fast_put(container->sram_ptr); + fast_put(res->heap, container->sram_ptr); return 0; #endif default: @@ -337,38 +363,92 @@ static int free_contents(struct processing_module *mod, struct module_resource * return -EINVAL; } +struct mod_res_cb_arg { + struct processing_module *mod; + const void *ptr; +}; + +static bool mod_res_free(void *data, void *arg) +{ + struct mod_res_cb_arg *cb_arg = arg; + struct module_resource *container = data; + + if (cb_arg->ptr && container->ptr != cb_arg->ptr) + return false; + + int ret = free_contents(cb_arg->mod, container); + + if (ret < 0) + comp_err(cb_arg->mod->dev, "Cannot free allocation %p", cb_arg->ptr); + + container_put(cb_arg->mod, container); + + /* cb_arg->ptr == NULL means, that we're freeing all. Continue iterating */ + return !!cb_arg->ptr; +} + /** * Frees the memory block removes it from module's book keeping. * @param mod Pointer to module this memory block was allocated for. * @param ptr Pointer to the memory block. */ -int mod_free(struct processing_module *mod, const void *ptr) +int z_impl_mod_free(struct processing_module *mod, const void *ptr) { struct module_resources *res = &mod->priv.resources; - struct module_resource *container; - struct list_item *res_list; MEM_API_CHECK_THREAD(res); if (!ptr) return 0; - /* Find which container keeps this memory */ - list_for_item(res_list, &res->res_list) { - container = container_of(res_list, struct module_resource, list); - if (container->ptr == ptr) { - int ret = free_contents(mod, container); + /* Find which container holds this memory */ + struct mod_res_cb_arg cb_arg = {mod, ptr}; + int ret = objpool_iterate(&res->objpool, mod_res_free, &cb_arg); - list_item_del(&container->list); - container_put(mod, container); - return ret; - } - } + if (ret < 0) + comp_err(mod->dev, "error: could not find memory pointed by %p", ptr); - comp_err(mod->dev, "error: could not find memory pointed by %p", ptr); + return ret; +} +EXPORT_SYMBOL(z_impl_mod_free); - return -EINVAL; +#ifdef CONFIG_USERSPACE +#include +const void *z_vrfy_mod_fast_get(struct processing_module *mod, const void * const dram_ptr, + size_t size) +{ + struct module_resources *res = &mod->priv.resources; + + K_OOPS(K_SYSCALL_MEMORY_WRITE(mod, sizeof(*mod))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(res->heap, sizeof(*res->heap))); + K_OOPS(K_SYSCALL_MEMORY_READ(dram_ptr, size)); + + return z_impl_mod_fast_get(mod, dram_ptr, size); } -EXPORT_SYMBOL(mod_free); +#include + +void *z_vrfy_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, + size_t alignment) +{ + struct module_resources *res = &mod->priv.resources; + + K_OOPS(K_SYSCALL_MEMORY_WRITE(mod, sizeof(*mod))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(res->heap, sizeof(*res->heap))); + + return z_impl_mod_alloc_ext(mod, flags, size, alignment); +} +#include + +int z_vrfy_mod_free(struct processing_module *mod, const void *ptr) +{ + struct module_resources *res = &mod->priv.resources; + + K_OOPS(K_SYSCALL_MEMORY_WRITE(mod, sizeof(*mod))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(res->heap, sizeof(*res->heap))); + + return z_impl_mod_free(mod, ptr); +} +#include +#endif #if CONFIG_COMP_BLOB void mod_data_blob_handler_free(struct processing_module *mod, struct comp_data_blob_handler *dbh) @@ -403,7 +483,24 @@ int module_prepare(struct processing_module *mod, return -EPERM; #endif if (ops->prepare) { - int ret = ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); + int ret; + +#if CONFIG_SOF_USERSPACE_APPLICATION + if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + const union scheduler_dp_thread_ipc_param param = { + .pipeline_state = { + .trigger_cmd = COMP_TRIGGER_PREPARE, + .state = SOF_IPC4_PIPELINE_STATE_RUNNING, + .n_sources = num_of_sources, + .sources = sources, + .n_sinks = num_of_sinks, + .sinks = sinks, + }, + }; + ret = scheduler_dp_thread_ipc(mod, SOF_IPC4_GLB_SET_PIPELINE_STATE, ¶m); + } else +#endif + ret = ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); if (ret) { comp_err(dev, "error %d: module specific prepare failed", ret); @@ -522,11 +619,23 @@ int module_reset(struct processing_module *mod) if (md->state < MODULE_IDLE) return 0; #endif + /* cancel task if DP task*/ - if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP && mod->dev->task) + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP && mod->dev->task && + !IS_ENABLED(CONFIG_SOF_USERSPACE_APPLICATION)) schedule_task_cancel(mod->dev->task); + if (ops->reset) { - ret = ops->reset(mod); +#if CONFIG_SOF_USERSPACE_APPLICATION + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + const union scheduler_dp_thread_ipc_param param = { + .pipeline_state.trigger_cmd = COMP_TRIGGER_STOP, + }; + ret = scheduler_dp_thread_ipc(mod, SOF_IPC4_GLB_SET_PIPELINE_STATE, ¶m); + } else +#endif + ret = ops->reset(mod); + if (ret) { if (ret != PPL_STATUS_PATH_STOP) comp_err(mod->dev, @@ -559,28 +668,18 @@ int module_reset(struct processing_module *mod) void mod_free_all(struct processing_module *mod) { struct module_resources *res = &mod->priv.resources; - struct list_item *list; - struct list_item *_list; MEM_API_CHECK_THREAD(res); - /* Find which container keeps this memory */ - list_for_item_safe(list, _list, &res->res_list) { - struct module_resource *container = - container_of(list, struct module_resource, list); - free_contents(mod, container); - list_item_del(&container->list); - } + /* Free all contents found in used containers */ + struct mod_res_cb_arg cb_arg = {mod, NULL}; - list_for_item_safe(list, _list, &res->cont_chunk_list) { - struct container_chunk *chunk = - container_of(list, struct container_chunk, chunk_list); + objpool_iterate(&res->objpool, mod_res_free, &cb_arg); + objpool_prune(&res->objpool); - list_item_del(&chunk->chunk_list); - rfree(chunk); - } + /* Make sure resource lists and accounting are reset */ + mod_resource_init(mod); } -EXPORT_SYMBOL(mod_free_all); int module_free(struct processing_module *mod) { @@ -588,7 +687,8 @@ int module_free(struct processing_module *mod) struct module_data *md = &mod->priv; int ret = 0; - if (ops->free) { + if (ops->free && (mod->dev->ipc_config.proc_domain != COMP_PROCESSING_DOMAIN_DP || + !IS_ENABLED(CONFIG_SOF_USERSPACE_APPLICATION))) { ret = ops->free(mod); if (ret) comp_warn(mod->dev, "error: %d", ret); @@ -733,8 +833,17 @@ int module_bind(struct processing_module *mod, struct bind_info *bind_data) if (ret) return ret; - if (ops->bind) - ret = ops->bind(mod, bind_data); + if (ops->bind) { +#if CONFIG_SOF_USERSPACE_APPLICATION + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + const union scheduler_dp_thread_ipc_param param = { + .bind_data = bind_data, + }; + ret = scheduler_dp_thread_ipc(mod, SOF_IPC4_MOD_BIND, ¶m); + } else +#endif + ret = ops->bind(mod, bind_data); + } return ret; } @@ -757,8 +866,17 @@ int module_unbind(struct processing_module *mod, struct bind_info *unbind_data) if (ret) return ret; - if (ops->unbind) - ret = ops->unbind(mod, unbind_data); + if (ops->unbind) { +#if CONFIG_SOF_USERSPACE_APPLICATION + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + const union scheduler_dp_thread_ipc_param param = { + .bind_data = unbind_data, + }; + ret = scheduler_dp_thread_ipc(mod, SOF_IPC4_MOD_UNBIND, ¶m); + } else +#endif + ret = ops->unbind(mod, unbind_data); + } return ret; } @@ -774,3 +892,26 @@ void module_update_buffer_position(struct input_stream_buffer *input_buffers, output_buffers->size += audio_stream_frame_bytes(sink) * frames; } EXPORT_SYMBOL(module_update_buffer_position); + +uint32_t module_get_deadline(struct processing_module *mod) +{ + uint32_t deadline; + + /* LL modules have no deadline - it is always "now" */ + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) + return 0; + + /* startup condition - set deadline to "unknown" */ + if (mod->dp_startup_delay) + return UINT32_MAX / 2; + + deadline = UINT32_MAX; + /* calculate the shortest LFT for all sinks */ + for (size_t i = 0; i < mod->num_of_sinks; i++) { + uint32_t sink_lft = sink_get_last_feeding_time(mod->sinks[i]); + + deadline = MIN(deadline, sink_lft); + } + + return deadline; +} diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 3bb34c449478..589a25e33887 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,6 @@ LOG_MODULE_REGISTER(sof_modules, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(modules); -DECLARE_TR_CTX(intel_codec_tr, SOF_UUID(modules_uuid), LOG_LEVEL_INFO); /** * \brief modules_init. @@ -201,7 +201,7 @@ static int modules_reset(struct processing_module *mod) } /* Processing Module Adapter API*/ -const struct module_interface processing_module_adapter_interface = { +APP_TASK_DATA const struct module_interface processing_module_adapter_interface = { .init = modules_init, .prepare = modules_prepare, .process = modules_process, diff --git a/src/audio/module_adapter/module/passthrough.c b/src/audio/module_adapter/module/passthrough.c index 484e1319ae3a..4ad42277cbe3 100644 --- a/src/audio/module_adapter/module/passthrough.c +++ b/src/audio/module_adapter/module/passthrough.c @@ -12,7 +12,6 @@ LOG_MODULE_REGISTER(passthrough, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(passthrough); -DECLARE_TR_CTX(passthrough_tr, SOF_UUID(passthrough_uuid), LOG_LEVEL_INFO); static int passthrough_codec_init(struct processing_module *mod) { @@ -127,5 +126,6 @@ static const struct module_interface passthrough_interface = { .free = passthrough_codec_free }; +DECLARE_TR_CTX(passthrough_tr, SOF_UUID(passthrough_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(passthrough_interface, passthrough_uuid, passthrough_tr); SOF_MODULE_INIT(passthrough, sys_comp_module_passthrough_interface_init); diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index 624b53f5f75c..6616527d2308 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -20,7 +20,6 @@ SOF_DEFINE_REG_UUID(waves); -DECLARE_TR_CTX(waves_tr, SOF_UUID(waves_uuid), LOG_LEVEL_INFO); LOG_MODULE_REGISTER(waves, CONFIG_SOF_LOG_LEVEL); struct waves_codec_data { @@ -191,11 +190,11 @@ static int waves_effect_allocate(struct processing_module *mod) struct waves_codec_data *waves_codec = codec->private; MaxxStatus_t status; - comp_dbg(dev, "waves_effect_allocate() start"); + comp_dbg(dev, "start"); status = MaxxEffect_GetEffectSize(&waves_codec->effect_size); if (status) { - comp_err(dev, "waves_effect_allocate() MaxxEffect_GetEffectSize returned %d", + comp_err(dev, "MaxxEffect_GetEffectSize returned %d", status); return -EINVAL; } @@ -204,12 +203,12 @@ static int waves_effect_allocate(struct processing_module *mod) waves_codec->effect_size, 16); if (!waves_codec->effect) { - comp_err(dev, "waves_effect_allocate() failed to allocate %d bytes for effect", + comp_err(dev, "failed to allocate %d bytes for effect", waves_codec->effect_size); return -ENOMEM; } - comp_dbg(dev, "waves_effect_allocate() allocated %d bytes for effect", + comp_dbg(dev, "allocated %d bytes for effect", waves_codec->effect_size); return 0; @@ -224,7 +223,7 @@ static int waves_effect_check(struct comp_dev *dev) const struct audio_stream *snk_fmt = &sink->stream; /* Init sink & source buffers */ - comp_dbg(dev, "waves_effect_check() start"); + comp_dbg(dev, "start"); if (!source || !sink) { comp_err(dev, "no source or sink buffer"); @@ -235,55 +234,55 @@ static int waves_effect_check(struct comp_dev *dev) /* resampling not supported */ if (audio_stream_get_rate(src_fmt) != audio_stream_get_rate(snk_fmt)) { - comp_err(dev, "waves_effect_check() source %d sink %d rate mismatch", + comp_err(dev, "source %d sink %d rate mismatch", audio_stream_get_rate(src_fmt), audio_stream_get_rate(snk_fmt)); return -EINVAL; } /* upmix/downmix not supported */ if (audio_stream_get_channels(src_fmt) != audio_stream_get_channels(snk_fmt)) { - comp_err(dev, "waves_effect_check() source %d sink %d channels mismatch", + comp_err(dev, "source %d sink %d channels mismatch", audio_stream_get_channels(src_fmt), audio_stream_get_channels(snk_fmt)); return -EINVAL; } /* different frame format not supported */ if (audio_stream_get_frm_fmt(src_fmt) != audio_stream_get_frm_fmt(snk_fmt)) { - comp_err(dev, "waves_effect_check() source %d sink %d sample format mismatch", + comp_err(dev, "source %d sink %d sample format mismatch", audio_stream_get_frm_fmt(src_fmt), audio_stream_get_frm_fmt(snk_fmt)); return -EINVAL; } /* different interleaving is not supported */ if (audio_stream_get_buffer_fmt(src_fmt) != audio_stream_get_buffer_fmt(snk_fmt)) { - comp_err(dev, "waves_effect_check() source %d sink %d buffer format mismatch", + comp_err(dev, "source %d sink %d buffer format mismatch", audio_stream_get_buffer_fmt(src_fmt), audio_stream_get_buffer_fmt(snk_fmt)); return -EINVAL; } if (!format_is_supported(audio_stream_get_frm_fmt(src_fmt))) { - comp_err(dev, "waves_effect_check() float samples not supported"); + comp_err(dev, "float samples not supported"); return -EINVAL; } if (!layout_is_supported(audio_stream_get_buffer_fmt(src_fmt))) { - comp_err(dev, "waves_effect_check() non interleaved format not supported"); + comp_err(dev, "non interleaved format not supported"); return -EINVAL; } if (!rate_is_supported(audio_stream_get_rate(src_fmt))) { - comp_err(dev, "waves_effect_check() rate %d not supported", + comp_err(dev, "rate %d not supported", audio_stream_get_rate(src_fmt)); return -EINVAL; } if (audio_stream_get_channels(src_fmt) != 2) { - comp_err(dev, "waves_effect_check() channels %d not supported", + comp_err(dev, "channels %d not supported", audio_stream_get_channels(src_fmt)); return -EINVAL; } - comp_dbg(dev, "waves_effect_check() done"); + comp_dbg(dev, "done"); return 0; } @@ -302,25 +301,25 @@ static int waves_effect_init(struct processing_module *mod) MaxxStreamFormat_t *i_formats[NUM_IO_STREAMS] = { &waves_codec->i_format }; MaxxStreamFormat_t *o_formats[NUM_IO_STREAMS] = { &waves_codec->o_format }; - comp_dbg(dev, "waves_effect_init() start"); + comp_dbg(dev, "start"); sample_format = format_convert_sof_to_me(audio_stream_get_frm_fmt(src_fmt)); if (sample_format < 0) { - comp_err(dev, "waves_effect_init() sof sample format %d not supported", + comp_err(dev, "sof sample format %d not supported", audio_stream_get_frm_fmt(src_fmt)); return -EINVAL; } buffer_format = layout_convert_sof_to_me(audio_stream_get_buffer_fmt(src_fmt)); if (buffer_format < 0) { - comp_err(dev, "waves_effect_init() sof buffer format %d not supported", + comp_err(dev, "sof buffer format %d not supported", audio_stream_get_buffer_fmt(src_fmt)); return -EINVAL; } sample_bytes = sample_format_convert_to_bytes(sample_format); if (sample_bytes < 0) { - comp_err(dev, "waves_effect_init() sample_format %d not supported", + comp_err(dev, "sample_format %d not supported", sample_format); return -EINVAL; } @@ -346,22 +345,22 @@ static int waves_effect_init(struct processing_module *mod) // trace allows printing only up-to 4 words at a time // logging all the information in two calls - comp_info(dev, "waves_effect_init() rate %d, channels %d", waves_codec->i_format.sampleRate, + comp_info(dev, "rate %d, channels %d", waves_codec->i_format.sampleRate, waves_codec->i_format.numChannels); - comp_info(dev, "waves_effect_init() format %d, layout %d, frame %d", + comp_info(dev, "format %d, layout %d, frame %d", waves_codec->i_format.samplesFormat, waves_codec->i_format.samplesLayout, waves_codec->buffer_samples); status = MaxxEffect_Initialize(waves_codec->effect, i_formats, 1, o_formats, 1); if (status) { - comp_err(dev, "waves_effect_init() MaxxEffect_Initialize returned %d", status); + comp_err(dev, "MaxxEffect_Initialize returned %d", status); return -EINVAL; } waves_codec->initialized = true; - comp_dbg(dev, "waves_effect_init() done"); + comp_dbg(dev, "done"); return 0; } @@ -374,11 +373,11 @@ static int waves_effect_buffers(struct processing_module *mod) int ret; void *i_buffer = NULL, *o_buffer = NULL; - comp_dbg(dev, "waves_effect_buffers() start"); + comp_dbg(dev, "start"); i_buffer = mod_alloc_align(mod, waves_codec->buffer_bytes, 16); if (!i_buffer) { - comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for i_buffer", + comp_err(dev, "failed to allocate %d bytes for i_buffer", waves_codec->buffer_bytes); ret = -ENOMEM; goto err; @@ -386,7 +385,7 @@ static int waves_effect_buffers(struct processing_module *mod) o_buffer = mod_alloc_align(mod, waves_codec->buffer_bytes, 16); if (!o_buffer) { - comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for o_buffer", + comp_err(dev, "failed to allocate %d bytes for o_buffer", waves_codec->buffer_bytes); ret = -ENOMEM; goto err; @@ -399,10 +398,10 @@ static int waves_effect_buffers(struct processing_module *mod) codec->mpd.out_buff = waves_codec->o_buffer; codec->mpd.out_buff_size = waves_codec->buffer_bytes; - comp_dbg(dev, "waves_effect_buffers() in_buff_size %d, out_buff_size %d", + comp_dbg(dev, "in_buff_size %d, out_buff_size %d", codec->mpd.in_buff_size, codec->mpd.out_buff_size); - comp_dbg(dev, "waves_effect_buffers() done"); + comp_dbg(dev, "done"); return 0; err: @@ -423,12 +422,12 @@ static int waves_effect_revision(struct processing_module *mod) uint32_t revision_len; MaxxStatus_t status; - comp_info(dev, "waves_effect_revision() start"); + comp_info(dev, "start"); status = MaxxEffect_Revision_Get(waves_codec->effect, &revision, &revision_len); if (status) { - comp_err(dev, "waves_effect_revision() MaxxEffect_Revision_Get returned %d", + comp_err(dev, "MaxxEffect_Revision_Get returned %d", status); return -EINVAL; } @@ -458,7 +457,7 @@ static int waves_effect_revision(struct processing_module *mod) } #endif - comp_info(dev, "waves_effect_revision() done"); + comp_info(dev, "done"); return 0; } @@ -470,11 +469,11 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod, struct module_data *codec = &mod->priv; struct waves_codec_data *waves_codec = codec->private; - comp_info(dev, "waves_effect_save_config_blob_to_cache() start"); + comp_info(dev, "start"); /* release old cached config blob*/ if (waves_codec->config_blob && size != waves_codec->config_blob_size) { - comp_info(dev, "waves_effect_save_config_blob_to_cache() release blob"); + comp_info(dev, "release blob"); mod_free(mod, waves_codec->config_blob); waves_codec->config_blob = NULL; waves_codec->config_blob_size = 0; @@ -484,7 +483,7 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod, waves_codec->config_blob = mod_alloc_align(mod, size, 16); if (!waves_codec->config_blob) { comp_err(dev, - "waves_effect_save_config_blob_to_cache() failed to allocate %d bytes for config blob", + "failed to allocate %d bytes for config blob", size); return -ENOMEM; } @@ -503,7 +502,7 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod, return ret; } - comp_dbg(dev, "waves_effect_save_config_blob_to_cache() done"); + comp_dbg(dev, "done"); return 0; } @@ -517,13 +516,13 @@ static int waves_effect_message(struct processing_module *mod, void *data, uint3 uint32_t response_size = 0; if (waves_codec->initialized) { - comp_info(dev, "waves_effect_message() start data %p size %d", data, size); + comp_info(dev, "start data %p size %d", data, size); status = MaxxEffect_Message(waves_codec->effect, data, size, waves_codec->response, &response_size); if (status) { - comp_err(dev, "waves_effect_message() MaxxEffect_Message returned %d", + comp_err(dev, "MaxxEffect_Message returned %d", status); return -EINVAL; } @@ -553,7 +552,7 @@ static int waves_effect_apply_config_blob_from_cache(struct processing_module *m struct module_data *codec = &mod->priv; struct waves_codec_data *waves_codec = codec->private; - comp_info(dev, "waves_effect_apply_config_blob_from_cache()"); + comp_info(dev, "entry"); if (waves_codec->config_blob) { return waves_effect_message(mod, waves_codec->config_blob, @@ -584,24 +583,24 @@ static int waves_effect_apply_config(struct processing_module *mod) uint32_t param_number = 0; int ret = 0; - comp_info(dev, "waves_effect_apply_config() start"); + comp_info(dev, "start"); cfg = &codec->cfg; - comp_info(dev, "waves_effect_apply_config() config %p, size %d, avail %d", + comp_info(dev, "config %p, size %d, avail %d", cfg->data, cfg->size, cfg->avail); if (!cfg->data) { ret = waves_effect_apply_config_blob_from_cache(mod); if (ret) { - comp_err(dev, "waves_effect_apply_config() error %x: apply cache fail", + comp_err(dev, "error %x: apply cache fail", ret); return ret; } } if (cfg->size > MAX_CONFIG_SIZE_BYTES) { - comp_err(dev, "waves_effect_apply_config() provided config is too big, size %d", + comp_err(dev, "provided config is too big, size %d", cfg->size); return -EINVAL; } @@ -616,24 +615,24 @@ static int waves_effect_apply_config(struct processing_module *mod) param = (struct module_param *)((char *)cfg->data + index); param_data_size = param->size - sizeof(param->size) - sizeof(param->id); - comp_info(dev, "waves_effect_apply_config() param num %d id %d size %d", + comp_info(dev, "param num %d id %d size %d", param_number, param->id, param->size); if ((param->size <= header_size) || (param->size > MAX_CONFIG_SIZE_BYTES)) { - comp_err(dev, "waves_effect_apply_config() invalid module_param size: %d", + comp_err(dev, "invalid module_param size: %d", param->size); return -EINVAL; } if ((index + param->size) > cfg->size) { - comp_err(dev, "waves_effect_apply_config() module_param size: %d exceeds cfg buffer size: %d", + comp_err(dev, "module_param size: %d exceeds cfg buffer size: %d", param->size, cfg->size); return -EINVAL; } switch (param->id) { case PARAM_NOP: - comp_info(dev, "waves_effect_apply_config() NOP"); + comp_info(dev, "NOP"); break; case PARAM_MESSAGE: ret = waves_effect_handle_param_message(mod, param->data, param_data_size); @@ -650,11 +649,11 @@ static int waves_effect_apply_config(struct processing_module *mod) } if (ret) { - comp_err(dev, "waves_effect_apply_config() failed %d", ret); + comp_err(dev, "failed %d", ret); return ret; } - comp_dbg(dev, "waves_effect_apply_config() done"); + comp_dbg(dev, "done"); return 0; } @@ -666,11 +665,11 @@ static int waves_codec_init(struct processing_module *mod) int ret = 0; void *response = NULL; - comp_dbg(dev, "waves_codec_init() start"); + comp_dbg(dev, "start"); waves_codec = mod_alloc_align(mod, sizeof(struct waves_codec_data), 16); if (!waves_codec) { - comp_err(dev, "waves_codec_init() failed to allocate %d bytes for waves_codec_data", + comp_err(dev, "failed to allocate %d bytes for waves_codec_data", sizeof(struct waves_codec_data)); ret = -ENOMEM; } else { @@ -682,7 +681,7 @@ static int waves_codec_init(struct processing_module *mod) } if (ret) { - comp_err(dev, "waves_codec_init() failed %d", ret); + comp_err(dev, "failed %d", ret); return ret; } @@ -690,20 +689,20 @@ static int waves_codec_init(struct processing_module *mod) &waves_codec->response_max_bytes); if (ret) { - comp_err(dev, "waves_codec_init() MaxxEffect_GetMessageMaxSize returned %d", ret); + comp_err(dev, "MaxxEffect_GetMessageMaxSize returned %d", ret); return -EINVAL; } response = mod_alloc_align(mod, waves_codec->response_max_bytes, 16); if (!response) { - comp_err(dev, "waves_codec_init() failed to allocate %d bytes for response", + comp_err(dev, "failed to allocate %d bytes for response", waves_codec->response_max_bytes); return -ENOMEM; } waves_codec->response = response; waves_codec->initialized = false; - comp_dbg(dev, "waves_codec_init() done"); + comp_dbg(dev, "done"); return ret; } @@ -714,7 +713,7 @@ static int waves_codec_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "waves_codec_prepare() start"); + comp_dbg(dev, "start"); ret = waves_effect_check(dev); if (ret) @@ -732,11 +731,11 @@ static int waves_codec_prepare(struct processing_module *mod, if (ret) goto error; - comp_dbg(dev, "waves_codec_prepare() done"); + comp_dbg(dev, "done"); return 0; error: - comp_err(dev, "waves_codec_prepare() failed %d", ret); + comp_err(dev, "failed %d", ret); return ret; } @@ -745,7 +744,7 @@ static int waves_codec_init_process(struct processing_module *mod) struct module_data *codec = &mod->priv; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "waves_codec_init_process()"); + comp_dbg(dev, "entry"); codec->mpd.produced = 0; codec->mpd.consumed = 0; @@ -777,7 +776,7 @@ waves_codec_process(struct processing_module *mod, input_buffers[0].data, codec->mpd.in_buff_size); codec->mpd.avail = codec->mpd.in_buff_size; - comp_dbg(dev, "waves_codec_process() start"); + comp_dbg(dev, "start"); MaxxStream_t *i_streams[NUM_IO_STREAMS] = { &waves_codec->i_stream }; MaxxStream_t *o_streams[NUM_IO_STREAMS] = { &waves_codec->o_stream }; @@ -789,7 +788,7 @@ waves_codec_process(struct processing_module *mod, * on the other hand there is available/produced counters in mpd, check them anyways */ if (codec->mpd.avail != waves_codec->buffer_bytes) { - comp_warn(dev, "waves_codec_process() input buffer %d is not full %d", + comp_warn(dev, "input buffer %d is not full %d", codec->mpd.avail, waves_codec->buffer_bytes); num_input_samples = codec->mpd.avail / (waves_codec->sample_size_in_bytes * waves_codec->i_format.numChannels); @@ -807,7 +806,7 @@ waves_codec_process(struct processing_module *mod, status = MaxxEffect_Process(waves_codec->effect, i_streams, o_streams); if (status) { - comp_err(dev, "waves_codec_process() MaxxEffect_Process returned %d", status); + comp_err(dev, "MaxxEffect_Process returned %d", status); ret = -EINVAL; } else { codec->mpd.produced = waves_codec->o_stream.numAvailableSamples * @@ -822,9 +821,9 @@ waves_codec_process(struct processing_module *mod, } if (ret) - comp_err(dev, "waves_codec_process() failed %d", ret); + comp_err(dev, "failed %d", ret); - comp_dbg(dev, "waves_codec_process() done"); + comp_dbg(dev, "done"); return ret; } @@ -836,16 +835,16 @@ static int waves_codec_reset(struct processing_module *mod) struct module_data *codec = &mod->priv; struct waves_codec_data *waves_codec = codec->private; - comp_info(dev, "waves_codec_reset() start"); + comp_info(dev, "start"); status = MaxxEffect_Reset(waves_codec->effect); if (status) { - comp_err(dev, "waves_codec_reset() MaxxEffect_Reset returned %d", status); + comp_err(dev, "MaxxEffect_Reset returned %d", status); ret = -EINVAL; } if (ret) - comp_err(dev, "waves_codec_reset() failed %d", ret); + comp_err(dev, "failed %d", ret); if (codec->mpd.in_buff) mod_free(mod, codec->mpd.in_buff); @@ -854,13 +853,13 @@ static int waves_codec_reset(struct processing_module *mod) mod_free(mod, codec->mpd.out_buff); waves_codec->initialized = false; - comp_dbg(dev, "waves_codec_reset() done"); + comp_dbg(dev, "done"); return ret; } static int waves_codec_free(struct processing_module *mod) { - comp_dbg(mod->dev, "waves_codec_free()"); + comp_dbg(mod->dev, "entry"); return 0; } @@ -920,6 +919,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(waves_tr, SOF_UUID(waves_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(waves_interface, waves_uuid, waves_tr); SOF_MODULE_INIT(waves, sys_comp_module_waves_interface_init); diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 77777727efba..048eda0d47e0 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -18,12 +18,18 @@ #include #include #include +#include #include #include #include #include +#if CONFIG_IPC_MAJOR_4 +#include +#include +#include +#endif #include -#include +#include #include #include @@ -41,14 +47,146 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec) { - return module_adapter_new_ext(drv, config, spec, NULL); + return module_adapter_new_ext(drv, config, spec, NULL, NULL); +} + +#if CONFIG_MM_DRV +#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE +#else +#include +#define PAGE_SZ HOST_PAGE_SIZE +#endif + +static struct dp_heap_user *module_adapter_dp_heap_new(const struct comp_ipc_config *config, + size_t *heap_size) +{ + /* src-lite with 8 channels has been seen allocating 14k in one go */ + /* FIXME: the size will be derived from configuration */ + const size_t buf_size = 20 * 1024; + + /* Keep uncached to match the default SOF heap! */ + uint8_t *mod_heap_mem = rballoc_align(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + buf_size, PAGE_SZ); + + if (!mod_heap_mem) + return NULL; + + struct dp_heap_user *mod_heap_user = (struct dp_heap_user *)mod_heap_mem; + struct k_heap *mod_heap = &mod_heap_user->heap; + const size_t heap_prefix_size = ALIGN_UP(sizeof(*mod_heap_user), 4); + void *mod_heap_buf = mod_heap_mem + heap_prefix_size; + + *heap_size = buf_size - heap_prefix_size; + k_heap_init(mod_heap, mod_heap_buf, *heap_size); +#ifdef __ZEPHYR__ + mod_heap->heap.init_mem = mod_heap_buf; + mod_heap->heap.init_bytes = *heap_size; +#endif + + return mod_heap_user; +} + +static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, + const struct comp_ipc_config *config) +{ + struct k_heap *mod_heap; + /* + * For DP shared modules the struct processing_module object must be + * accessible from all cores. Unfortunately at this point there's no + * information of components the module will be bound to. So we need to + * allocate shared memory for each DP module. + * To be removed when pipeline 2.0 is ready. + */ + uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER; + struct dp_heap_user *mod_heap_user; + size_t heap_size; + + if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_USERSPACE) && + !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) { + mod_heap_user = module_adapter_dp_heap_new(config, &heap_size); + if (!mod_heap_user) { + comp_cl_err(drv, "Failed to allocate DP module heap"); + return NULL; + } + mod_heap = &mod_heap_user->heap; + } else { + mod_heap = drv->user_heap; + mod_heap_user = NULL; + heap_size = 0; + } + + struct processing_module *mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0); + + if (!mod) { + comp_cl_err(drv, "failed to allocate memory for module"); + goto emod; + } + + memset(mod, 0, sizeof(*mod)); + mod->priv.resources.heap = mod_heap; + mod_resource_init(mod); + + /* + * Would be difficult to optimize the allocation to use cache. Only if + * the whole currently active topology is running on the primary core, + * then it can be cached. Effectively it can be only cached in + * single-core configurations. + */ + struct comp_dev *dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0); + + if (!dev) { + comp_cl_err(drv, "failed to allocate memory for comp_dev"); + goto err; + } + + memset(dev, 0, sizeof(*dev)); + comp_init(drv, dev, sizeof(*dev)); + dev->ipc_config = *config; + mod->dev = dev; + dev->mod = mod; + + if (mod_heap_user) + mod_heap_user->client_count++; + + return mod; + +err: + sof_heap_free(mod_heap, mod); +emod: + rfree(mod_heap_user); + + return NULL; +} + +static void module_adapter_mem_free(struct processing_module *mod) +{ + struct k_heap *mod_heap = mod->priv.resources.heap; + unsigned int domain = mod->dev->ipc_config.proc_domain; + + /* + * In principle it shouldn't even be needed to free individual objects + * on the module heap since we're freeing the heap itself too + */ +#if CONFIG_IPC_MAJOR_4 + sof_heap_free(mod_heap, mod->priv.cfg.input_pins); +#endif + sof_heap_free(mod_heap, mod->dev); + sof_heap_free(mod_heap, mod); + if (domain == COMP_PROCESSING_DOMAIN_DP) { + struct dp_heap_user *mod_heap_user = container_of(mod_heap, struct dp_heap_user, + heap); + + if (mod_heap && !--mod_heap_user->client_count) + rfree(mod_heap_user); + } } /* * \brief Create a module adapter component. * \param[in] drv - component driver pointer. * \param[in] config - component ipc descriptor pointer. - * \param[in] spec - passdowned data from driver. + * \param[in] const_spec - passdowned data from driver. * \param[in] mod_priv - Pointer to private data for processing module. * * \return: a pointer to newly created module adapter component on success. NULL on error. @@ -57,54 +195,64 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, * the create method. */ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, - const struct comp_ipc_config *config, const void *spec, - void *mod_priv) + const struct comp_ipc_config *config, + const void *const_spec, void *mod_priv, + struct userspace_context *user_ctx) { int ret; - struct comp_dev *dev; - struct processing_module *mod; struct module_config *dst; const struct module_interface *const interface = drv->adapter_ops; - + struct ipc_config_process spec = + *((const struct ipc_config_process *) const_spec); +#if CONFIG_IPC_MAJOR_4 + struct module_ext_init_data ext_data = { 0 }; +#endif comp_cl_dbg(drv, "start"); if (!config) { - comp_cl_err(drv, "wrong input params! drv = %zx config = %zx", - (size_t)drv, (size_t)config); + comp_cl_err(drv, "NULL config! drv = %p", drv); return NULL; } +#if CONFIG_IPC_MAJOR_4 + if (config->ipc_extended_init) { + ret = module_ext_init_decode(drv, &ext_data, &spec); + if (ret != 0) + return NULL; + } +#endif - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) { - comp_cl_err(drv, "failed to allocate memory for comp_dev"); + struct processing_module *mod = module_adapter_mem_alloc(drv, config); + + if (!mod) return NULL; - } - dev->ipc_config = *config; - /* allocate module information. - * for DP shared modules this struct must be accessible from all cores - * Unfortunately at this point there's no information of components the module - * will be bound to. So we need to allocate shared memory for each DP module - * To be removed when pipeline 2.0 is ready - */ - int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? - SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER; + struct comp_dev *dev = mod->dev; - mod = module_driver_heap_rzalloc(drv->user_heap, flags, sizeof(*mod)); - if (!mod) { - comp_err(dev, "failed to allocate memory for module"); - goto err; +#if CONFIG_ZEPHYR_DP_SCHEDULER + /* create a task for DP processing */ + if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) { + /* All data allocated, create a thread */ + pipeline_comp_dp_task_init(dev); } - - dst = &mod->priv.cfg; +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ module_set_private_data(mod, mod_priv); - mod->dev = dev; - dev->mod = mod; - list_init(&mod->raw_data_buffers_list); +#if CONFIG_USERSPACE + mod->user_ctx = user_ctx; +#endif /* CONFIG_USERSPACE */ - ret = module_adapter_init_data(dev, dst, config, spec); + dst = &mod->priv.cfg; + /* + * NOTE: dst->ext_data points to stack variable and contains + * pointers to IPC payload mailbox, so its only valid in + * functions that called from this function. This why + * the pointer is set NULL before this function exits. + */ +#if CONFIG_IPC_MAJOR_4 + dst->ext_data = &ext_data; +#endif + ret = module_adapter_init_data(dev, dst, config, &spec); if (ret) { comp_err(dev, "%d: module init data failed", ret); @@ -125,6 +273,22 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, else goto err; +#if CONFIG_IPC_MAJOR_4 + struct ipc_comp_dev *ipc_pipe; + struct ipc *ipc = ipc_get(); + + /* set the pipeline pointer if ipc_pipe is valid */ + ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id, + IPC_COMP_IGNORE_REMOTE); + if (ipc_pipe) { + dev->pipeline = ipc_pipe->pipeline; + + /* LL modules have the same period as the pipeline */ + if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) + dev->period = ipc_pipe->pipeline->period; + } +#endif + /* Init processing module */ ret = module_init(mod); if (ret) { @@ -133,12 +297,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, goto err; } -#if CONFIG_ZEPHYR_DP_SCHEDULER - /* create a task for DP processing */ - if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) - pipeline_comp_dp_task_init(dev); -#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ - module_adapter_reset_data(dst); dev->state = COMP_STATE_READY; @@ -155,20 +313,29 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, comp_err(dev, "%d: module params failed", ret); goto err; } + + /* set component period frames */ + component_set_nearest_period_frames(dev, params.rate); #endif +#if CONFIG_IPC_MAJOR_4 + dst->ext_data = NULL; +#endif comp_dbg(dev, "done"); return dev; + err: +#if CONFIG_ZEPHYR_DP_SCHEDULER + if (dev->task) + schedule_task_free(dev->task); +#endif + module_adapter_mem_free(mod); #if CONFIG_IPC_MAJOR_4 - if (mod) - rfree(mod->priv.cfg.input_pins); + dst->ext_data = NULL; #endif - rfree(mod); - rfree(dev); + return NULL; } -EXPORT_SYMBOL(module_adapter_new); #if CONFIG_ZEPHYR_DP_SCHEDULER static void module_adapter_calculate_dp_period(struct comp_dev *dev) @@ -215,11 +382,7 @@ int module_adapter_prepare(struct comp_dev *dev) comp_dbg(dev, "start"); #if CONFIG_IPC_MAJOR_4 - /* - * if the stream_params are valid, just update the sink/source buffer params. If not, - * retrieve the params from the basecfg, allocate stream_params and then update the - * sink/source buffer params. - */ + /* allocate stream_params and retrieve the params from the basecfg if needed */ if (!mod->stream_params) { struct sof_ipc_stream_params params; @@ -228,12 +391,6 @@ int module_adapter_prepare(struct comp_dev *dev) comp_err(dev, "module_adapter_new() %d: module params failed", ret); return ret; } - } else { - ret = comp_verify_params(dev, mod->verify_params_flags, mod->stream_params); - if (ret < 0) { - comp_err(dev, "comp_verify_params() failed."); - return ret; - } } #endif /* Prepare module */ @@ -301,10 +458,15 @@ int module_adapter_prepare(struct comp_dev *dev) mod->deep_buff_bytes = 0; - /* Get period_bytes first on prepare(). At this point it is guaranteed that the stream - * parameter from sink buffer is settled, and still prior to all references to period_bytes. + /* Get period_bytes first on prepare(). At this point the stream parameter from sink buffer + * shall be settled, provided that the pipeline is built correctly (bind IPC received). + * Hence check for NULL. */ sink = comp_dev_get_first_data_consumer(dev); + if (!sink) { + comp_err(dev, "no sink present on period size calculation"); + return -EINVAL; + } mod->period_bytes = audio_stream_period_bytes(&sink->stream, dev->frames); comp_dbg(dev, "got period_bytes = %u", mod->period_bytes); @@ -449,7 +611,8 @@ int module_adapter_prepare(struct comp_dev *dev) if (list_is_empty(&mod->raw_data_buffers_list)) { for (i = 0; i < mod->num_of_sinks; i++) { /* allocate not shared buffer */ - struct comp_buffer *buffer = buffer_alloc(buff_size, memory_flags, + struct comp_buffer *buffer = buffer_alloc(md->resources.heap, buff_size, + memory_flags, PLATFORM_DCACHE_ALIGN, BUFFER_USAGE_NOT_SHARED); uint32_t flags; @@ -460,6 +623,14 @@ int module_adapter_prepare(struct comp_dev *dev) goto free; } + if (md->resources.heap && md->resources.heap != dev->drv->user_heap) { + struct dp_heap_user *dp_user = container_of(md->resources.heap, + struct dp_heap_user, + heap); + + dp_user->client_count++; + } + irq_local_disable(flags); list_item_prepend(&buffer->buffers_list, &mod->raw_data_buffers_list); irq_local_enable(flags); @@ -515,7 +686,6 @@ int module_adapter_prepare(struct comp_dev *dev) mod->input_buffers = NULL; return ret; } -EXPORT_SYMBOL(module_adapter_prepare); int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -524,18 +694,18 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa module_adapter_set_params(mod, params); +#if CONFIG_IPC_MAJOR_3 ret = comp_verify_params(dev, mod->verify_params_flags, params); if (ret < 0) { comp_err(dev, "comp_verify_params() failed."); return ret; } +#endif /* allocate stream_params each time */ - if (mod->stream_params) - rfree(mod->stream_params); + mod_free(mod, mod->stream_params); - mod->stream_params = rzalloc(SOF_MEM_FLAG_USER, - sizeof(*mod->stream_params) + params->ext_data_length); + mod->stream_params = mod_alloc(mod, sizeof(*mod->stream_params) + params->ext_data_length); if (!mod->stream_params) return -ENOMEM; @@ -555,7 +725,6 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa return 0; } -EXPORT_SYMBOL(module_adapter_params); /* * Function to copy from source buffer to the module buffer @@ -1170,7 +1339,6 @@ int module_adapter_copy(struct comp_dev *dev) comp_err(dev, "unknown processing_data_type"); return -EINVAL; } -EXPORT_SYMBOL(module_adapter_copy); int module_adapter_trigger(struct comp_dev *dev, int cmd) { @@ -1191,12 +1359,23 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd) dev->state = COMP_STATE_ACTIVE; return PPL_STATUS_PATH_STOP; } - if (interface->trigger) + + if (interface->trigger) { +#if CONFIG_SOF_USERSPACE_APPLICATION + if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + /* Process DP module's trigger */ + const union scheduler_dp_thread_ipc_param param = { + .pipeline_state.trigger_cmd = cmd, + }; + return scheduler_dp_thread_ipc(mod, SOF_IPC4_GLB_SET_PIPELINE_STATE, + ¶m); + } +#endif return interface->trigger(mod, cmd); + } return module_adapter_set_state(mod, dev, cmd); } -EXPORT_SYMBOL(module_adapter_trigger); int module_adapter_reset(struct comp_dev *dev) { @@ -1237,14 +1416,13 @@ int module_adapter_reset(struct comp_dev *dev) buffer_zero(buffer); } - rfree(mod->stream_params); + mod_free(mod, mod->stream_params); mod->stream_params = NULL; comp_dbg(dev, "done"); return comp_set_state(dev, COMP_TRIGGER_RESET); } -EXPORT_SYMBOL(module_adapter_reset); void module_adapter_free(struct comp_dev *dev) { @@ -1254,6 +1432,19 @@ void module_adapter_free(struct comp_dev *dev) comp_dbg(dev, "start"); + if (dev->task) { + /* + * Run DP module's .free() method in its thread context. + * Unlike with other IPCs we first run module's .free() in + * thread context, then cancel the thread, and then execute + * final clean up + */ +#if CONFIG_SOF_USERSPACE_APPLICATION + scheduler_dp_thread_ipc(mod, SOF_IPC4_MOD_DELETE_INSTANCE, NULL); +#endif + schedule_task_free(dev->task); + } + ret = module_free(mod); if (ret) comp_err(dev, "failed with error: %d", ret); @@ -1269,17 +1460,11 @@ void module_adapter_free(struct comp_dev *dev) buffer_free(buffer); } + mod_free(mod, mod->stream_params); mod_free_all(mod); -#if CONFIG_IPC_MAJOR_4 - rfree(mod->priv.cfg.input_pins); -#endif - - rfree(mod->stream_params); - rfree(mod); - rfree(dev); + module_adapter_mem_free(mod); } -EXPORT_SYMBOL(module_adapter_free); size_t module_adapter_heap_usage(struct processing_module *mod, size_t *hwm) { @@ -1290,7 +1475,6 @@ size_t module_adapter_heap_usage(struct processing_module *mod, size_t *hwm) return res->heap_usage; } -EXPORT_SYMBOL(module_adapter_heap_usage); /* * \brief Get DAI hw params @@ -1313,7 +1497,6 @@ int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_par return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_get_hw_params); /* * \brief Get stream position @@ -1334,7 +1517,6 @@ int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *po return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_position); /* * \brief DAI timestamp configure @@ -1354,7 +1536,6 @@ int module_adapter_ts_config_op(struct comp_dev *dev) return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_ts_config_op); /* * \brief DAI timestamp start @@ -1374,7 +1555,6 @@ int module_adapter_ts_start_op(struct comp_dev *dev) return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_ts_start_op); /* * \brief DAI timestamp stop @@ -1394,7 +1574,6 @@ int module_adapter_ts_stop_op(struct comp_dev *dev) return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_ts_stop_op); /* * \brief Get DAI timestamp @@ -1419,4 +1598,3 @@ int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) return -EOPNOTSUPP; } -EXPORT_SYMBOL(module_adapter_ts_get_op); diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c index 30aa8492c25d..74c8f02afa2f 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -91,7 +91,7 @@ int module_adapter_init_data(struct comp_dev *dev, break; } default: - comp_err(dev, "module_adapter_init_data() unsupported comp type %d", config->type); + comp_err(dev, "unsupported comp type %d", config->type); return -EINVAL; } @@ -99,7 +99,7 @@ int module_adapter_init_data(struct comp_dev *dev, if (size) { ret = module_load_config(dev, data, size); if (ret < 0) { - comp_err(dev, "module_adapter_init_data() error %d: config loading has failed.", + comp_err(dev, "error %d: config loading has failed.", ret); return ret; } @@ -270,7 +270,7 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s const struct module_interface *const interface = mod->dev->drv->adapter_ops; int ret = 0; - comp_dbg(dev, "module_adapter_cmd() %d start", cmd); + comp_dbg(dev, "%d start", cmd); switch (cmd) { case COMP_CMD_SET_DATA: @@ -307,12 +307,12 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s ret = interface->get_configuration(mod, 0, 0, (uint8_t *)cdata, 0); break; default: - comp_err(dev, "module_adapter_cmd() error: unknown command"); + comp_err(dev, "error: unknown command"); ret = -EINVAL; break; } - comp_dbg(dev, "module_adapter_cmd() done"); + comp_dbg(dev, "done"); return ret; } diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c index 2657e7e2a561..37184a5a5587 100644 --- a/src/audio/module_adapter/module_adapter_ipc4.c +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -25,19 +25,19 @@ LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); -static const struct ipc4_base_module_extended_cfg * -module_ext_init_decode(struct comp_dev *dev, struct module_config *dst, - const unsigned char *data, size_t *size) +int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init_data *ext_data, + struct ipc_config_process *spec) { const struct ipc4_module_init_ext_init *ext_init = - (const struct ipc4_module_init_ext_init *)data; + (const struct ipc4_module_init_ext_init *)spec->data; bool last_object = !ext_init->data_obj_array; const struct ipc4_module_init_ext_object *obj; - if (*size < sizeof(ext_init)) { - comp_err(dev, "Size too small for ext init %u < %u", - *size, sizeof(ext_init)); - return NULL; + assert(drv->type == SOF_COMP_MODULE_ADAPTER); + if (spec->size < sizeof(ext_init)) { + comp_cl_err(drv, "Size too small for ext init %zu < %zu", + spec->size, sizeof(ext_init)); + return -EINVAL; } /* TODO: Handle ext_init->gna_used and ext_init->rtos_domain here */ /* Get the first obj struct right after ext_init struct */ @@ -46,18 +46,18 @@ module_ext_init_decode(struct comp_dev *dev, struct module_config *dst, const struct ipc4_module_init_ext_object *next_obj; /* Check if there is space for the object header */ - if ((unsigned char *)(obj + 1) - data > *size) { - comp_err(dev, "ext init obj overflow, %u > %u", - (unsigned char *)(obj + 1) - data, *size); - return NULL; + if ((unsigned char *)(obj + 1) - spec->data > spec->size) { + comp_cl_err(drv, "ext init obj overflow, %u > %zu", + (unsigned char *)(obj + 1) - spec->data, spec->size); + return -EINVAL; } /* Calculate would be next object position and check if current object fits */ next_obj = (const struct ipc4_module_init_ext_object *) (((uint32_t *) (obj + 1)) + obj->object_words); - if ((unsigned char *)next_obj - data > *size) { - comp_err(dev, "ext init object array overflow, %u > %u", - (unsigned char *)obj - data, *size); - return NULL; + if ((unsigned char *)next_obj - spec->data > spec->size) { + comp_cl_err(drv, "ext init object array overflow, %u > %zu", + (unsigned char *)obj - spec->data, spec->size); + return -EINVAL; } switch (obj->object_id) { case IPC4_MOD_INIT_DATA_ID_DP_DATA: @@ -67,20 +67,34 @@ module_ext_init_decode(struct comp_dev *dev, struct module_config *dst, (const struct ipc4_module_init_ext_obj_dp_data *)(obj + 1); if (obj->object_words * sizeof(uint32_t) < sizeof(*dp_data)) { - comp_err(dev, "dp_data object too small %u < %u", - obj->object_words * sizeof(uint32_t), sizeof(*dp_data)); - return NULL; + comp_cl_warn(drv, "dp_data object too small %zu < %zu", + obj->object_words * sizeof(uint32_t), + sizeof(*dp_data)); + break; } - dst->domain_id = dp_data->domain_id; - dst->stack_bytes = dp_data->stack_bytes; - dst->heap_bytes = dp_data->heap_bytes; - comp_info(dev, "init_ext_obj_dp_data domain %u stack %u heap %u", - dp_data->domain_id, dp_data->stack_bytes, dp_data->heap_bytes); + ext_data->dp_data = dp_data; + comp_cl_info(drv, + "init_ext_obj_dp_data domain %u stack %u interim %u lifetime %u shared %u", + dp_data->domain_id, dp_data->stack_bytes, + dp_data->interim_heap_bytes, dp_data->lifetime_heap_bytes, + dp_data->shared_bytes); + break; + } + case IPC4_MOD_INIT_DATA_ID_MODULE_DATA: + { + /* + * set the module init_data. Modules must copy/save this in their init + * callbacks if they need this to be persistent + */ + ext_data->module_data = (const void *)(obj + 1); + ext_data->module_data_size = obj->object_words * sizeof(uint32_t); + comp_cl_info(drv, "module init data size %u bytes", + ext_data->module_data_size); break; } default: - comp_info(dev, "Unknown ext init object id %u of %u words", - obj->object_id, obj->object_words); + comp_cl_info(drv, "Unknown ext init object id %u of %u words", + obj->object_id, obj->object_words); } /* Read the last object flag from obj header */ last_object = obj->last_object; @@ -88,11 +102,11 @@ module_ext_init_decode(struct comp_dev *dev, struct module_config *dst, obj = next_obj; } - /* Remove decoded ext_init payload from the size */ - *size -= (unsigned char *) obj - data; + /* Remove decoded ext_init payload from spec */ + spec->size -= (unsigned char *)obj - spec->data; + spec->data = (const unsigned char *)obj; - /* return remaining payload */ - return (const struct ipc4_base_module_extended_cfg *)obj; + return 0; } /* @@ -114,10 +128,7 @@ int module_adapter_init_data(struct comp_dev *dev, size_t cfgsz = args->size; assert(dev->drv->type == SOF_COMP_MODULE_ADAPTER); - if (config->ipc_extended_init) - cfg = module_ext_init_decode(dev, dst, args->data, &cfgsz); - else - cfg = (const struct ipc4_base_module_extended_cfg *)args->data; + cfg = (const struct ipc4_base_module_extended_cfg *)args->data; if (cfg == NULL) return -EINVAL; @@ -136,9 +147,9 @@ int module_adapter_init_data(struct comp_dev *dev, if (cfgsz == (sizeof(*cfg) + pinsz)) { dst->nb_input_pins = n_in; dst->nb_output_pins = n_out; - dst->input_pins = module_driver_heap_rmalloc(dev->drv->user_heap, - SOF_MEM_FLAG_USER | - SOF_MEM_FLAG_COHERENT, pinsz); + dst->input_pins = sof_heap_alloc(dev->mod->priv.resources.heap, + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + pinsz, 0); if (!dst->input_pins) return -ENOMEM; @@ -148,8 +159,12 @@ int module_adapter_init_data(struct comp_dev *dev, } } - dst->init_data = cfg; /* legacy API */ - dst->avail = true; + if (!config->ipc_extended_init || + (!dst->ext_data->dp_data && !dst->ext_data->module_data)) { + dst->init_data = cfg; /* legacy API */ + dst->avail = true; + } + return 0; } @@ -212,7 +227,6 @@ int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ NULL, 0); return 0; } -EXPORT_SYMBOL(module_set_large_config); int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, bool last_block, uint32_t *data_offset_size, char *data) @@ -244,7 +258,6 @@ int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ */ return -EIO; } -EXPORT_SYMBOL(module_get_large_config); int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) { @@ -266,7 +279,6 @@ int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *valu return 0; } -EXPORT_SYMBOL(module_adapter_get_attribute); int module_adapter_set_attribute(struct comp_dev *dev, uint32_t type, void *value) { @@ -284,7 +296,6 @@ int module_adapter_set_attribute(struct comp_dev *dev, uint32_t type, void *valu return 0; } -EXPORT_SYMBOL(module_adapter_set_attribute); static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) { @@ -320,11 +331,47 @@ static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) return false; } +static int module_update_source_buffer_params(struct processing_module *mod, + struct bind_info *bind_data) +{ + struct module_config *dst = &mod->priv.cfg; + struct sof_ipc_stream_params params; + struct comp_buffer *buffer; + int dst_queue_id = bind_data->ipc4_data->extension.r.dst_queue; + + /* only update buffer params for sink components */ + if (bind_data->bind_type != COMP_BIND_TYPE_SOURCE) + return 0; + + comp_dev_for_each_producer(mod->dev, buffer) { + if (IPC4_SINK_QUEUE_ID(buffer->stream.runtime_stream_params.id) != dst_queue_id) + continue; + + /* use base_cfg params for pin 0 or if base config extn is missing */ + if (!dst_queue_id || dst_queue_id >= dst->nb_input_pins) { + buffer_set_params(buffer, mod->stream_params, BUFFER_UPDATE_FORCE); + return 0; + } + + /* otherwise use the respective input pin audio format */ + ipc4_audio_format_to_stream_params(&dst->input_pins[dst_queue_id].audio_fmt, + ¶ms); + buffer_set_params(buffer, ¶ms, BUFFER_UPDATE_FORCE); + return 0; + } + + return 0; +} + int module_adapter_bind(struct comp_dev *dev, struct bind_info *bind_data) { struct processing_module *mod = comp_mod(dev); int ret; + ret = module_update_source_buffer_params(mod, bind_data); + if (ret < 0) + return ret; + ret = module_bind(mod, bind_data); if (ret < 0) return ret; @@ -333,7 +380,6 @@ int module_adapter_bind(struct comp_dev *dev, struct bind_info *bind_data) return 0; } -EXPORT_SYMBOL(module_adapter_bind); int module_adapter_unbind(struct comp_dev *dev, struct bind_info *unbind_data) { @@ -348,7 +394,6 @@ int module_adapter_unbind(struct comp_dev *dev, struct bind_info *unbind_data) return 0; } -EXPORT_SYMBOL(module_adapter_unbind); uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no, bool input) @@ -364,7 +409,6 @@ uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, else return mod->total_data_consumed; } -EXPORT_SYMBOL(module_adapter_get_total_data_processed); int module_adapter_sink_src_prepare(struct comp_dev *dev) { diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index cca2850cfe12..51835ba37264 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -39,31 +39,31 @@ LOG_MODULE_REGISTER(multiband_drc, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(multiband_drc); -DECLARE_TR_CTX(multiband_drc_tr, SOF_UUID(multiband_drc_uuid), LOG_LEVEL_INFO); - /* Called from multiband_drc_setup() from multiband_drc_process(), so cannot be __cold */ -static void multiband_drc_reset_state(struct multiband_drc_state *state) +static void multiband_drc_reset_state(struct processing_module *mod, + struct multiband_drc_state *state) { int i; /* Reset emphasis eq-iir state */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - multiband_drc_iir_reset_state_ch(&state->emphasis[i]); + multiband_drc_iir_reset_state_ch(mod, &state->emphasis[i]); /* Reset crossover state */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - crossover_reset_state_ch(&state->crossover[i]); + crossover_reset_state_ch(mod, &state->crossover[i]); /* Reset drc kernel state */ for (i = 0; i < SOF_MULTIBAND_DRC_MAX_BANDS; i++) - drc_reset_state(&state->drc[i]); + drc_reset_state(mod, &state->drc[i]); /* Reset deemphasis eq-iir state */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - multiband_drc_iir_reset_state_ch(&state->deemphasis[i]); + multiband_drc_iir_reset_state_ch(mod, &state->deemphasis[i]); } -static int multiband_drc_eq_init_coef_ch(struct sof_eq_iir_biquad *coef, +static int multiband_drc_eq_init_coef_ch(struct processing_module *mod, + struct sof_eq_iir_biquad *coef, struct iir_state_df1 *eq) { int ret; @@ -72,8 +72,7 @@ static int multiband_drc_eq_init_coef_ch(struct sof_eq_iir_biquad *coef, if (SOF_EMP_DEEMP_BIQUADS != SOF_IIR_DF1_4TH_NUM_BIQUADS) return -EINVAL; - eq->coef = rzalloc(SOF_MEM_FLAG_USER, - sizeof(struct sof_eq_iir_biquad) * SOF_EMP_DEEMP_BIQUADS); + eq->coef = mod_zalloc(mod, sizeof(struct sof_eq_iir_biquad) * SOF_EMP_DEEMP_BIQUADS); if (!eq->coef) return -ENOMEM; @@ -86,8 +85,7 @@ static int multiband_drc_eq_init_coef_ch(struct sof_eq_iir_biquad *coef, * delay[0..1] -> state for first biquad * delay[2..3] -> state for second biquad */ - eq->delay = rzalloc(SOF_MEM_FLAG_USER, - sizeof(uint64_t) * CROSSOVER_NUM_DELAYS_LR4); + eq->delay = mod_zalloc(mod, sizeof(uint64_t) * CROSSOVER_NUM_DELAYS_LR4); if (!eq->delay) return -ENOMEM; @@ -110,7 +108,7 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u int i, ch, ret, num_bands; if (!config) { - comp_err(dev, "multiband_drc_init_coef(), no config is set"); + comp_err(dev, "no config is set"); return -EINVAL; } @@ -119,22 +117,22 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u /* Sanity checks */ if (nch > PLATFORM_MAX_CHANNELS) { comp_err(dev, - "multiband_drc_init_coef(), invalid channels count(%i)", nch); + "invalid channels count(%i)", nch); return -EINVAL; } if (config->num_bands > SOF_MULTIBAND_DRC_MAX_BANDS) { - comp_err(dev, "multiband_drc_init_coef(), invalid bands count(%i)", + comp_err(dev, "invalid bands count(%i)", config->num_bands); return -EINVAL; } - comp_info(dev, "multiband_drc_init_coef(), initializing %i-way crossover", + comp_info(dev, "initializing %i-way crossover", config->num_bands); /* Crossover: determine the split function */ cd->crossover_split = crossover_find_split_func(config->num_bands); if (!cd->crossover_split) { - comp_err(dev, "multiband_drc_init_coef(), No crossover_split for band count(%i)", + comp_err(dev, "No crossover_split for band count(%i)", config->num_bands); return -EINVAL; } @@ -142,39 +140,39 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u /* Crossover: collect the coef array and assign it to every channel */ crossover = config->crossover_coef; for (ch = 0; ch < nch; ch++) { - ret = crossover_init_coef_ch(crossover, &state->crossover[ch], + ret = crossover_init_coef_ch(mod, crossover, &state->crossover[ch], config->num_bands); /* Free all previously allocated blocks in case of an error */ if (ret < 0) { comp_err(dev, - "multiband_drc_init_coef(), could not assign coeffs to ch %d", ch); + "could not assign coeffs to ch %d", ch); goto err; } } - comp_info(dev, "multiband_drc_init_coef(), initializing emphasis_eq"); + comp_info(dev, "initializing emphasis_eq"); /* Emphasis: collect the coef array and assign it to every channel */ emphasis = config->emp_coef; for (ch = 0; ch < nch; ch++) { - ret = multiband_drc_eq_init_coef_ch(emphasis, &state->emphasis[ch]); + ret = multiband_drc_eq_init_coef_ch(mod, emphasis, &state->emphasis[ch]); /* Free all previously allocated blocks in case of an error */ if (ret < 0) { - comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d", + comp_err(dev, "could not assign coeffs to ch %d", ch); goto err; } } - comp_info(dev, "multiband_drc_init_coef(), initializing deemphasis_eq"); + comp_info(dev, "initializing deemphasis_eq"); /* Deemphasis: collect the coef array and assign it to every channel */ deemphasis = config->deemp_coef; for (ch = 0; ch < nch; ch++) { - ret = multiband_drc_eq_init_coef_ch(deemphasis, &state->deemphasis[ch]); + ret = multiband_drc_eq_init_coef_ch(mod, deemphasis, &state->deemphasis[ch]); /* Free all previously allocated blocks in case of an error */ if (ret < 0) { - comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d", + comp_err(dev, "could not assign coeffs to ch %d", ch); goto err; } @@ -182,19 +180,20 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u /* Allocate all DRC pre-delay buffers and set delay time with band number */ for (i = 0; i < num_bands; i++) { - comp_info(dev, "multiband_drc_init_coef(), initializing drc band %d", i); + comp_info(dev, "initializing drc band %d", i); - ret = drc_init_pre_delay_buffers(&state->drc[i], (size_t)sample_bytes, (int)nch); + ret = drc_init_pre_delay_buffers(mod, &state->drc[i], + (size_t)sample_bytes, (int)nch); if (ret < 0) { comp_err(dev, - "multiband_drc_init_coef(), could not init pre delay buffers"); + "could not init pre delay buffers"); goto err; } ret = drc_set_pre_delay_time(&state->drc[i], cd->config->drc_coef[i].pre_delay_time, rate); if (ret < 0) { - comp_err(dev, "multiband_drc_init_coef(), could not set pre delay time"); + comp_err(dev, "could not set pre delay time"); goto err; } } @@ -202,7 +201,7 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u return 0; err: - multiband_drc_reset_state(state); + multiband_drc_reset_state(mod, state); return ret; } @@ -213,7 +212,7 @@ static int multiband_drc_setup(struct processing_module *mod, int16_t channels, struct multiband_drc_comp_data *cd = module_get_private_data(mod); /* Reset any previous state */ - multiband_drc_reset_state(&cd->state); + multiband_drc_reset_state(mod, &cd->state); /* Setup Crossover, Emphasis EQ, Deemphasis EQ, and DRC */ return multiband_drc_init_coef(mod, channels, rate); @@ -232,18 +231,18 @@ static int multiband_drc_init(struct processing_module *mod) size_t bs = cfg->size; int ret; - comp_info(dev, "multiband_drc_init()"); + comp_info(dev, "entry"); /* Check first before proceeding with dev and cd that coefficients * blob size is sane. */ if (bs > SOF_MULTIBAND_DRC_MAX_BLOB_SIZE) { - comp_err(dev, "multiband_drc_init(), error: configuration blob size = %u > %d", + comp_err(dev, "error: configuration blob size = %u > %d", bs, SOF_MULTIBAND_DRC_MAX_BLOB_SIZE); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -258,7 +257,7 @@ static int multiband_drc_init(struct processing_module *mod) multiband_drc_process_enable(&cd->process_enabled); /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { comp_err(dev, "comp_data_blob_handler_new() failed."); ret = -ENOMEM; @@ -271,13 +270,13 @@ static int multiband_drc_init(struct processing_module *mod) comp_err(dev, "comp_init_data_blob() failed."); goto cd_fail; } - multiband_drc_reset_state(&cd->state); + multiband_drc_reset_state(mod, &cd->state); return 0; cd_fail: - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -287,11 +286,11 @@ __cold static int multiband_drc_free(struct processing_module *mod) assert_can_be_cold(); - comp_info(mod->dev, "multiband_drc_free()"); + comp_info(mod->dev, "entry"); - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -305,7 +304,7 @@ __cold static int multiband_drc_set_config(struct processing_module *mod, uint32 assert_can_be_cold(); - comp_dbg(dev, "multiband_drc_set_config()"); + comp_dbg(dev, "entry"); return multiband_drc_set_ipc_config(mod, param_id, fragment, pos, data_offset_size, fragment_size); @@ -319,7 +318,7 @@ __cold static int multiband_drc_get_config(struct processing_module *mod, assert_can_be_cold(); - comp_dbg(mod->dev, "multiband_drc_get_config()"); + comp_dbg(mod->dev, "entry"); return multiband_drc_get_ipc_config(mod, cdata, fragment_size); } @@ -336,7 +335,7 @@ static int multiband_drc_process(struct processing_module *mod, int frames = input_buffers[0].size; int ret; - comp_dbg(dev, "multiband_drc_process()"); + comp_dbg(dev, "entry"); /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { @@ -344,7 +343,7 @@ static int multiband_drc_process(struct processing_module *mod, ret = multiband_drc_setup(mod, (int16_t)audio_stream_get_channels(sink), audio_stream_get_rate(sink)); if (ret < 0) { - comp_err(dev, "multiband_drc_process(), failed DRC setup"); + comp_err(dev, "failed DRC setup"); return ret; } } @@ -370,7 +369,7 @@ static int multiband_drc_prepare(struct processing_module *mod, int rate; int ret = 0; - comp_info(dev, "multiband_drc_prepare()"); + comp_info(dev, "entry"); ret = multiband_drc_params(mod); if (ret < 0) @@ -389,20 +388,20 @@ static int multiband_drc_prepare(struct processing_module *mod, rate = audio_stream_get_rate(&sourceb->stream); /* Initialize DRC */ - comp_dbg(dev, "multiband_drc_prepare(), source_format=%d, sink_format=%d", + comp_dbg(dev, "source_format=%d, sink_format=%d", cd->source_format, cd->source_format); cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); if (cd->config) { ret = multiband_drc_setup(mod, channels, rate); if (ret < 0) { - comp_err(dev, "multiband_drc_prepare() error: multiband_drc_setup failed."); + comp_err(dev, "error: multiband_drc_setup failed."); return ret; } } cd->multiband_drc_func = multiband_drc_find_proc_func(cd->source_format); if (!cd->multiband_drc_func) { - comp_err(dev, "multiband_drc_prepare(), No proc func"); + comp_err(dev, "No proc func"); return -EINVAL; } @@ -413,9 +412,9 @@ static int multiband_drc_reset(struct processing_module *mod) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "multiband_drc_reset()"); + comp_info(mod->dev, "entry"); - multiband_drc_reset_state(&cd->state); + multiband_drc_reset_state(mod, &cd->state); cd->source_format = 0; cd->multiband_drc_func = NULL; @@ -449,6 +448,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(multiband_drc_tr, SOF_UUID(multiband_drc_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(multiband_drc_interface, multiband_drc_uuid, multiband_drc_tr); SOF_MODULE_INIT(multiband_drc, sys_comp_module_multiband_drc_interface_init); diff --git a/src/audio/multiband_drc/multiband_drc.h b/src/audio/multiband_drc/multiband_drc.h index 20f939877209..6a99fda55cef 100644 --- a/src/audio/multiband_drc/multiband_drc.h +++ b/src/audio/multiband_drc/multiband_drc.h @@ -89,10 +89,11 @@ static inline multiband_drc_func multiband_drc_find_proc_func_pass(enum sof_ipc_ return NULL; } -static inline void multiband_drc_iir_reset_state_ch(struct iir_state_df1 *iir) +static inline void multiband_drc_iir_reset_state_ch(struct processing_module *mod, + struct iir_state_df1 *iir) { - rfree(iir->coef); - rfree(iir->delay); + mod_free(mod, iir->coef); + mod_free(mod, iir->delay); iir->coef = NULL; iir->delay = NULL; diff --git a/src/audio/multiband_drc/multiband_drc_ipc3.c b/src/audio/multiband_drc/multiband_drc_ipc3.c index fdc9de9e5ba9..04aa4fc33e40 100644 --- a/src/audio/multiband_drc/multiband_drc_ipc3.c +++ b/src/audio/multiband_drc/multiband_drc_ipc3.c @@ -30,10 +30,10 @@ static int multiband_drc_cmd_set_value(struct processing_module *mod, switch (cdata->cmd) { case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "multiband_drc_multiband_drc_cmd_set_value(), SOF_CTRL_CMD_SWITCH"); + comp_dbg(dev, "multiband_drc_SOF_CTRL_CMD_SWITCH"); if (cdata->num_elems == 1) { cd->process_enabled = cdata->chanv[0].value; - comp_info(dev, "multiband_drc_cmd_set_value(), process_enabled = %d", + comp_info(dev, "process_enabled = %d", cd->process_enabled); return 0; } @@ -68,13 +68,13 @@ static int multiband_drc_cmd_get_value(struct processing_module *mod, switch (cdata->cmd) { case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "multiband_drc_cmd_get_value(), SOF_CTRL_CMD_SWITCH"); + comp_dbg(dev, "SOF_CTRL_CMD_SWITCH"); for (j = 0; j < cdata->num_elems; j++) cdata->chanv[j].value = cd->process_enabled; if (cdata->num_elems == 1) return 0; - comp_warn(dev, "multiband_drc_cmd_get_value() warn: num_elems should be 1, got %d", + comp_warn(dev, "warn: num_elems should be 1, got %d", cdata->num_elems); return 0; } @@ -91,7 +91,7 @@ int multiband_drc_get_ipc_config(struct processing_module *mod, struct sof_ipc_c if (cdata->cmd != SOF_CTRL_CMD_BINARY) return multiband_drc_cmd_get_value(mod, cdata); - comp_dbg(mod->dev, "multiband_drc_get_ipc_config(), SOF_CTRL_CMD_BINARY"); + comp_dbg(mod->dev, "SOF_CTRL_CMD_BINARY"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } diff --git a/src/audio/multiband_drc/multiband_drc_ipc4.c b/src/audio/multiband_drc/multiband_drc_ipc4.c index 03d7e6c5a074..ac2a7a7426aa 100644 --- a/src/audio/multiband_drc/multiband_drc_ipc4.c +++ b/src/audio/multiband_drc/multiband_drc_ipc4.c @@ -54,11 +54,11 @@ __cold int multiband_drc_set_ipc_config(struct processing_module *mod, uint32_t return 0; case SOF_IPC4_ENUM_CONTROL_PARAM_ID: - comp_err(dev, "multiband_drc_set_ipc_config(), illegal control."); + comp_err(dev, "illegal control."); return -EINVAL; } - comp_dbg(mod->dev, "multiband_drc_set_ipc_config(), SOF_CTRL_CMD_BINARY"); + comp_dbg(mod->dev, "SOF_CTRL_CMD_BINARY"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); } @@ -68,7 +68,7 @@ __cold int multiband_drc_get_ipc_config(struct processing_module *mod, { struct multiband_drc_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "multiband_drc_get_ipc_config(), SOF_CTRL_CMD_BINARY"); + comp_dbg(mod->dev, "SOF_CTRL_CMD_BINARY"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -82,7 +82,7 @@ int multiband_drc_params(struct processing_module *mod) enum sof_ipc_frame valid_fmt, frame_fmt; int i; - comp_dbg(dev, "multiband_drc_params()"); + comp_dbg(dev, "entry"); comp_params = *params; comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index bbcf1b544e90..3dc844c8ef7e 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -94,14 +93,13 @@ static int mux_demux_common_init(struct processing_module *mod, enum sof_comp_ty return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, - sizeof(*cd) + MUX_BLOB_STREAMS_SIZE); + cd = mod_zalloc(mod, sizeof(*cd) + MUX_BLOB_STREAMS_SIZE); if (!cd) return -ENOMEM; - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto err; } @@ -109,7 +107,7 @@ static int mux_demux_common_init(struct processing_module *mod, enum sof_comp_ty module_data->private = cd; ret = comp_init_data_blob(cd->model_handler, cfg->size, cfg->init_data); if (ret < 0) { - comp_err(dev, "comp_init_data_blob() failed."); + comp_err(dev, "module data blob initialization failed."); goto err_init; } @@ -119,10 +117,10 @@ static int mux_demux_common_init(struct processing_module *mod, enum sof_comp_ty return 0; err_init: - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); err: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -137,10 +135,10 @@ static int mux_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "mux_free()"); + comp_dbg(mod->dev, "entry"); - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return 0; } @@ -240,7 +238,7 @@ static int demux_process(struct processing_module *mod, int source_bytes; int i; - comp_dbg(dev, "demux_process()"); + comp_dbg(dev, "entry"); /* align sink streams with their respective configurations */ comp_dev_for_each_consumer(dev, sink) { @@ -317,7 +315,7 @@ static int mux_process(struct processing_module *mod, int source_bytes; int i, j; - comp_dbg(dev, "mux_process()"); + comp_dbg(dev, "entry"); /* align source streams with their respective configurations */ j = 0; @@ -368,7 +366,7 @@ static int mux_reset(struct processing_module *mod) struct comp_dev *dev = mod->dev; int dir = dev->pipeline->source_comp->direction; - comp_dbg(dev, "mux_reset()"); + comp_dbg(dev, "entry"); if (dir == SOF_IPC_STREAM_PLAYBACK) { comp_dev_for_each_producer(dev, source) { @@ -392,19 +390,9 @@ static int mux_prepare(struct processing_module *mod, { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); - struct sof_mux_config *config; - size_t blob_size; int ret; - comp_dbg(dev, "mux_prepare()"); - - config = comp_get_data_blob(cd->model_handler, &blob_size, NULL); - if (blob_size > MUX_BLOB_MAX_SIZE) { - comp_err(dev, "illegal blob size %zu", blob_size); - return -EINVAL; - } - - memcpy_s(&cd->config, MUX_BLOB_MAX_SIZE, config, blob_size); + comp_dbg(dev, "entry"); ret = mux_params(mod); if (ret < 0) @@ -431,7 +419,7 @@ static int mux_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "mux_get_config()"); + comp_dbg(mod->dev, "entry"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -443,7 +431,7 @@ static int mux_set_config(struct processing_module *mod, uint32_t config_id, { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "mux_set_config()"); + comp_dbg(mod->dev, "entry"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); diff --git a/src/audio/mux/mux.h b/src/audio/mux/mux.h index 526d70ecb870..0fb11d8300b5 100644 --- a/src/audio/mux/mux.h +++ b/src/audio/mux/mux.h @@ -213,7 +213,11 @@ void sys_comp_module_demux_interface_init(void); #endif /* UNIT_TEST */ #define MUX_BLOB_STREAMS_SIZE (MUX_MAX_STREAMS * sizeof(struct mux_stream_data)) +#ifdef CONFIG_IPC_MAJOR_4 +#define MUX_BLOB_MAX_SIZE (sizeof(struct mux_data)) +#else #define MUX_BLOB_MAX_SIZE (sizeof(struct sof_mux_config) + MUX_BLOB_STREAMS_SIZE) +#endif extern const struct sof_uuid demux_uuid; extern struct tr_ctx mux_tr; diff --git a/src/audio/mux/mux_generic.c b/src/audio/mux/mux_generic.c index 991b79097fec..20d21afdffb1 100644 --- a/src/audio/mux/mux_generic.c +++ b/src/audio/mux/mux_generic.c @@ -171,7 +171,7 @@ static void demux_s16le(struct comp_dev *dev, struct audio_stream *sink, uint32_t elem; uint32_t frames_without_wrap; - comp_dbg(dev, "demux_s16le()"); + comp_dbg(dev, "entry"); if (!lookup || !lookup->num_elems) return; @@ -224,7 +224,7 @@ static void mux_s16le(struct comp_dev *dev, struct audio_stream *sink, uint32_t elem; uint32_t frames_without_wrap; - comp_dbg(dev, "mux_s16le()"); + comp_dbg(dev, "entry"); if (!lookup || !lookup->num_elems) return; @@ -371,7 +371,7 @@ static void demux_s32le(struct comp_dev *dev, struct audio_stream *sink, uint32_t elem; uint32_t frames_without_wrap; - comp_dbg(dev, "demux_s32le"); + comp_dbg(dev, "entry"); if (!lookup || !lookup->num_elems) return; @@ -424,7 +424,7 @@ static void mux_s32le(struct comp_dev *dev, struct audio_stream *sink, uint32_t elem; uint32_t frames_without_wrap; - comp_dbg(dev, "mux_s32le()"); + comp_dbg(dev, "entry"); if (!lookup || !lookup->num_elems) return; diff --git a/src/audio/mux/mux_ipc3.c b/src/audio/mux/mux_ipc3.c index 4a39dd277012..fb00030b5814 100644 --- a/src/audio/mux/mux_ipc3.c +++ b/src/audio/mux/mux_ipc3.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -38,7 +39,7 @@ static int mux_set_values(struct processing_module *mod) unsigned int i; unsigned int j; - comp_dbg(dev, "mux_set_values()"); + comp_dbg(dev, "entry"); /* check if number of streams configured doesn't exceed maximum */ if (cfg->num_streams > MUX_MAX_STREAMS) { @@ -98,6 +99,18 @@ static int mux_set_values(struct processing_module *mod) int mux_params(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + struct sof_mux_config *config; + size_t blob_size; + + config = comp_get_data_blob(cd->model_handler, &blob_size, NULL); + if (blob_size > MUX_BLOB_MAX_SIZE) { + comp_err(mod->dev, "illegal blob size %zu", blob_size); + return -EINVAL; + } + + memcpy_s(&cd->config, MUX_BLOB_MAX_SIZE, config, blob_size); + return mux_set_values(mod); } #endif /* CONFIG_COMP_MUX */ diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index 9d844ac15efa..dc6877059f57 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ SOF_DEFINE_REG_UUID(demux); DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO); -static int build_config(struct processing_module *mod) +static int build_config(struct processing_module *mod, struct mux_data *cfg) { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); @@ -45,12 +46,12 @@ static int build_config(struct processing_module *mod) memset(cd->config.streams[i].mask, 0, sizeof(cd->config.streams[i].mask)); /* Setting masks for streams */ - for (i = 0; i < cd->md.base_cfg.audio_fmt.channels_count; i++) { + for (i = 0; i < cfg->base_cfg.audio_fmt.channels_count; i++) { cd->config.streams[0].mask[i] = mask; mask <<= 1; } - for (i = 0; i < cd->md.reference_format.channels_count; i++) { + for (i = 0; i < cfg->reference_format.channels_count; i++) { cd->config.streams[1].mask[i] = mask; mask <<= 1; } @@ -67,7 +68,7 @@ static int build_config(struct processing_module *mod) * set up param then verify param. BTW for IPC3 path, the param is sent by * host driver. */ -static void set_mux_params(struct processing_module *mod) +static void set_mux_params(struct processing_module *mod, struct mux_data *cfg) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); @@ -76,12 +77,12 @@ static void set_mux_params(struct processing_module *mod) int j; params->direction = dev->direction; - params->channels = cd->md.base_cfg.audio_fmt.channels_count; - params->rate = cd->md.base_cfg.audio_fmt.sampling_frequency; - params->sample_container_bytes = cd->md.base_cfg.audio_fmt.depth / 8; - params->sample_valid_bytes = cd->md.base_cfg.audio_fmt.valid_bit_depth / 8; - params->buffer_fmt = cd->md.base_cfg.audio_fmt.interleaving_style; - params->buffer.size = cd->md.base_cfg.ibs; + params->channels = cfg->base_cfg.audio_fmt.channels_count; + params->rate = cfg->base_cfg.audio_fmt.sampling_frequency; + params->sample_container_bytes = cfg->base_cfg.audio_fmt.depth / 8; + params->sample_valid_bytes = cfg->base_cfg.audio_fmt.valid_bit_depth / 8; + params->buffer_fmt = cfg->base_cfg.audio_fmt.interleaving_style; + params->buffer.size = cfg->base_cfg.ibs; params->no_stream_position = 1; /* There are two input pins and one output pin in the mux. @@ -95,7 +96,7 @@ static void set_mux_params(struct processing_module *mod) sink = comp_dev_get_first_data_consumer(dev); if (!audio_buffer_hw_params_configured(&sink->audio_buffer)) { - ipc4_update_buffer_format(sink, &cd->md.output_format); + ipc4_update_buffer_format(sink, &cfg->output_format); params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream); } } @@ -105,12 +106,12 @@ static void set_mux_params(struct processing_module *mod) struct ipc4_audio_format *audio_fmt; comp_dev_for_each_producer(dev, source) { - j = buf_get_id(source); + j = IPC4_SINK_QUEUE_ID(buf_get_id(source)); cd->config.streams[j].pipeline_id = buffer_pipeline_id(source); if (j == BASE_CFG_QUEUED_ID) - audio_fmt = &cd->md.base_cfg.audio_fmt; + audio_fmt = &cfg->base_cfg.audio_fmt; else - audio_fmt = &cd->md.reference_format; + audio_fmt = &cfg->reference_format; ipc4_update_buffer_format(source, audio_fmt); } @@ -121,13 +122,22 @@ static void set_mux_params(struct processing_module *mod) int mux_params(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + struct mux_data *cfg; + size_t blob_size; int ret; - ret = build_config(mod); + cfg = comp_get_data_blob(cd->model_handler, &blob_size, NULL); + if (!cfg || blob_size > MUX_BLOB_MAX_SIZE) { + comp_err(mod->dev, "illegal blob size %zu", blob_size); + return -EINVAL; + } + + ret = build_config(mod, cfg); if (ret < 0) return ret; - set_mux_params(mod); + set_mux_params(mod, cfg); return ret; } diff --git a/src/audio/nxp/eap.c b/src/audio/nxp/eap.c index 4e6e2c5eb535..3e596a5cf85d 100644 --- a/src/audio/nxp/eap.c +++ b/src/audio/nxp/eap.c @@ -5,7 +5,6 @@ // Author: Daniel Baluta #include -#include #include #include #include @@ -93,9 +92,9 @@ static int nxp_eap_init(struct processing_module *mod) tr_info(mod->dev, "NXP EAP library, platform: %s version:%s", info.pPlatform, info.pVersionNumber); - eap = rballoc(SOF_MEM_FLAG_USER, sizeof(*eap)); + eap = mod_alloc(mod, sizeof(*eap)); if (!eap) { - comp_err(dev, "nxp_eap_init() failed to allocate module private data"); + comp_err(dev, "failed to allocate module private data"); return -ENOMEM; } @@ -105,8 +104,8 @@ static int nxp_eap_init(struct processing_module *mod) lvm_ret = LVM_GetMemoryTable(LVM_NULL, &eap->mem_tab, &eap->inst_params); if (lvm_ret != LVM_SUCCESS) { - comp_err(dev, "nxp_eap_init() failed to get memory table %d", lvm_ret); - rfree(eap); + comp_err(dev, "failed to get memory table %d", lvm_ret); + mod_free(mod, eap); return -EINVAL; } @@ -115,10 +114,9 @@ static int nxp_eap_init(struct processing_module *mod) eap->mem_tab.Region[i].pBaseAddress = NULL; for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) { - eap->mem_tab.Region[i].pBaseAddress = rballoc(SOF_MEM_FLAG_USER, - eap->mem_tab.Region[i].Size); + eap->mem_tab.Region[i].pBaseAddress = mod_balloc(mod, eap->mem_tab.Region[i].Size); if (!eap->mem_tab.Region[i].pBaseAddress) { - comp_err(dev, "nxp_eap_init() failed to allocate memory for region %d", i); + comp_err(dev, "failed to allocate memory for region %d", i); ret = -ENOMEM; goto free_mem; } @@ -126,7 +124,7 @@ static int nxp_eap_init(struct processing_module *mod) lvm_ret = LVM_GetInstanceHandle(&eap->instance, &eap->mem_tab, &eap->inst_params); if (lvm_ret != LVM_SUCCESS) { - comp_err(dev, "nxp_eap_init() failed to get instance handle err: %d", lvm_ret); + comp_err(dev, "failed to get instance handle err: %d", lvm_ret); ret = -EINVAL; goto free_mem; } @@ -139,11 +137,11 @@ static int nxp_eap_init(struct processing_module *mod) free_mem: for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) { if (eap->mem_tab.Region[i].pBaseAddress) { - rfree(eap->mem_tab.Region[i].pBaseAddress); + mod_free(mod, eap->mem_tab.Region[i].pBaseAddress); eap->mem_tab.Region[i].pBaseAddress = NULL; } } - rfree(eap); + mod_free(mod, eap); return ret; } @@ -152,16 +150,15 @@ static int nxp_eap_free(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct nxp_eap_data *eap = module_get_private_data(mod); - comp_dbg(dev, "nxp_eap_free()"); + comp_dbg(dev, "entry"); for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) { if (eap->mem_tab.Region[i].pBaseAddress) { - rfree(eap->mem_tab.Region[i].pBaseAddress); + mod_free(mod, eap->mem_tab.Region[i].pBaseAddress); eap->mem_tab.Region[i].pBaseAddress = NULL; } } - - rfree(eap); + mod_free(mod, eap); return 0; } @@ -176,7 +173,7 @@ static int nxp_eap_prepare(struct processing_module *mod, struct comp_buffer *source = comp_dev_get_first_data_producer(dev); const struct audio_stream *stream; - comp_dbg(dev, "nxp_eap_prepare()"); + comp_dbg(dev, "entry"); stream = &source->stream; eap->sample_rate = audio_stream_get_rate(stream); @@ -189,13 +186,13 @@ static int nxp_eap_prepare(struct processing_module *mod, */ eap->buffer_bytes = NXP_EAP_DEFAULT_MAX_BLOCK_SIZE; - md->mpd.in_buff = rballoc_align(SOF_MEM_FLAG_USER, eap->buffer_bytes, 32); + md->mpd.in_buff = mod_balloc_align(mod, eap->buffer_bytes, 32); if (!md->mpd.in_buff) return -ENOMEM; - md->mpd.out_buff = rballoc_align(SOF_MEM_FLAG_USER, eap->buffer_bytes, 32); + md->mpd.out_buff = mod_balloc_align(mod, eap->buffer_bytes, 32); if (!md->mpd.out_buff) { - rfree(md->mpd.in_buff); + mod_free(mod, md->mpd.in_buff); return -ENOMEM; } @@ -210,16 +207,16 @@ static int nxp_eap_reset(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct module_data *md = &mod->priv; - comp_dbg(dev, "nxp_eap_reset"); + comp_dbg(dev, "entry"); if (md->mpd.in_buff) { - rfree(md->mpd.in_buff); + mod_free(mod, md->mpd.in_buff); md->mpd.in_buff = NULL; md->mpd.in_buff_size = 0; } if (md->mpd.out_buff) { - rfree(md->mpd.out_buff); + mod_free(mod, md->mpd.out_buff); md->mpd.out_buff = NULL; md->mpd.out_buff_size = 0; } @@ -237,7 +234,7 @@ static int nxp_eap_process(struct processing_module *mod, LVM_INT16 *buffer_table[2]; LVM_ReturnStatus_en ret; - comp_dbg(dev, "nxp_eap_process()"); + comp_dbg(dev, "entry"); /* we need to input buffer to be completely full to be able to process it */ if (input_buffers[0].size < eap->mpd.in_buff_size) @@ -257,7 +254,7 @@ static int nxp_eap_process(struct processing_module *mod, (LVM_INT16 **)buffer_table, eap->mpd.avail / eap_data->frame_bytes, eap_data->audio_time_ms); if (ret != LVM_SUCCESS) { - comp_err(dev, "nxp_eap_process() failed with error %d", ret); + comp_err(dev, "failed with error %d", ret); return -EIO; } @@ -283,7 +280,7 @@ static int nxp_eap_cmd_set_value(struct processing_module *mod, struct sof_ipc_c index = cdata->chanv[0].value; if (index >= ARRAY_SIZE(nxp_eap_effect_presets)) { - comp_info(dev, "nxp_eap_cmd_set_value() invalid index (%d), config not changed", + comp_info(dev, "invalid index (%d), config not changed", index); } else { memcpy(&eap->ctrl_params, nxp_eap_effect_presets[index].params, @@ -307,7 +304,7 @@ static int nxp_eap_set_config(struct processing_module *mod, uint32_t param_id, struct comp_dev *dev = mod->dev; struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; - comp_dbg(dev, "nxp_eap_set_config()"); + comp_dbg(dev, "entry"); if (cdata->cmd != SOF_CTRL_CMD_BINARY) return nxp_eap_cmd_set_value(mod, cdata); @@ -322,7 +319,7 @@ static int nxp_eap_get_config(struct processing_module *mod, { struct comp_dev *dev = mod->dev; - comp_dbg(dev, "nxp_eap_get_config()"); + comp_dbg(dev, "entry"); return 0; } diff --git a/src/audio/pipeline/pipeline-graph.c b/src/audio/pipeline/pipeline-graph.c index 678b8095289f..89bb3574289b 100644 --- a/src/audio/pipeline/pipeline-graph.c +++ b/src/audio/pipeline/pipeline-graph.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,8 @@ void pipeline_posn_init(struct sof *sof) } /* create new pipeline - returns pipeline id or negative error */ -struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t comp_id) +struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority, + uint32_t comp_id, struct create_pipeline_params *pparams) { struct sof_ipc_stream_posn posn; struct pipeline *p; @@ -121,13 +123,16 @@ struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t heap_trace_all(0); /* allocate new pipeline */ - p = rzalloc(SOF_MEM_FLAG_USER, sizeof(*p)); + p = sof_heap_alloc(heap, SOF_MEM_FLAG_USER, sizeof(*p), 0); if (!p) { pipe_cl_err("Out of Memory"); return NULL; } + memset(p, 0, sizeof(*p)); + /* init pipeline */ + p->heap = heap; p->comp_id = comp_id; p->priority = priority; p->pipeline_id = pipeline_id; @@ -160,7 +165,7 @@ struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t return p; free: - rfree(p); + sof_heap_free(heap, p); return NULL; } @@ -217,7 +222,7 @@ void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int /* pipelines must be inactive */ int pipeline_free(struct pipeline *p) { - pipe_dbg(p, "pipeline_free()"); + pipe_dbg(p, "entry"); /* * pipeline_free should always be called only after all the widgets in the pipeline have @@ -229,7 +234,7 @@ int pipeline_free(struct pipeline *p) #if !CONFIG_LIBRARY || UNIT_TEST schedule_task_free(p->pipe_task); #endif - rfree(p->pipe_task); + sof_heap_free(p->heap, p->pipe_task); } ipc_msg_free(p->msg); @@ -237,7 +242,7 @@ int pipeline_free(struct pipeline *p) pipeline_posn_offset_put(p->posn_offset); /* now free the pipeline */ - rfree(p); + sof_heap_free(p->heap, p); /* show heap status */ heap_trace_all(0); @@ -251,11 +256,11 @@ static int pipeline_comp_complete(struct comp_dev *current, { struct pipeline_data *ppl_data = ctx->comp_data; - pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(ppl_data->p, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); if (!comp_is_single_pipeline(current, ppl_data->start)) { - pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current is from another pipeline"); + pipe_dbg(ppl_data->p, "current is from another pipeline"); return 0; } @@ -326,7 +331,7 @@ static int pipeline_comp_reset(struct comp_dev *current, int is_single_ppl; int err; - pipe_dbg(p_current, "pipeline_comp_reset(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(p_current, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); if (!p->source_comp) { diff --git a/src/audio/pipeline/pipeline-params.c b/src/audio/pipeline/pipeline-params.c index f2aa30b978c1..16273e0897d4 100644 --- a/src/audio/pipeline/pipeline-params.c +++ b/src/audio/pipeline/pipeline-params.c @@ -31,7 +31,7 @@ static int pipeline_comp_params_neg(struct comp_dev *current, struct pipeline_data *ppl_data = ctx->comp_data; int err = 0; - pipe_dbg(current->pipeline, "pipeline_comp_params_neg(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(current->pipeline, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); /* check if 'current' is already configured */ @@ -81,7 +81,7 @@ static int pipeline_comp_params(struct comp_dev *current, int stream_direction = ppl_data->params->params.direction; int err; - pipe_dbg(current->pipeline, "pipeline_comp_params(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(current->pipeline, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); /* Don't propagate to pipelines in the opposite direction */ @@ -131,7 +131,7 @@ static int pipeline_comp_hw_params(struct comp_dev *current, struct pipeline_data *ppl_data = ctx->comp_data; int ret; - pipe_dbg(current->pipeline, "pipeline_comp_hw_params(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(current->pipeline, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); ret = pipeline_for_each_comp(current, ctx, dir); @@ -262,7 +262,7 @@ static int pipeline_comp_prepare(struct comp_dev *current, struct pipeline_data *ppl_data = ctx->comp_data; int err; - pipe_dbg(current->pipeline, "pipeline_comp_prepare(), current->comp.id = 0x%x, dir = %u", + pipe_dbg(current->pipeline, "current->comp.id = 0x%x, dir = %u", dev_comp_id(current), dir); if (!comp_is_single_pipeline(current, ppl_data->start)) { diff --git a/src/audio/pipeline/pipeline-schedule.c b/src/audio/pipeline/pipeline-schedule.c index a13e95982ccc..45fd1eed639c 100644 --- a/src/audio/pipeline/pipeline-schedule.c +++ b/src/audio/pipeline/pipeline-schedule.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -167,7 +168,7 @@ static enum task_state pipeline_task(void *arg) struct pipeline *p = arg; int err; - pipe_dbg(p, "pipeline_task()"); + pipe_dbg(p, "entry"); /* are we in xrun ? */ if (p->xrun_bytes) { @@ -232,7 +233,7 @@ static enum task_state pipeline_task(void *arg) } } - pipe_dbg(p, "pipeline_task() sched"); + pipe_dbg(p, "sched"); return SOF_TASK_STATE_RESCHEDULE; } @@ -241,15 +242,17 @@ static struct task *pipeline_task_init(struct pipeline *p, uint32_t type) { struct pipeline_task *task = NULL; - task = rzalloc(SOF_MEM_FLAG_USER, - sizeof(*task)); + task = sof_heap_alloc(p->heap, SOF_MEM_FLAG_USER, + sizeof(*task), 0); if (!task) return NULL; + memset(task, 0, sizeof(*task)); + if (schedule_task_init_ll(&task->task, SOF_UUID(pipe_task_uuid), type, p->priority, pipeline_task, p, p->core, 0) < 0) { - rfree(task); + sof_heap_free(p->heap, task); return NULL; } @@ -383,7 +386,6 @@ static enum task_state dp_task_run(void *data) int pipeline_comp_dp_task_init(struct comp_dev *comp) { - int ret; /* DP tasks are guaranteed to have a module_adapter */ struct processing_module *mod = comp_mod(comp); struct task_ops ops = { @@ -392,22 +394,17 @@ int pipeline_comp_dp_task_init(struct comp_dev *comp) .complete = NULL }; - if (!comp->task) { - ret = scheduler_dp_task_init(&comp->task, - SOF_UUID(dp_task_uuid), - &ops, - mod, - comp->ipc_config.core, - TASK_DP_STACK_SIZE, -#if CONFIG_USERSPACE - mod->user_ctx ? K_USER : -#endif /* CONFIG_USERSPACE */ - 0); - if (ret < 0) - return ret; - } + if (comp->task) + return 0; - return 0; +#if CONFIG_SOF_USERSPACE_PROXY + unsigned int flags = mod->user_ctx ? K_USER : 0; +#else + unsigned int flags = IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0; +#endif + + return scheduler_dp_task_init(&comp->task, SOF_UUID(dp_task_uuid), &ops, mod, + comp->ipc_config.core, TASK_DP_STACK_SIZE, flags); } #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ diff --git a/src/audio/pipeline/pipeline-stream.c b/src/audio/pipeline/pipeline-stream.c index 6ababd12d838..0b38574610de 100644 --- a/src/audio/pipeline/pipeline-stream.c +++ b/src/audio/pipeline/pipeline-stream.c @@ -115,17 +115,17 @@ static int pipeline_comp_copy(struct comp_dev *current, bool is_single_ppl = comp_is_single_pipeline(current, ppl_data->start); int err; - pipe_dbg(current->pipeline, "pipeline_comp_copy(), current->comp.id = %u, dir = %u", + pipe_dbg(current->pipeline, "current->comp.id = %u, dir = %u", dev_comp_id(current), dir); if (!is_single_ppl) { pipe_dbg(current->pipeline, - "pipeline_comp_copy(), current is from another pipeline and can't be scheduled together"); + "current is from another pipeline and can't be scheduled together"); return 0; } if (!comp_is_active(current)) { - pipe_dbg(current->pipeline, "pipeline_comp_copy(), current is not active"); + pipe_dbg(current->pipeline, "current is not active"); return 0; } @@ -239,7 +239,7 @@ static int pipeline_comp_list(struct comp_dev *current, */ if (!is_single_ppl && (!is_same_sched || IPC4_MOD_ID(current->ipc_config.id))) { pipe_dbg(current->pipeline, - "pipeline_comp_list(), current is from another pipeline"); + "current is from another pipeline"); return 0; } @@ -473,7 +473,7 @@ static int pipeline_comp_trigger(struct comp_dev *current, int err; pipe_dbg(current->pipeline, - "pipeline_comp_trigger(), current->comp.id = %u, dir = %u", + "current->comp.id = %u, dir = %u", dev_comp_id(current), dir); switch (ppl_data->cmd) { @@ -520,7 +520,7 @@ static int pipeline_comp_trigger(struct comp_dev *current, */ if (!is_single_ppl && (!is_same_sched || IS_ENABLED(CONFIG_IPC_MAJOR_4))) { pipe_dbg(current->pipeline, - "pipeline_comp_trigger(), current is from another pipeline"); + "current is from another pipeline"); if (pipeline_should_report_enodata_on_trigger(current, ctx, dir)) return -ENODATA; diff --git a/src/audio/pipeline/pipeline-xrun.c b/src/audio/pipeline/pipeline-xrun.c index 3b727074ab97..c535ddbb84a1 100644 --- a/src/audio/pipeline/pipeline-xrun.c +++ b/src/audio/pipeline/pipeline-xrun.c @@ -29,6 +29,8 @@ LOG_MODULE_DECLARE(pipe, CONFIG_SOF_LOG_LEVEL); */ #define NO_XRUN_RECOVERY 1 +#if CONFIG_IPC_MAJOR_3 + /* This function always returns success */ static int pipeline_comp_xrun(struct comp_dev *current, struct comp_buffer *calling_buf, @@ -49,6 +51,8 @@ static int pipeline_comp_xrun(struct comp_dev *current, return pipeline_for_each_comp(current, ctx, dir); } +#endif /* CONFIG_IPC_MAJOR_3 */ + #if NO_XRUN_RECOVERY /* recover the pipeline from a XRUN condition */ int pipeline_xrun_recover(struct pipeline *p) @@ -63,7 +67,7 @@ int pipeline_xrun_recover(struct pipeline *p) { int ret; - pipe_err(p, "pipeline_xrun_recover()"); + pipe_err(p, "entry"); /* prepare the pipeline */ ret = pipeline_prepare(p, p->source_comp); @@ -139,6 +143,7 @@ int pipeline_xrun_handle_trigger(struct pipeline *p, int cmd) void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, int32_t bytes) { +#if CONFIG_IPC_MAJOR_3 struct pipeline_data data; struct pipeline_walk_context walk_ctx = { .comp_func = pipeline_comp_xrun, @@ -146,6 +151,7 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, .skip_incomplete = true, }; struct sof_ipc_stream_posn posn; +#endif int ret; /* don't flood host */ @@ -162,6 +168,12 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, pipe_err(p, "Pipelines notification about XRUN failed, ret = %d", ret); + /* + * The IPC position info reporting via window2 is only + * used for IPC3 and e.g. in IPC4 this is conflicting + * with the debug window usages (logging, debug, ..) + */ +#if CONFIG_IPC_MAJOR_3 memset(&posn, 0, sizeof(posn)); ipc_build_stream_posn(&posn, SOF_IPC_STREAM_TRIG_XRUN, dev_comp_id(dev)); @@ -172,4 +184,5 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, data.p = p; walk_ctx.comp_func(dev, NULL, &walk_ctx, dev->direction); +#endif } diff --git a/src/audio/rtnr/rtnr.c b/src/audio/rtnr/rtnr.c index 541f985753a1..45ff62a60f8d 100644 --- a/src/audio/rtnr/rtnr.c +++ b/src/audio/rtnr/rtnr.c @@ -74,27 +74,27 @@ void rtnr_printf(int a, int b, int c, int d, int e) { switch (a) { case 0xa: - tr_info(&rtnr_tr, "rtnr_printf 1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", + tr_info(&rtnr_tr, "1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", b, c, d, e); break; case 0xb: - tr_info(&rtnr_tr, "rtnr_printf 1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", + tr_info(&rtnr_tr, "1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", b, c, d, e); break; case 0xc: - tr_warn(&rtnr_tr, "rtnr_printf 1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", + tr_warn(&rtnr_tr, "1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", b, c, d, e); break; case 0xd: - tr_dbg(&rtnr_tr, "rtnr_printf 1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", + tr_dbg(&rtnr_tr, "1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", b, c, d, e); break; case 0xe: - tr_err(&rtnr_tr, "rtnr_printf 1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", + tr_err(&rtnr_tr, "1st=%08x, 2nd=%08x, 3rd=%08x, 4st=%08x", b, c, d, e); break; @@ -197,7 +197,7 @@ static inline void rtnr_set_process_sample_rate(struct processing_module *mod, u { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "rtnr_set_process_sample_rate()"); + comp_dbg(mod->dev, "entry"); cd->process_sample_rate = sample_rate; } @@ -206,12 +206,12 @@ static int32_t rtnr_check_config_validity(struct processing_module *mod) struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "rtnr_check_config_validity() sample_rate:%d enabled: %d", + comp_dbg(dev, "sample_rate:%d enabled: %d", cd->config.params.sample_rate, cd->config.params.enabled); if ((cd->config.params.sample_rate != 48000) && (cd->config.params.sample_rate != 16000)) { - comp_err(dev, "rtnr_check_config_validity() invalid sample_rate:%d", + comp_err(dev, "invalid sample_rate:%d", cd->config.params.sample_rate); return -EINVAL; } @@ -241,7 +241,7 @@ static int rtnr_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -250,9 +250,9 @@ static int rtnr_init(struct processing_module *mod) cd->process_enable = true; /* Handler for component data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto cd_fail; } @@ -285,8 +285,8 @@ static int rtnr_init(struct processing_module *mod) return 0; cd_fail: - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -294,13 +294,13 @@ static int rtnr_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "rtnr_free()"); + comp_info(mod->dev, "entry"); - comp_data_blob_handler_free(cd->model_handler); + mod_data_blob_handler_free(mod, cd->model_handler); RTKMA_API_Context_Free(cd->rtk_agl); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -312,7 +312,7 @@ static int rtnr_check_params(struct processing_module *mod, struct audio_stream struct comp_data *cd = module_get_private_data(mod); bool channels_valid; - comp_info(dev, "rtnr_check_params()"); + comp_info(dev, "entry"); /* set source/sink_frames/rate */ cd->source_rate = audio_stream_get_rate(source); @@ -439,7 +439,7 @@ static int rtnr_get_config(struct processing_module *mod, struct comp_dev *dev = mod->dev; #if CONFIG_IPC_MAJOR_4 - comp_err(dev, "rtnr_get_config(), Not supported, should not happen"); + comp_err(dev, "Not supported, should not happen"); return -EINVAL; #elif CONFIG_IPC_MAJOR_3 @@ -447,7 +447,7 @@ static int rtnr_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; int j; - comp_dbg(dev, "rtnr_get_config()"); + comp_dbg(dev, "entry"); switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: @@ -478,7 +478,7 @@ static int rtnr_reconfigure(struct processing_module *mod) uint8_t *config; size_t size; - comp_dbg(dev, "rtnr_reconfigure()"); + comp_dbg(dev, "entry"); if (!comp_is_current_data_blob_valid(cd->model_handler) && !comp_is_new_data_blob_available(cd->model_handler)) { @@ -494,7 +494,7 @@ static int rtnr_reconfigure(struct processing_module *mod) } config = comp_get_data_blob(cd->model_handler, &size, NULL); - comp_dbg(dev, "rtnr_reconfigure() size: %d", size); + comp_dbg(dev, "size: %d", size); if (size == 0) { /* No data to be handled */ @@ -562,7 +562,7 @@ static int32_t rtnr_set_value(struct processing_module *mod, void *ctl_data) for (j = 0; j < cdata->num_elems; j++) { val |= cdata->chanv[j].value; - comp_dbg(dev, "rtnr_set_value(), value = %u", val); + comp_dbg(dev, "value = %u", val); } if (val) { @@ -614,7 +614,7 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id, * concurrently which is the case when there is no preemption. */ if (comp_is_new_data_blob_available(cd->model_handler)) { - comp_dbg(dev, "rtnr_set_config(), new data blob available"); + comp_dbg(dev, "new data blob available"); comp_get_data_blob(cd->model_handler, NULL, NULL); cd->reconfigure = true; } @@ -629,7 +629,7 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id, return rtnr_set_value(mod, cdata); } - comp_err(dev, "rtnr_set_config() error: invalid command %d", cdata->cmd); + comp_err(dev, "error: invalid command %d", cdata->cmd); return -EINVAL; #elif CONFIG_IPC_MAJOR_4 @@ -637,10 +637,10 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id, switch (param_id) { case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: - comp_dbg(dev, "rtnr_set_config(), SOF_IPC4_SWITCH_CONTROL_PARAM_ID"); + comp_dbg(dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID"); return rtnr_set_value(mod, ctl); case SOF_RTNR_CONFIG: - comp_dbg(dev, "rtnr_set_config(), SOF_RTNR_CONFIG"); + comp_dbg(dev, "SOF_RTNR_CONFIG"); if (dev->state < COMP_STATE_READY) { comp_err(dev, "driver in init!"); return -EBUSY; @@ -648,7 +648,7 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id, return rtnr_set_config_bytes(mod, fragment, fragment_size); case SOF_RTNR_DATA: - comp_dbg(dev, "rtnr_set_config(), SOF_RTNR_DATA"); + comp_dbg(dev, "SOF_RTNR_DATA"); if (dev->state < COMP_STATE_READY) { comp_err(dev, "driver in init!"); return -EBUSY; @@ -675,7 +675,7 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id, return 0; } - comp_err(dev, "rtnr_set_config(), error: invalid param_id = %d", param_id); + comp_err(dev, "error: invalid param_id = %d", param_id); return -EINVAL; #endif } @@ -799,7 +799,7 @@ static int rtnr_prepare(struct processing_module *mod, struct comp_buffer *sourceb, *sinkb; int ret; - comp_dbg(dev, "rtnr_prepare()"); + comp_dbg(dev, "entry"); sinkb = comp_dev_get_first_data_consumer(dev); sourceb = comp_dev_get_first_data_producer(dev); @@ -829,7 +829,7 @@ static int rtnr_prepare(struct processing_module *mod, goto err; /* Check source and sink PCM format and get processing function */ - comp_info(dev, "rtnr_prepare(), sink_format=%d", cd->sink_format); + comp_info(dev, "sink_format=%d", cd->sink_format); cd->rtnr_func = rtnr_find_func(cd->sink_format); if (!cd->rtnr_func) { comp_err(dev, "No suitable processing function found."); @@ -853,7 +853,7 @@ static int rtnr_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "rtnr_reset()"); + comp_info(mod->dev, "entry"); cd->sink_format = 0; cd->rtnr_func = NULL; diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 201ed9fa6567..40a4a2c5b888 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -43,7 +43,6 @@ LOG_MODULE_REGISTER(selector, CONFIG_SOF_LOG_LEVEL); static const struct comp_driver comp_selector; SOF_DEFINE_REG_UUID(selector); -DECLARE_TR_CTX(selector_tr, SOF_UUID(selector_uuid), LOG_LEVEL_INFO); static int selector_verify_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) @@ -53,7 +52,7 @@ static int selector_verify_params(struct comp_dev *dev, uint32_t in_channels; uint32_t out_channels; - comp_dbg(dev, "selector_verify_params()"); + comp_dbg(dev, "entry"); sinkb = comp_dev_get_first_data_consumer(dev); @@ -164,7 +163,7 @@ static struct comp_dev *selector_new(const struct comp_driver *drv, cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); if (!cd) { - rfree(dev); + comp_free_device(dev); return NULL; } @@ -173,7 +172,7 @@ static struct comp_dev *selector_new(const struct comp_driver *drv, ret = memcpy_s(&cd->config, sizeof(cd->config), ipc_process->data, bs); if (ret) { rfree(cd); - rfree(dev); + comp_free_device(dev); return NULL; } @@ -189,10 +188,10 @@ static void selector_free(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "selector_free()"); + comp_dbg(dev, "entry"); rfree(cd); - rfree(dev); + comp_free_device(dev); } /** @@ -207,7 +206,7 @@ static int selector_params(struct comp_dev *dev, { int err; - comp_dbg(dev, "selector_params()"); + comp_dbg(dev, "entry"); err = selector_verify_params(dev, params); if (err < 0) { @@ -233,7 +232,7 @@ static int selector_ctrl_set_data(struct comp_dev *dev, switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: - comp_dbg(dev, "selector_ctrl_set_data(), SOF_CTRL_CMD_BINARY"); + comp_dbg(dev, "SOF_CTRL_CMD_BINARY"); cfg = (struct sof_sel_config *) ASSUME_ALIGNED(&cdata->data->data, 4); @@ -269,7 +268,7 @@ static int selector_ctrl_get_data(struct comp_dev *dev, switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: - comp_dbg(dev, "selector_ctrl_get_data(), SOF_CTRL_CMD_BINARY"); + comp_dbg(dev, "SOF_CTRL_CMD_BINARY"); if (size < sizeof(cd->config)) return -EINVAL; @@ -306,7 +305,7 @@ static int selector_cmd(struct comp_dev *dev, int cmd, void *data, struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); int ret = 0; - comp_dbg(dev, "selector_cmd()"); + comp_dbg(dev, "entry"); switch (cmd) { case COMP_CMD_SET_DATA: @@ -316,10 +315,10 @@ static int selector_cmd(struct comp_dev *dev, int cmd, void *data, ret = selector_ctrl_get_data(dev, cdata, max_data_size); break; case COMP_CMD_SET_VALUE: - comp_dbg(dev, "selector_cmd(), COMP_CMD_SET_VALUE"); + comp_dbg(dev, "COMP_CMD_SET_VALUE"); break; case COMP_CMD_GET_VALUE: - comp_dbg(dev, "selector_cmd(), COMP_CMD_GET_VALUE"); + comp_dbg(dev, "COMP_CMD_GET_VALUE"); break; default: comp_err(dev, "invalid command"); @@ -341,7 +340,7 @@ static int selector_trigger(struct comp_dev *dev, int cmd) enum sof_comp_type type; int ret; - comp_dbg(dev, "selector_trigger()"); + comp_dbg(dev, "entry"); sourceb = comp_dev_get_first_data_producer(dev); if (!sourceb) { @@ -375,7 +374,7 @@ static int selector_copy(struct comp_dev *dev) uint32_t source_bytes; uint32_t sink_bytes; - comp_dbg(dev, "selector_copy()"); + comp_dbg(dev, "entry"); /* selector component will have 1 source and 1 sink buffer */ source = comp_dev_get_first_data_producer(dev); @@ -388,7 +387,7 @@ static int selector_copy(struct comp_dev *dev) source_bytes = frames * audio_stream_frame_bytes(&source->stream); sink_bytes = frames * audio_stream_frame_bytes(&sink->stream); - comp_dbg(dev, "selector_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", + comp_dbg(dev, "source_bytes = 0x%x, sink_bytes = 0x%x", source_bytes, sink_bytes); /* copy selected channels from in to out */ @@ -415,7 +414,7 @@ static int selector_prepare(struct comp_dev *dev) size_t sink_size; int ret; - comp_dbg(dev, "selector_prepare()"); + comp_dbg(dev, "entry"); ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); if (ret < 0) @@ -499,7 +498,7 @@ static int selector_reset(struct comp_dev *dev) int ret; struct comp_data *cd = comp_get_drvdata(dev); - comp_dbg(dev, "selector_reset()"); + comp_dbg(dev, "entry"); cd->source_period_bytes = 0; cd->sink_period_bytes = 0; @@ -510,6 +509,8 @@ static int selector_reset(struct comp_dev *dev) return ret; } +DECLARE_TR_CTX(selector_tr, SOF_UUID(selector_uuid), LOG_LEVEL_INFO); + /** \brief Selector component definition. */ static const struct comp_driver comp_selector = { .type = SOF_COMP_SELECTOR, @@ -544,7 +545,6 @@ SOF_MODULE_INIT(selector, sys_comp_selector_init); #else SOF_DEFINE_REG_UUID(selector4); -DECLARE_TR_CTX(selector_tr, SOF_UUID(selector4_uuid), LOG_LEVEL_INFO); static void build_config(struct comp_data *cd, struct module_config *cfg) { @@ -589,7 +589,7 @@ static int selector_init(struct processing_module *mod) size_t bs[2]; int ret; - comp_dbg(mod->dev, "selector_init()"); + comp_dbg(mod->dev, "entry"); init_cfg_ext = cfg->init_data; init_cfg_out_fmt = cfg->init_data; @@ -613,7 +613,7 @@ static int selector_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -692,7 +692,7 @@ static int selector_verify_params(struct processing_module *mod, uint32_t in_channels = cd->config.in_channels_count; uint32_t out_channels = cd->config.out_channels_count; - comp_dbg(dev, "selector_verify_params()"); + comp_dbg(dev, "entry"); /* verify input channels */ if (in_channels == 0 || in_channels > SEL_SOURCE_CHANNELS_MAX) { @@ -731,9 +731,9 @@ static int selector_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "selector_free()"); + comp_dbg(mod->dev, "entry"); - rfree(cd); + mod_free(mod, cd); return 0; } @@ -750,7 +750,7 @@ static int selector_params(struct processing_module *mod) struct sof_ipc_stream_params *params = mod->stream_params; int err; - comp_dbg(mod->dev, "selector_params()"); + comp_dbg(mod->dev, "entry"); set_selector_params(mod, params); @@ -802,7 +802,7 @@ static int selector_process(struct processing_module *mod, struct comp_data *cd = module_get_private_data(mod); uint32_t avail_frames = input_buffers[0].size; - comp_dbg(mod->dev, "selector_process()"); + comp_dbg(mod->dev, "entry"); if (avail_frames) /* copy selected channels from in to out */ @@ -827,7 +827,7 @@ static int selector_prepare(struct processing_module *mod, size_t sink_size; int ret; - comp_dbg(dev, "selector_prepare()"); + comp_dbg(dev, "entry"); ret = selector_params(mod); if (ret < 0) @@ -903,7 +903,7 @@ static int selector_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "selector_reset()"); + comp_dbg(mod->dev, "entry"); cd->source_period_bytes = 0; cd->sink_period_bytes = 0; @@ -937,6 +937,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(selector_tr, SOF_UUID(selector4_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(selector_interface, selector4_uuid, selector_tr); SOF_MODULE_INIT(selector, sys_comp_module_selector_interface_init); diff --git a/src/audio/selector/selector.toml b/src/audio/selector/selector.toml index 69256573033f..3c984a00fd45 100644 --- a/src/audio/selector/selector.toml +++ b/src/audio/selector/selector.toml @@ -39,7 +39,7 @@ 13, 0, 0, 0, 216, 8818000, 384, 1152, 0, 8818, 0, 14, 0, 0, 0, 216, 12274000, 768, 1152, 0, 12274, 0, 15, 0, 0, 0, 216, 19186000, 1536, 1152, 0, 19186, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 216, 2952000, 384, 192, 0, 2952, 0, 1, 0, 0, 0, 216, 4720000, 384, 384, 0, 4720, 0, 2, 0, 0, 0, 216, 5705000, 576, 384, 0, 5705, 0, diff --git a/src/audio/selector/tune/sof_selector_blobs.m b/src/audio/selector/tune/sof_selector_blobs.m index 10ea1879b74a..83b38be64e3e 100644 --- a/src/audio/selector/tune/sof_selector_blobs.m +++ b/src/audio/selector/tune/sof_selector_blobs.m @@ -1,4 +1,13 @@ -% Export configuration blobs for Selector +% sof_selector_blobs - export configuration blobs for Selector +% +% This script is run without arguments. It exports a number of +% configuration blobs for selector/micsel component. The first +% category of blobs are for upmix and downmix between mono to +% 7.1 channel audio formats. +% +% The second category is for duplicating stereo to four channels +% for 2-way speaker crossover filter. +% % SPDX-License-Identifier: BSD-3-Clause % @@ -97,6 +106,39 @@ function sof_selector_blobs() write_blob(sel, "upmix_stereo_to_51"); write_blob(sel, "upmix_stereo_to_71"); + % Stereo to L,L,R,R + sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_llrr"); + + % Stereo to R,R,L,L + sel.coeffs = [ 0 1 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_rrll"); + + % Stereo to L,R,L,R + sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_lrlr"); + sof_selector_paths(false); end diff --git a/src/audio/smart_amp/Kconfig b/src/audio/smart_amp/Kconfig index 34c537d4db16..51564f99eebc 100644 --- a/src/audio/smart_amp/Kconfig +++ b/src/audio/smart_amp/Kconfig @@ -2,7 +2,6 @@ config COMP_SMART_AMP bool "Smart Amplifier component" - select COMP_BLOB help Select for Smart Amp component. This component protect the speaker from overheating and excursion violation. This consists of two parts diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index f7ed81d25b8a..f82e3d2f7360 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -18,8 +19,6 @@ #include #include -static const struct comp_driver comp_smart_amp; - /* NOTE: this code builds itself with one of two distinct UUIDs * depending on configuration! */ @@ -29,25 +28,23 @@ SOF_DEFINE_REG_UUID(maxim_dsm); #else /* Passthrough */ SOF_DEFINE_REG_UUID(passthru_smart_amp); -#define UUID_SYM passthru_smart_amp +#define UUID_SYM passthru_smart_amp_uuid #endif -DECLARE_TR_CTX(smart_amp_comp_tr, SOF_UUID(UUID_SYM), - LOG_LEVEL_INFO); + +LOG_MODULE_REGISTER(smart_amp, CONFIG_SOF_LOG_LEVEL); /* Amp configuration & model calibration data for tuning/debug */ #define SOF_SMART_AMP_CONFIG 0 #define SOF_SMART_AMP_MODEL 1 struct smart_amp_data { + struct processing_module *mod; struct sof_smart_amp_config config; - struct comp_data_blob_handler *model_handler; struct comp_buffer *source_buf; /**< stream source buffer */ struct comp_buffer *feedback_buf; /**< feedback source buffer */ struct comp_buffer *sink_buf; /**< sink buffer */ - struct ipc_config_process ipc_config; - smart_amp_src_func ff_get_frame; /**< function to get stream source */ smart_amp_src_func fb_get_frame; /**< function to get feedback source */ smart_amp_sink_func ff_set_frame; /**< function to set sink */ @@ -69,33 +66,34 @@ struct smart_amp_data { static inline void smart_amp_free_mod_memories(struct smart_amp_data *sad) { /* sof -> mod feed-forward data re-mapping and format conversion */ - rfree(sad->ff_mod.buf.data); + mod_free(sad->mod, sad->ff_mod.buf.data); sad->ff_mod.buf.data = NULL; /* sof -> mod feedback data re-mapping and format conversion */ - rfree(sad->fb_mod.buf.data); + mod_free(sad->mod, sad->fb_mod.buf.data); sad->fb_mod.buf.data = NULL; /* mod -> sof processed data format conversion */ - rfree(sad->out_mod.buf.data); + mod_free(sad->mod, sad->out_mod.buf.data); sad->out_mod.buf.data = NULL; /* mem block for mod private data usage */ - rfree(sad->mod_mems[MOD_MEMBLK_PRIVATE].data); + mod_free(sad->mod, sad->mod_mems[MOD_MEMBLK_PRIVATE].data); sad->mod_mems[MOD_MEMBLK_PRIVATE].data = NULL; /* mem block for mod audio frame data usage */ - rfree(sad->mod_mems[MOD_MEMBLK_FRAME].data); + mod_free(sad->mod, sad->mod_mems[MOD_MEMBLK_FRAME].data); sad->mod_mems[MOD_MEMBLK_FRAME].data = NULL; /* mem block for mod parameter blob usage */ - rfree(sad->mod_mems[MOD_MEMBLK_PARAM].data); + mod_free(sad->mod, sad->mod_mems[MOD_MEMBLK_PARAM].data); sad->mod_mems[MOD_MEMBLK_PARAM].data = NULL; /* inner model data struct */ - rfree(sad->mod_data); + mod_free(sad->mod, sad->mod_data); sad->mod_data = NULL; } -static inline int smart_amp_buf_alloc(struct smart_amp_buf *buf, size_t size) +static inline int smart_amp_buf_alloc(struct processing_module *mod, + struct smart_amp_buf *buf, size_t size) { - buf->data = rballoc(SOF_MEM_FLAG_USER, size); + buf->data = mod_alloc(mod, size); if (!buf->data) return -ENOMEM; buf->size = size; @@ -105,12 +103,12 @@ static inline int smart_amp_buf_alloc(struct smart_amp_buf *buf, size_t size) static ssize_t smart_amp_alloc_mod_memblk(struct smart_amp_data *sad, enum smart_amp_mod_memblk blk) { - struct smart_amp_mod_data_base *mod = sad->mod_data; + struct smart_amp_mod_data_base *smod = sad->mod_data; int ret; size_t size; /* query the required size from inner model. */ - ret = mod->mod_ops->query_memblk_size(mod, blk); + ret = smod->mod_ops->query_memblk_size(smod, blk); if (ret < 0) goto error; @@ -120,12 +118,12 @@ static ssize_t smart_amp_alloc_mod_memblk(struct smart_amp_data *sad, /* allocate the memory block when returned size > 0. */ size = ret; - ret = smart_amp_buf_alloc(&sad->mod_mems[blk], size); + ret = smart_amp_buf_alloc(sad->mod, &sad->mod_mems[blk], size); if (ret < 0) goto error; /* provide the memory block information to inner model. */ - ret = mod->mod_ops->set_memblk(mod, blk, &sad->mod_mems[blk]); + ret = smod->mod_ops->set_memblk(smod, blk, &sad->mod_mems[blk]); if (ret < 0) goto error; @@ -145,21 +143,21 @@ static int smart_amp_alloc_data_buffers(struct comp_dev *dev, /* sof -> mod feed-forward data re-mapping and format conversion */ size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); - ret = smart_amp_buf_alloc(&sad->ff_mod.buf, size); + ret = smart_amp_buf_alloc(sad->mod, &sad->ff_mod.buf, size); if (ret < 0) goto error; total_size = size; /* sof -> mod feedback data re-mapping and format conversion */ size = SMART_AMP_FB_BUF_DB_SZ * sizeof(int32_t); - ret = smart_amp_buf_alloc(&sad->fb_mod.buf, size); + ret = smart_amp_buf_alloc(sad->mod, &sad->fb_mod.buf, size); if (ret < 0) goto error; total_size += size; /* mod -> sof processed data format conversion */ size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); - ret = smart_amp_buf_alloc(&sad->out_mod.buf, size); + ret = smart_amp_buf_alloc(sad->mod, &sad->out_mod.buf, size); if (ret < 0) goto error; total_size += size; @@ -172,46 +170,35 @@ static int smart_amp_alloc_data_buffers(struct comp_dev *dev, return ret; } -static struct comp_dev *smart_amp_new(const struct comp_driver *drv, - const struct comp_ipc_config *config, - const void *spec) +static int smart_amp_init(struct processing_module *mod) { - struct comp_dev *dev; - const struct ipc_config_process *ipc_sa = spec; + struct comp_dev *dev = mod->dev; + struct module_config *mcfg = &mod->priv.cfg; struct smart_amp_data *sad; struct sof_smart_amp_config *cfg; size_t bs; int ret; - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) - return NULL; - - dev->ipc_config = *config; - - sad = rzalloc(SOF_MEM_FLAG_USER, sizeof(*sad)); - if (!sad) { - rfree(dev); - return NULL; - } - - comp_set_drvdata(dev, sad); - sad->ipc_config = *ipc_sa; + /* Allocate smart_amp_data using module API */ + sad = mod_zalloc(mod, sizeof(*sad)); + if (!sad) + return -ENOMEM; - cfg = (struct sof_smart_amp_config *)ipc_sa->data; - bs = ipc_sa->size; + mod->priv.private = sad; + sad->mod = mod; - if (bs > 0 && bs < sizeof(struct sof_smart_amp_config)) { - comp_err(dev, "failed to apply config"); - goto error; + /* Copy config blob if present */ + if (mcfg->avail && mcfg->init_data && mcfg->size >= sizeof(struct sof_smart_amp_config)) { + cfg = (struct sof_smart_amp_config *)mcfg->init_data; + bs = mcfg->size; + memcpy_s(&sad->config, sizeof(struct sof_smart_amp_config), cfg, bs); } - memcpy_s(&sad->config, sizeof(struct sof_smart_amp_config), cfg, bs); - /* allocate inner model data struct */ sad->mod_data = mod_data_create(dev); if (!sad->mod_data) { - comp_err(dev, "failed to allocate nner model data"); + comp_err(dev, "failed to allocate inner model data"); + ret = -ENOMEM; goto error; } @@ -253,22 +240,19 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, } comp_dbg(dev, "used mod config buffer %d bytes", ret); - dev->state = COMP_STATE_READY; - - return dev; - + return 0; error: smart_amp_free_mod_memories(sad); - rfree(sad); - rfree(dev); - return NULL; + mod_free(mod, sad); + return ret; } -static int smart_amp_set_config(struct comp_dev *dev, +static int smart_amp_set_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); struct sof_smart_amp_config *cfg; + struct comp_dev *dev = mod->dev; size_t bs; /* Copy new config, find size from header */ @@ -276,7 +260,7 @@ static int smart_amp_set_config(struct comp_dev *dev, ASSUME_ALIGNED(&cdata->data->data, sizeof(uint32_t)); bs = cfg->size; - comp_dbg(dev, "smart_amp_set_config(), actual blob size = %zu, expected blob size = %zu", + comp_dbg(dev, "actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); if (bs != sizeof(struct sof_smart_amp_config)) { @@ -291,17 +275,18 @@ static int smart_amp_set_config(struct comp_dev *dev, return 0; } -static int smart_amp_get_config(struct comp_dev *dev, +static int smart_amp_get_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata, int size) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; size_t bs; int ret = 0; /* Copy back to user space */ bs = sad->config.size; - comp_dbg(dev, "smart_amp_get_config(), actual blob size = %zu, expected blob size = %zu", + comp_dbg(dev, "actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); if (bs == 0 || bs > size) @@ -316,24 +301,24 @@ static int smart_amp_get_config(struct comp_dev *dev, return ret; } -#if CONFIG_IPC_MAJOR_3 -static int smart_amp_ctrl_get_bin_data(struct comp_dev *dev, +static int smart_amp_ctrl_get_bin_data(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata, int size) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod; + struct comp_dev *dev = mod->dev; int ret = 0; assert(sad); - mod = sad->mod_data; + smod = sad->mod_data; switch (cdata->data->type) { case SOF_SMART_AMP_CONFIG: - ret = smart_amp_get_config(dev, cdata, size); + ret = smart_amp_get_config(mod, cdata, size); break; case SOF_SMART_AMP_MODEL: - ret = mod->mod_ops->get_config(mod, cdata, size); + ret = smod->mod_ops->get_config(smod, cdata, size); if (ret < 0) { comp_err(dev, "failed to read inner model!"); return ret; @@ -347,34 +332,38 @@ static int smart_amp_ctrl_get_bin_data(struct comp_dev *dev, return ret; } -static int smart_amp_ctrl_get_data(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int size) +static int smart_amp_get_configuration(struct processing_module *mod, + uint32_t config_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size) { - int ret = 0; + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "smart_amp_ctrl_get_data() size: %d", size); + comp_dbg(dev, "config_id %u size: %zu", config_id, fragment_size); +#if CONFIG_IPC_MAJOR_3 switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: - ret = smart_amp_ctrl_get_bin_data(dev, cdata, size); - break; + return smart_amp_ctrl_get_bin_data(mod, cdata, fragment_size); default: comp_err(dev, "invalid cdata->cmd"); - return -EINVAL; } - - return ret; +#elif CONFIG_IPC_MAJOR_4 + return smart_amp_ctrl_get_bin_data(mod, cdata, fragment_size); +#endif + return -EINVAL; } -static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, +static int smart_amp_ctrl_set_bin_data(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod; + struct comp_dev *dev = mod->dev; int ret = 0; assert(sad); - mod = sad->mod_data; + smod = sad->mod_data; if (dev->state < COMP_STATE_READY) { comp_err(dev, "driver in init!"); @@ -383,10 +372,10 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, switch (cdata->data->type) { case SOF_SMART_AMP_CONFIG: - ret = smart_amp_set_config(dev, cdata); + ret = smart_amp_set_config(mod, cdata); break; case SOF_SMART_AMP_MODEL: - ret = mod->mod_ops->set_config(mod, cdata); + ret = smod->mod_ops->set_config(smod, cdata); if (ret < 0) { comp_err(dev, "failed to write inner model!"); return ret; @@ -400,9 +389,10 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, return ret; } -static int smart_amp_ctrl_set_data(struct comp_dev *dev, +static int smart_amp_ctrl_set_data(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata) { + struct comp_dev *dev = mod->dev; int ret = 0; /* Check version from ABI header */ @@ -413,8 +403,8 @@ static int smart_amp_ctrl_set_data(struct comp_dev *dev, switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: - comp_dbg(dev, "smart_amp_ctrl_set_data(), SOF_CTRL_CMD_BINARY"); - ret = smart_amp_ctrl_set_bin_data(dev, cdata); + comp_dbg(dev, "SOF_CTRL_CMD_BINARY"); + ret = smart_amp_ctrl_set_bin_data(mod, cdata); break; default: comp_err(dev, "invalid cdata->cmd"); @@ -425,77 +415,74 @@ static int smart_amp_ctrl_set_data(struct comp_dev *dev, return ret; } -/* used to pass standard and bespoke commands (with data) to component */ -static int smart_amp_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) +static int smart_amp_set_configuration(struct processing_module *mod, + uint32_t config_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, + uint8_t *response, size_t response_size) { - struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "cmd: %d", cmd); + comp_info(dev, "config_id %u size %zu", config_id, response_size); - switch (cmd) { - case COMP_CMD_SET_DATA: - return smart_amp_ctrl_set_data(dev, cdata); - case COMP_CMD_GET_DATA: - return smart_amp_ctrl_get_data(dev, cdata, max_data_size); +#if CONFIG_IPC_MAJOR_3 + switch (cdata->cmd) { + case SOF_CTRL_CMD_BINARY: + comp_info(dev, "SOF_CTRL_CMD_BINARY"); + return smart_amp_ctrl_set_data(mod, cdata); default: - return -EINVAL; + comp_err(dev, "unknown cmd %d", cdata->cmd); } -} +#elif CONFIG_IPC_MAJOR_4 + return smart_amp_ctrl_set_data(mod, cdata); #endif + return -EINVAL; +} -static void smart_amp_free(struct comp_dev *dev) +static int smart_amp_free(struct processing_module *mod) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "smart_amp_free()"); + comp_dbg(dev, "entry"); + if (!sad) + return 0; smart_amp_free_mod_memories(sad); - rfree(sad); - sad = NULL; - rfree(dev); - dev = NULL; -} - -static int smart_amp_verify_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) -{ - int ret; - - comp_dbg(dev, "smart_amp_verify_params()"); - - ret = comp_verify_params(dev, BUFF_PARAMS_CHANNELS, params); - if (ret < 0) { - comp_err(dev, "volume_verify_params() error: comp_verify_params() failed."); - return ret; - } + mod_free(mod, sad); + mod->priv.private = NULL; return 0; } -static int smart_amp_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) +#if CONFIG_IPC_MAJOR_4 +static void smart_amp_ipc4_params(struct processing_module *mod) { - int err; + struct sof_ipc_stream_params *params = mod->stream_params; + struct comp_buffer *sinkb, *sourceb; + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "smart_amp_params()"); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + component_set_nearest_period_frames(dev, params->rate); - err = smart_amp_verify_params(dev, params); - if (err < 0) { - comp_err(dev, "pcm params verification failed."); - return -EINVAL; - } + sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); - return 0; + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); } +#endif /* CONFIG_IPC_MAJOR_4 */ -static int smart_amp_trigger(struct comp_dev *dev, int cmd) +static int smart_amp_trigger(struct processing_module *mod, int cmd) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int ret = 0; - comp_dbg(dev, "smart_amp_trigger(), command = %u", cmd); + comp_dbg(dev, "command = %u", cmd); ret = comp_set_state(dev, cmd); @@ -516,13 +503,14 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) return ret; } -static int smart_amp_ff_process(struct comp_dev *dev, +static int smart_amp_ff_process(struct processing_module *mod, const struct audio_stream *source, const struct audio_stream *sink, uint32_t frames, const int8_t *chan_map) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod = sad->mod_data; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod = sad->mod_data; + struct comp_dev *dev = mod->dev; int ret; sad->ff_mod.consumed = 0; @@ -541,7 +529,7 @@ static int smart_amp_ff_process(struct comp_dev *dev, sad->ff_get_frame(&sad->ff_mod, frames, source, chan_map); - ret = mod->mod_ops->ff_proc(mod, frames, &sad->ff_mod, &sad->out_mod); + ret = smod->mod_ops->ff_proc(smod, frames, &sad->ff_mod, &sad->out_mod); if (ret) { comp_err(dev, "feed forward inner model process error"); return ret; @@ -552,12 +540,13 @@ static int smart_amp_ff_process(struct comp_dev *dev, return 0; } -static int smart_amp_fb_process(struct comp_dev *dev, +static int smart_amp_fb_process(struct processing_module *mod, const struct audio_stream *source, uint32_t frames, const int8_t *chan_map) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod = sad->mod_data; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod = sad->mod_data; + struct comp_dev *dev = mod->dev; int ret; sad->fb_mod.consumed = 0; @@ -575,7 +564,7 @@ static int smart_amp_fb_process(struct comp_dev *dev, sad->fb_get_frame(&sad->fb_mod, frames, source, chan_map); - ret = mod->mod_ops->fb_proc(mod, frames, &sad->fb_mod); + ret = smod->mod_ops->fb_proc(smod, frames, &sad->fb_mod); if (ret) { comp_err(dev, "feedback inner model process error"); return ret; @@ -584,11 +573,14 @@ static int smart_amp_fb_process(struct comp_dev *dev, return 0; } -static int smart_amp_copy(struct comp_dev *dev) +static int smart_amp_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; struct comp_buffer *source_buf = sad->source_buf; - struct comp_buffer *sink_buf = sad->sink_buf; + struct comp_buffer *sink_buf = comp_buffer_get_from_sink(sinks[0]); uint32_t avail_passthrough_frames; uint32_t avail_feedback_frames; uint32_t avail_frames; @@ -596,7 +588,7 @@ static int smart_amp_copy(struct comp_dev *dev) uint32_t sink_bytes; uint32_t feedback_bytes; - comp_dbg(dev, "smart_amp_copy()"); + comp_dbg(dev, "%d sources %d sinks", num_of_sources, num_of_sinks); /* available bytes and samples calculation */ avail_passthrough_frames = audio_stream_avail_frames(&source_buf->stream, @@ -623,7 +615,7 @@ static int smart_amp_copy(struct comp_dev *dev) /* perform buffer writeback after source_buf process */ buffer_stream_invalidate(feedback_buf, feedback_bytes); - smart_amp_fb_process(dev, &feedback_buf->stream, + smart_amp_fb_process(mod, &feedback_buf->stream, avail_feedback_frames, sad->config.feedback_ch_map); @@ -642,7 +634,7 @@ static int smart_amp_copy(struct comp_dev *dev) source_bytes = avail_frames * audio_stream_frame_bytes(&source_buf->stream); buffer_stream_invalidate(source_buf, source_bytes); - smart_amp_ff_process(dev, &source_buf->stream, &sink_buf->stream, + smart_amp_ff_process(mod, &source_buf->stream, &sink_buf->stream, avail_frames, sad->config.source_ch_map); comp_dbg(dev, "processing %u feed forward frames (consumed: %u, produced: %u)", @@ -660,26 +652,20 @@ static int smart_amp_copy(struct comp_dev *dev) return 0; } -static int smart_amp_reset(struct comp_dev *dev) +static int smart_amp_reset(struct processing_module *mod) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod = sad->mod_data; - int ret; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod = sad->mod_data; + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "smart_amp_reset()"); + comp_dbg(dev, "entry"); sad->ff_get_frame = NULL; sad->fb_get_frame = NULL; sad->ff_set_frame = NULL; /* reset inner model */ - ret = mod->mod_ops->reset(mod); - if (ret) - return ret; - - comp_set_state(dev, COMP_TRIGGER_RESET); - - return 0; + return smod->mod_ops->reset(smod); } /* supported formats: {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE} @@ -690,17 +676,18 @@ static inline bool is_supported_fmt(uint16_t fmt) return fmt <= SOF_IPC_FRAME_S32_LE; } -static int smart_amp_resolve_mod_fmt(struct comp_dev *dev, uint32_t least_req_depth) +static int smart_amp_resolve_mod_fmt(struct processing_module *mod, uint32_t least_req_depth) { - struct smart_amp_data *sad = comp_get_drvdata(dev); - struct smart_amp_mod_data_base *mod = sad->mod_data; + struct smart_amp_data *sad = module_get_private_data(mod); + struct smart_amp_mod_data_base *smod = sad->mod_data; + struct comp_dev *dev = mod->dev; const uint16_t *mod_fmts; int num_mod_fmts; int ret; int i; /* get supported formats from mod */ - ret = mod->mod_ops->get_supported_fmts(mod, &mod_fmts, &num_mod_fmts); + ret = smod->mod_ops->get_supported_fmts(smod, &mod_fmts, &num_mod_fmts); if (ret) { comp_err(dev, "failed to get supported formats"); return ret; @@ -712,7 +699,7 @@ static int smart_amp_resolve_mod_fmt(struct comp_dev *dev, uint32_t least_req_de /* set frame format to inner model */ comp_dbg(dev, "set mod format to %u", mod_fmts[i]); - ret = mod->mod_ops->set_fmt(mod, mod_fmts[i]); + ret = smod->mod_ops->set_fmt(smod, mod_fmts[i]); if (ret) { comp_err(dev, "failed setting format %u", @@ -728,32 +715,36 @@ static int smart_amp_resolve_mod_fmt(struct comp_dev *dev, uint32_t least_req_de return -EINVAL; } -static int smart_amp_prepare(struct comp_dev *dev) +static int smart_amp_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { - struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_data *sad = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; uint16_t ff_src_fmt, fb_src_fmt, resolved_mod_fmt; uint32_t least_req_depth; - int ret; - - comp_dbg(dev, "smart_amp_prepare()"); - - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); - if (ret < 0) - return ret; + int ret, i; - /* searching for stream and feedback source buffers */ - struct comp_buffer *source_buffer; + comp_dbg(dev, "%d sources %d sinks", num_of_sources, num_of_sinks); +#if CONFIG_IPC_MAJOR_4 + smart_amp_ipc4_params(mod); +#endif - comp_dev_for_each_producer(dev, source_buffer) { - if (comp_buffer_get_source_component(source_buffer)->ipc_config.type - == SOF_COMP_DEMUX) - sad->feedback_buf = source_buffer; + /* In module API, state is managed by the framework, so no comp_set_state needed */ + for (i = 0; i < num_of_sources; i++) { + /* NOTE: This should not work in module based environment: + * sources[i]->bound_module->dev->ipc_config.type == SOF_COMP_DEMUX + * So let's check which one of the sources is from a capture stream. + * The code is not tested and may not work. + */ + if (sources[i]->bound_module->dev->direction == SOF_IPC_STREAM_CAPTURE) + sad->feedback_buf = comp_buffer_get_from_source(sources[i]); else - sad->source_buf = source_buffer; + sad->source_buf = comp_buffer_get_from_source(sources[i]); } /* sink buffer */ - sad->sink_buf = comp_dev_get_first_data_consumer(dev); + sad->sink_buf = comp_buffer_get_from_sink(sinks[0]); if (!sad->sink_buf) { comp_err(dev, "no sink buffer"); return -ENOTCONN; @@ -778,14 +769,13 @@ static int smart_amp_prepare(struct comp_dev *dev) fb_src_fmt = audio_stream_get_frm_fmt(&sad->feedback_buf->stream); sad->fb_mod.channels = MIN(SMART_AMP_FB_MAX_CH_NUM, audio_stream_get_channels(&sad->feedback_buf->stream)); - least_req_depth = MAX(least_req_depth, get_sample_bitdepth(fb_src_fmt)); } /* resolve the frame format for inner model. The return value will be the applied format * or the negative error code. */ - ret = smart_amp_resolve_mod_fmt(dev, least_req_depth); + ret = smart_amp_resolve_mod_fmt(mod, least_req_depth); if (ret < 0) return ret; @@ -809,36 +799,21 @@ static int smart_amp_prepare(struct comp_dev *dev) comp_dbg(dev, "fb mod buffer channels:%u fmt_conv:%u -> %u", sad->fb_mod.channels, fb_src_fmt, sad->fb_mod.frame_fmt); } + return 0; } -static const struct comp_driver comp_smart_amp = { - .type = SOF_COMP_SMART_AMP, - .uid = SOF_RT_UUID(UUID_SYM), - .tctx = &smart_amp_comp_tr, - .ops = { - .create = smart_amp_new, - .free = smart_amp_free, - .params = smart_amp_params, - .prepare = smart_amp_prepare, -#if CONFIG_IPC_MAJOR_3 - .cmd = smart_amp_cmd, -#endif - .trigger = smart_amp_trigger, - .copy = smart_amp_copy, - .reset = smart_amp_reset, - }, -}; - -static SHARED_DATA struct comp_driver_info comp_smart_amp_info = { - .drv = &comp_smart_amp, +static struct module_interface smart_amp_interface = { + .init = smart_amp_init, + .prepare = smart_amp_prepare, + .process = smart_amp_process, + .set_configuration = smart_amp_set_configuration, + .get_configuration = smart_amp_get_configuration, + .reset = smart_amp_reset, + .free = smart_amp_free, + .trigger = smart_amp_trigger, }; -UT_STATIC void sys_comp_smart_amp_init(void) -{ - comp_register(platform_shared_get(&comp_smart_amp_info, - sizeof(comp_smart_amp_info))); -} - -DECLARE_MODULE(sys_comp_smart_amp_init); -SOF_MODULE_INIT(smart_amp, sys_comp_smart_amp_init); +DECLARE_TR_CTX(smart_amp_comp_tr, SOF_UUID(UUID_SYM), LOG_LEVEL_INFO); +DECLARE_MODULE_ADAPTER(smart_amp_interface, UUID_SYM, smart_amp_comp_tr); +SOF_MODULE_INIT(smart_amp, sys_comp_module_smart_amp_interface_init); diff --git a/src/audio/smart_amp/smart_amp_maxim_dsm.c b/src/audio/smart_amp/smart_amp_maxim_dsm.c index 3360ff5c3b86..b9289861aa8d 100644 --- a/src/audio/smart_amp/smart_amp_maxim_dsm.c +++ b/src/audio/smart_amp/smart_amp_maxim_dsm.c @@ -20,6 +20,8 @@ #include #include "dsm_api_public.h" +LOG_MODULE_DECLARE(smart_amp, CONFIG_SOF_LOG_LEVEL); + /* Maxim DSM(Dynamic Speaker Management) process buffer size */ #define DSM_FRM_SZ 48 #define DSM_FF_BUF_SZ (DSM_FRM_SZ * SMART_AMP_FF_MAX_CH_NUM) @@ -319,7 +321,7 @@ static int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, * required size */ if (bs > size) { - comp_err(dev, "[DSM] maxim_dsm_get_param(): invalid size %d", bs); + comp_err(dev, "[DSM] invalid size %d", bs); return -EINVAL; } @@ -392,7 +394,7 @@ static int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, */ retcode = dsm_api_set_params(hspk->dsmhandle, 1, value); if (retcode != DSM_API_OK) { - comp_err(dev, "[DSM] maxim_dsm_set_param() write failure. (id:%x, ret:%x)", + comp_err(dev, "[DSM] write failure. (id:%x, ret:%x)", id, retcode); return -EINVAL; } @@ -420,7 +422,7 @@ static int maxim_dsm_restore_param(struct smart_amp_mod_struct_t *hspk) retcode = dsm_api_set_params(hspk->dsmhandle, 1, value); if (retcode != DSM_API_OK) { - comp_err(dev, "[DSM] maxim_dsm_restore_param() write failure. (id:%x, ret:%x)", + comp_err(dev, "[DSM] write failure. (id:%x, ret:%x)", value[DSM_SET_ID_IDX], retcode); return -EINVAL; } diff --git a/src/audio/smart_amp/smart_amp_passthru.c b/src/audio/smart_amp/smart_amp_passthru.c index d2e408a6ccd4..53084345d6d1 100644 --- a/src/audio/smart_amp/smart_amp_passthru.c +++ b/src/audio/smart_amp/smart_amp_passthru.c @@ -10,12 +10,13 @@ #include #include -#include #include #include #include #include +LOG_MODULE_DECLARE(smart_amp, CONFIG_SOF_LOG_LEVEL); + /* self-declared inner model data struct */ struct passthru_mod_data { struct smart_amp_mod_data_base base; diff --git a/src/audio/sound_dose/sound_dose.c b/src/audio/sound_dose/sound_dose.c index dcbac5c643c7..0e162a783b8a 100644 --- a/src/audio/sound_dose/sound_dose.c +++ b/src/audio/sound_dose/sound_dose.c @@ -27,11 +27,6 @@ SOF_DEFINE_REG_UUID(sound_dose); /* Creates logging data for the component */ LOG_MODULE_REGISTER(sound_dose, CONFIG_SOF_LOG_LEVEL); -/* Creates the component trace. Traces show in trace console the component - * info, warning, and error messages. - */ -DECLARE_TR_CTX(sound_dose_tr, SOF_UUID(sound_dose_uuid), LOG_LEVEL_INFO); - void sound_dose_report_mel(const struct processing_module *mod) { struct sound_dose_comp_data *cd = module_get_private_data(mod); @@ -223,7 +218,7 @@ static int sound_dose_process(struct processing_module *mod, int frames = source_get_data_frames_available(source); int sink_frames = sink_get_free_frames(sink); - comp_dbg(dev, "sound_dose_process()"); + comp_dbg(dev, "entry"); if (cd->gain_update) { /* Convert dB * 100 to Q8.24 */ @@ -270,7 +265,7 @@ static int sound_dose_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; enum sof_ipc_frame source_format; - comp_dbg(dev, "sound_dose_prepare()"); + comp_dbg(dev, "entry"); /* The processing example in this component supports one input and one * output. Generally there can be more. @@ -307,7 +302,7 @@ static int sound_dose_reset(struct processing_module *mod) { struct sound_dose_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "sound_dose_reset()"); + comp_dbg(mod->dev, "entry"); sound_dose_setup_init(cd); return 0; @@ -329,7 +324,7 @@ __cold static int sound_dose_free(struct processing_module *mod) struct sound_dose_comp_data *cd = module_get_private_data(mod); assert_can_be_cold(); - comp_dbg(mod->dev, "sound_dose_free()"); + comp_dbg(mod->dev, "entry"); sound_dose_filters_free(cd); if (cd->msg) { @@ -369,6 +364,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(sound_dose_tr, SOF_UUID(sound_dose_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(sound_dose_interface, sound_dose_uuid, sound_dose_tr); SOF_MODULE_INIT(sound_dose, sys_comp_module_sound_dose_interface_init); diff --git a/src/audio/src/llext/CMakeLists.txt b/src/audio/src/llext/CMakeLists.txt index dfb9782ee941..7cd52be725c7 100644 --- a/src/audio/src/llext/CMakeLists.txt +++ b/src/audio/src/llext/CMakeLists.txt @@ -7,6 +7,7 @@ sof_llext_build("src" ../src_generic.c ../src_hifi3.c ../src_hifi4.c + ../src_hifi5.c ../src.c ../src_common.c ../src_ipc4.c @@ -19,6 +20,7 @@ sof_llext_build("src" ../src_generic.c ../src_hifi3.c ../src_hifi4.c + ../src_hifi5.c ../src.c ../src_common.c ../src_ipc4.c diff --git a/src/audio/src/src.c b/src/audio/src/src.c index 3b1eca197b6a..9870ad911ca8 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -78,8 +78,6 @@ static const struct module_interface src_interface = { .prepare = src_prepare, .process = src_process, .is_ready_to_process = src_is_ready_to_process, - .set_configuration = src_set_config, - .get_configuration = src_get_config, .reset = src_reset, .free = src_free, }; diff --git a/src/audio/src/src.toml b/src/audio/src/src.toml index 4cf472b27641..ab496c5b8a80 100644 --- a/src/audio/src/src.toml +++ b/src/audio/src/src.toml @@ -72,7 +72,7 @@ 23, 0, 0, 0, 12832, 21852000, 180, 256, 0, 21852, 0, 24, 0, 0, 0, 12832, 12629000, 256, 512, 0, 12629, 0, 25, 0, 0, 0, 12832, 13996000, 128, 256, 0, 13996, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 12832, 30633000, 128, 512, 0, 30633, 0, 1, 0, 0, 0, 12832, 28143000, 64, 256, 0, 28143, 0, 2, 0, 0, 0, 12832, 33513000, 96, 512, 0, 33513, 0, diff --git a/src/audio/src/src_common.c b/src/audio/src/src_common.c index 5d25413193a8..a8f91c11e100 100644 --- a/src/audio/src/src_common.c +++ b/src/audio/src/src_common.c @@ -669,24 +669,6 @@ int src_process(struct processing_module *mod, return cd->src_func(cd, sources[0], sinks[0]); } -__cold int src_set_config(struct processing_module *mod, uint32_t config_id, - enum module_cfg_fragment_position pos, uint32_t data_offset_size, - const uint8_t *fragment, size_t fragment_size, uint8_t *response, - size_t response_size) -{ - assert_can_be_cold(); - - return -EINVAL; -} - -__cold int src_get_config(struct processing_module *mod, uint32_t config_id, - uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) -{ - assert_can_be_cold(); - - return -EINVAL; -} - int src_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); @@ -701,9 +683,13 @@ int src_reset(struct processing_module *mod) __cold int src_free(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + assert_can_be_cold(); comp_info(mod->dev, "entry"); + mod_free(mod, cd->delay_lines); + mod_free(mod, cd); return 0; } diff --git a/src/audio/src/src_common.h b/src/audio/src/src_common.h index 6a8028662ffd..ae3c60574eec 100644 --- a/src/audio/src/src_common.h +++ b/src/audio/src/src_common.h @@ -242,12 +242,6 @@ int src_process(struct processing_module *mod, struct sof_source **sources, int num_of_sources, struct sof_sink **sinks, int num_of_sinks); -int src_set_config(struct processing_module *mod, uint32_t config_id, - enum module_cfg_fragment_position pos, uint32_t data_offset_size, - const uint8_t *fragment, size_t fragment_size, uint8_t *response, - size_t response_size); -int src_get_config(struct processing_module *mod, uint32_t config_id, - uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size); int src_free(struct processing_module *mod); int src_reset(struct processing_module *mod); extern struct tr_ctx src_tr; diff --git a/src/audio/src/src_lite.c b/src/audio/src/src_lite.c index cefe60367bfd..9d5593ff34ca 100644 --- a/src/audio/src/src_lite.c +++ b/src/audio/src/src_lite.c @@ -61,8 +61,6 @@ const struct module_interface src_lite_interface = { .prepare = src_lite_prepare, .process = src_process, .is_ready_to_process = src_is_ready_to_process, - .set_configuration = src_set_config, - .get_configuration = src_get_config, .reset = src_reset, .free = src_free, }; diff --git a/src/audio/stft_process/CMakeLists.txt b/src/audio/stft_process/CMakeLists.txt new file mode 100644 index 000000000000..66ccb2276c58 --- /dev/null +++ b/src/audio/stft_process/CMakeLists.txt @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause + +if(CONFIG_COMP_STFT_PROCESS STREQUAL "m" AND DEFINED CONFIG_LLEXT) + add_subdirectory(llext ${PROJECT_BINARY_DIR}/stft_process_llext) + add_dependencies(app stft_process) +else() + add_local_sources(sof stft_process.c) + add_local_sources(sof stft_process_setup.c) + add_local_sources(sof stft_process_common.c) + add_local_sources(sof stft_process-generic.c) + + if(CONFIG_IPC_MAJOR_4) + add_local_sources(sof stft_process-ipc4.c) + endif() +endif() diff --git a/src/audio/stft_process/Kconfig b/src/audio/stft_process/Kconfig new file mode 100644 index 000000000000..792c87954d2d --- /dev/null +++ b/src/audio/stft_process/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +config COMP_STFT_PROCESS + tristate "Template example component" + default n + select MATH_FFT + select MATH_32BIT_FFT + select MATH_FFT_MULTI + help + Select for stft_process component. Reason for existence + is to provide a minimal component example and use as + placeholder in processing pipelines. As example processing + it swaps or reverses the channels when the switch control + is enabled. diff --git a/src/audio/stft_process/llext/CMakeLists.txt b/src/audio/stft_process/llext/CMakeLists.txt new file mode 100644 index 000000000000..133330c4a69d --- /dev/null +++ b/src/audio/stft_process/llext/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +sof_llext_build("stft_process" + SOURCES ../stft_process.c + ../stft_process_setup.c + ../stft_process_common.c + ../stft_process-generic.c + ../stft_process-ipc4.c + LIB openmodules +) diff --git a/src/audio/stft_process/llext/llext.toml.h b/src/audio/stft_process/llext/llext.toml.h new file mode 100644 index 000000000000..e3988e4bb4ed --- /dev/null +++ b/src/audio/stft_process/llext/llext.toml.h @@ -0,0 +1,6 @@ +#include +#define LOAD_TYPE "2" +#include "../stft_process.toml" + +[module] +count = __COUNTER__ diff --git a/src/audio/stft_process/stft_process-generic.c b/src/audio/stft_process/stft_process-generic.c new file mode 100644 index 000000000000..3399c24657a4 --- /dev/null +++ b/src/audio/stft_process/stft_process-generic.c @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include +#include "stft_process.h" + +#if CONFIG_FORMAT_S32LE +/** + * stft_process_source_s32() - Process S16_LE format. + * @mod: Pointer to module data. + * @source: Source for PCM samples data. + * @sink: Sink for PCM samples data. + * @frames: Number of audio data frames to process. + * + * This is the processing function for 16-bit signed integer PCM formats. The + * audio samples in every frame are re-order to channels order defined in + * component data channel_map[]. + * + * Return: Value zero for success, otherwise an error code. + */ +int stft_process_source_s32(struct stft_comp_data *cd, struct sof_source *source, int frames) +{ + struct stft_process_state *state = &cd->state; + struct stft_process_buffer *ibuf; + int32_t const *x, *x_start, *x_end; + int x_size; + int bytes = frames * cd->frame_bytes; + int frames_left = frames; + int ret; + int n1; + int n2; + int channels = cd->channels; + int n; + int i; + int j; + + /* Get pointer to source data in circular buffer */ + ret = source_get_data_s32(source, bytes, &x, &x_start, &x_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + x_end = x_start + x_size; + + while (frames_left) { + /* Find out samples to process before first wrap or end of data. */ + ibuf = &state->ibuf[0]; + n1 = (x_end - x) / cd->channels; + n2 = stft_process_buffer_samples_without_wrap(ibuf, ibuf->w_ptr); + n = MIN(n1, n2); + n = MIN(n, frames_left); + for (i = 0; i < n; i++) { + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + *ibuf->w_ptr++ = *x++; + } + } + + /* One of the buffers needs a wrap (or end of data), so check for wrap */ + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + ibuf->w_ptr = stft_process_buffer_wrap(ibuf, ibuf->w_ptr); + } + + if (x >= x_end) + x -= x_size; + + /* Update processed samples count for next loop iteration. */ + frames_left -= n; + } + + /* Update the source for bytes consumed. Return success. */ + source_release_data(source, bytes); + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + ibuf->s_avail += frames; + ibuf->s_free -= frames; + } + + return 0; +} + +/** + * stft_process_sink_s32() - Process S16_LE format. + * @mod: Pointer to module data. + * @source: Source for PCM samples data. + * @sink: Sink for PCM samples data. + * @frames: Number of audio data frames to process. + * + * This is the processing function for 16-bit signed integer PCM formats. The + * audio samples in every frame are re-order to channels order defined in + * component data channel_map[]. + * + * Return: Value zero for success, otherwise an error code. + */ +int stft_process_sink_s32(struct stft_comp_data *cd, struct sof_sink *sink, int frames) +{ + struct stft_process_state *state = &cd->state; + struct stft_process_buffer *obuf; + int32_t *y, *y_start, *y_end; + int frames_remain = frames; + int channels = cd->channels; + int bytes = frames * cd->frame_bytes; + int y_size; + int ret; + int ch, n1, n, i; + + /* Get pointer to sink data in circular buffer */ + ret = sink_get_buffer_s32(sink, bytes, &y, &y_start, &y_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + y_end = y_start + y_size; + while (frames_remain) { + /* Find out samples to process before first wrap or end of data. */ + obuf = &state->obuf[0]; + n1 = (y_end - y) / cd->channels; + n = stft_process_buffer_samples_without_wrap(obuf, obuf->r_ptr); + n = MIN(n1, n); + n = MIN(n, frames_remain); + + for (i = 0; i < n; i++) { + for (ch = 0; ch < channels; ch++) { + obuf = &state->obuf[ch]; + *y++ = *obuf->r_ptr; + *obuf->r_ptr++ = 0; /* clear overlap add mix */ + } + } + + /* One of the buffers needs a wrap (or end of data), so check for wrap */ + for (ch = 0; ch < cd->channels; ch++) { + obuf = &state->obuf[ch]; + obuf->r_ptr = stft_process_buffer_wrap(obuf, obuf->r_ptr); + } + + if (y >= y_end) + y -= y_size; + + /* Update processed samples count for next loop iteration. */ + frames_remain -= n; + } + + /* Update the sink for bytes produced. Return success. */ + sink_commit_buffer(sink, bytes); + for (ch = 0; ch < channels; ch++) { + obuf = &state->obuf[ch]; + obuf->s_avail -= frames; + obuf->s_free += frames; + } + + return 0; +} +#endif /* CONFIG_FORMAT_S32LE */ + +#if CONFIG_FORMAT_S16LE +/** + * stft_process_source_s16() - Process S16_LE format. + * @mod: Pointer to module data. + * @source: Source for PCM samples data. + * @sink: Sink for PCM samples data. + * @frames: Number of audio data frames to process. + * + * This is the processing function for 16-bit signed integer PCM formats. The + * audio samples in every frame are re-order to channels order defined in + * component data channel_map[]. + * + * Return: Value zero for success, otherwise an error code. + */ +int stft_process_source_s16(struct stft_comp_data *cd, struct sof_source *source, int frames) +{ + struct stft_process_state *state = &cd->state; + struct stft_process_buffer *ibuf; + int16_t const *x, *x_start, *x_end; + int16_t in; + int x_size; + int channels = cd->channels; + int bytes = frames * cd->frame_bytes; + int frames_left = frames; + int ret; + int n1; + int n2; + int n; + int i; + int j; + + /* Get pointer to source data in circular buffer, get buffer start and size to + * check for wrap. The size in bytes is converted to number of s16 samples to + * control the samples process loop. If the number of bytes requested is not + * possible, an error is returned. + */ + ret = source_get_data_s16(source, bytes, &x, &x_start, &x_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + x_end = x_start + x_size; + + while (frames_left) { + /* Find out samples to process before first wrap or end of data. */ + ibuf = &state->ibuf[0]; + n1 = (x_end - x) / cd->channels; + n2 = stft_process_buffer_samples_without_wrap(ibuf, ibuf->w_ptr); + n = MIN(n1, n2); + n = MIN(n, frames_left); + for (i = 0; i < n; i++) { + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + in = *x++; + *ibuf->w_ptr++ = (int32_t)in << 16; + } + } + + /* One of the buffers needs a wrap (or end of data), so check for wrap */ + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + ibuf->w_ptr = stft_process_buffer_wrap(ibuf, ibuf->w_ptr); + } + + if (x >= x_end) + x -= x_size; + + /* Update processed samples count for next loop iteration. */ + frames_left -= n; + } + + /* Update the source for bytes consumed. Return success. */ + source_release_data(source, bytes); + for (j = 0; j < channels; j++) { + ibuf = &state->ibuf[j]; + ibuf->s_avail += frames; + ibuf->s_free -= frames; + } + return 0; +} + +/** + * stft_process_sink_s16() - Process S16_LE format. + * @mod: Pointer to module data. + * @source: Source for PCM samples data. + * @sink: Sink for PCM samples data. + * @frames: Number of audio data frames to process. + * + * This is the processing function for 16-bit signed integer PCM formats. The + * audio samples in every frame are re-order to channels order defined in + * component data channel_map[]. + * + * Return: Value zero for success, otherwise an error code. + */ +int stft_process_sink_s16(struct stft_comp_data *cd, struct sof_sink *sink, int frames) +{ + struct stft_process_state *state = &cd->state; + struct stft_process_buffer *obuf; + int16_t *y, *y_start, *y_end; + int frames_remain = frames; + int channels = cd->channels; + int bytes = frames * cd->frame_bytes; + int y_size; + int ret; + int ch, n1, n, i; + + /* Get pointer to sink data in circular buffer */ + ret = sink_get_buffer_s16(sink, bytes, &y, &y_start, &y_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + y_end = y_start + y_size; + while (frames_remain) { + /* Find out samples to process before first wrap or end of data. */ + obuf = &state->obuf[0]; + n1 = (y_end - y) / cd->channels; + n = stft_process_buffer_samples_without_wrap(obuf, obuf->r_ptr); + n = MIN(n1, n); + n = MIN(n, frames_remain); + + for (i = 0; i < n; i++) { + for (ch = 0; ch < channels; ch++) { + obuf = &state->obuf[ch]; + *y++ = sat_int16(Q_SHIFT_RND(*obuf->r_ptr, 31, 15)); + *obuf->r_ptr++ = 0; /* clear overlap add mix */ + } + } + + /* One of the buffers needs a wrap (or end of data), so check for wrap */ + for (ch = 0; ch < channels; ch++) { + obuf = &state->obuf[ch]; + obuf->r_ptr = stft_process_buffer_wrap(obuf, obuf->r_ptr); + } + + if (y >= y_end) + y -= y_size; + + /* Update processed samples count for next loop iteration. */ + frames_remain -= n; + } + + /* Update the sink for bytes produced. Return success. */ + sink_commit_buffer(sink, bytes); + for (ch = 0; ch < channels; ch++) { + obuf = &state->obuf[ch]; + obuf->s_avail -= frames; + obuf->s_free += frames; + } + + return 0; +} +#endif /* CONFIG_FORMAT_S16LE */ + +void stft_process_fill_prev_samples(struct stft_process_buffer *buf, int32_t *prev_data, + int prev_data_length) +{ + /* Fill prev_data from input buffer */ + int32_t *r = buf->r_ptr; + int32_t *p = prev_data; + int copied; + int nmax; + int n; + + for (copied = 0; copied < prev_data_length; copied += n) { + nmax = prev_data_length - copied; + n = stft_process_buffer_samples_without_wrap(buf, r); + n = MIN(n, nmax); + memcpy(p, r, sizeof(int32_t) * n); /* Not using memcpy_s() due to speed need */ + p += n; + r += n; + r = stft_process_buffer_wrap(buf, r); + } + + buf->s_avail -= copied; + buf->s_free += copied; + buf->r_ptr = r; +} + +void stft_process_fill_fft_buffer(struct stft_process_state *state, int ch) +{ + struct stft_process_buffer *ibuf = &state->ibuf[ch]; + struct stft_process_fft *fft = &state->fft; + int32_t *prev_data = state->prev_data[ch]; + int32_t *r = ibuf->r_ptr; + int copied; + int nmax; + int idx; + int j; + int n; + + /* Copy overlapped samples from state buffer. Imaginary part of input + * remains zero. + */ + for (j = 0; j < state->prev_data_size; j++) { + fft->fft_buf[j].real = prev_data[j]; + fft->fft_buf[j].imag = 0; + } + + /* Copy hop size of new data from circular buffer */ + idx = state->prev_data_size; + for (copied = 0; copied < fft->fft_hop_size; copied += n) { + nmax = fft->fft_hop_size - copied; + n = stft_process_buffer_samples_without_wrap(ibuf, r); + n = MIN(n, nmax); + for (j = 0; j < n; j++) { + fft->fft_buf[idx].real = *r++; + fft->fft_buf[idx].imag = 0; + idx++; + } + r = stft_process_buffer_wrap(ibuf, r); + } + + ibuf->s_avail -= copied; + ibuf->s_free += copied; + ibuf->r_ptr = r; + + /* Copy for next time data back to overlap buffer */ + idx = fft->fft_hop_size; + for (j = 0; j < state->prev_data_size; j++) + prev_data[j] = fft->fft_buf[idx + j].real; +} + +void stft_process_overlap_add_ifft_buffer(struct stft_process_state *state, int ch) +{ + struct stft_process_buffer *obuf = &state->obuf[ch]; + struct stft_process_fft *fft = &state->fft; + int32_t *w = obuf->w_ptr; + int32_t sample; + int i; + int n; + int samples_remain = fft->fft_size; + int idx = fft->fft_fill_start_idx; + + while (samples_remain) { + n = stft_process_buffer_samples_without_wrap(obuf, w); + n = MIN(samples_remain, n); + for (i = 0; i < n; i++) { + sample = Q_MULTSR_32X32((int64_t)state->gain_comp, fft->fft_buf[idx].real, + 31, 31, 31); + *w = sat_int32((int64_t)*w + sample); + w++; + idx++; + } + w = stft_process_buffer_wrap(obuf, w); + samples_remain -= n; + } + + w = obuf->w_ptr + fft->fft_hop_size; + obuf->w_ptr = stft_process_buffer_wrap(obuf, w); + obuf->s_avail += fft->fft_hop_size; + obuf->s_free -= fft->fft_hop_size; +} + +void stft_process_apply_window(struct stft_process_state *state) +{ + struct stft_process_fft *fft = &state->fft; + int j; + int i = fft->fft_fill_start_idx; + + /* Multiply Q1.31 by Q1.15 gives Q2.46, shift right by 15 to get Q2.31, no saturate need */ + for (j = 0; j < fft->fft_size; j++) + fft->fft_buf[i + j].real = + sat_int32(Q_MULTSR_32X32((int64_t)fft->fft_buf[i + j].real, + state->window[j], 31, 31, 31)); +} diff --git a/src/audio/stft_process/stft_process-ipc4.c b/src/audio/stft_process/stft_process-ipc4.c new file mode 100644 index 000000000000..ac6d9b5e56b5 --- /dev/null +++ b/src/audio/stft_process/stft_process-ipc4.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include "stft_process.h" + +LOG_MODULE_DECLARE(stft_process, CONFIG_SOF_LOG_LEVEL); + +/* IPC4 controls handler */ +__cold int stft_process_set_config(struct processing_module *mod, uint32_t param_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, uint8_t *response, + size_t response_size) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + + assert_can_be_cold(); + + switch (param_id) { + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + comp_err(dev, "Illegal control param_id %d.", param_id); + return -EINVAL; + } + + if (fragment_size != sizeof(struct sof_stft_process_config)) { + comp_err(dev, "Illegal fragment size %d, expect %d.", fragment_size, + sizeof(struct sof_stft_process_config)); + return -EINVAL; + } + + if (!cd->config) { + cd->config = mod_alloc(mod, sizeof(struct sof_stft_process_config)); + if (!cd->config) { + comp_err(dev, "Failed to allocate configuration."); + return -ENOMEM; + } + } + + memcpy_s(cd->config, sizeof(struct sof_stft_process_config), fragment, fragment_size); + return 0; +} + +/* Not used in IPC4 systems, if IPC4 only component, omit .get_configuration set */ +__cold int stft_process_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, + size_t fragment_size) +{ + assert_can_be_cold(); + return 0; +} diff --git a/src/audio/stft_process/stft_process.c b/src/audio/stft_process/stft_process.c new file mode 100644 index 000000000000..5fb96a267f15 --- /dev/null +++ b/src/audio/stft_process/stft_process.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include +#include +#include +#include "stft_process.h" + +/* UUID identifies the components. Use e.g. command uuidgen from package + * uuid-runtime, add it to uuid-registry.txt in SOF top level. + */ +SOF_DEFINE_REG_UUID(stft_process); + +/* Creates logging data for the component */ +LOG_MODULE_REGISTER(stft_process, CONFIG_SOF_LOG_LEVEL); + +#if STFT_DEBUG +FILE *stft_debug_fft_in_fh; +FILE *stft_debug_fft_out_fh; +FILE *stft_debug_ifft_out_fh; +#endif + +/** + * stft_process_init() - Initialize the stft_process component. + * @mod: Pointer to module data. + * + * This function is called when the instance is created. The + * macro __cold informs that the code that is non-critical + * is loaded to slower but large DRAM. + * + * Return: Zero if success, otherwise error code. + */ +__cold static int stft_process_init(struct processing_module *mod) +{ + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + struct stft_comp_data *cd; + + assert_can_be_cold(); + + comp_info(dev, "entry"); + + cd = mod_alloc(mod, sizeof(*cd)); + if (!cd) + return -ENOMEM; + + md->private = cd; + memset(cd, 0, sizeof(*cd)); + +#if STFT_DEBUG + stft_debug_fft_in_fh = fopen("stft_debug_fft_in.txt", "w"); + if (!stft_debug_fft_in_fh) { + fprintf(stderr, "Debug file open failed.\n"); + return -EINVAL; + } + + stft_debug_fft_out_fh = fopen("stft_debug_fft_out.txt", "w"); + if (!stft_debug_fft_out_fh) { + fprintf(stderr, "Debug file open failed.\n"); + return -EINVAL; + } + + stft_debug_ifft_out_fh = fopen("stft_debug_ifft_out.txt", "w"); + if (!stft_debug_ifft_out_fh) { + fprintf(stderr, "Debug file open failed.\n"); + fclose(stft_debug_fft_out_fh); + return -EINVAL; + } +#endif + + return 0; +} + +/** + * stft_process_process() - The audio data processing function. + * @mod: Pointer to module data. + * @sources: Pointer to audio samples data sources array. + * @num_of_sources: Number of sources in the array. + * @sinks: Pointer to audio samples data sinks array. + * @num_of_sinks: Number of sinks in the array. + * + * This is the processing function that is called for scheduled + * pipelines. The processing is controlled by the enable switch. + * + * Return: Zero if success, otherwise error code. + */ +static int stft_process_process(struct processing_module *mod, + struct sof_source **sources, + int num_of_sources, + struct sof_sink **sinks, + int num_of_sinks) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct sof_source *source = sources[0]; /* One input in this example */ + struct sof_sink *sink = sinks[0]; /* One output in this example */ + int frames = source_get_data_frames_available(source); + int sink_frames = sink_get_free_frames(sink); + int ret; + + frames = MIN(frames, sink_frames); + + /* Process the data with the channels swap example function. */ + ret = cd->stft_process_func(mod, source, sink, frames); + + return ret; +} + +/** + * stft_process_prepare() - Prepare the component for processing. + * @mod: Pointer to module data. + * @sources: Pointer to audio samples data sources array. + * @num_of_sources: Number of sources in the array. + * @sinks: Pointer to audio samples data sinks array. + * @num_of_sinks: Number of sinks in the array. + * + * Function prepare is called just before the pipeline is started. In + * this case the audio format parameters are for better code performance + * saved to component data to avoid to find out them in process. The + * processing function pointer is set to process the current audio format. + * + * Return: Value zero if success, otherwise error code. + */ +static int stft_process_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + enum sof_ipc_frame source_format; + int ret; + + comp_dbg(dev, "prepare"); + + /* The processing example in this component supports one input and one + * output. Generally there can be more. + */ + if (num_of_sources != 1 || num_of_sinks != 1) { + comp_err(dev, "Only one source and one sink is supported."); + return -EINVAL; + } + + /* Initialize STFT, max_frames is set to dev->frames + 4 */ + if (!cd->config) { + comp_err(dev, "Can't prepare without bytes control configuration."); + return -EINVAL; + } + + /* get source data format */ + cd->max_frames = dev->frames + 2; + cd->frame_bytes = source_get_frame_bytes(sources[0]); + cd->channels = source_get_channels(sources[0]); + source_format = source_get_frm_fmt(sources[0]); + + ret = stft_process_setup(mod, cd->max_frames, source_get_rate(sources[0]), + source_get_channels(sources[0])); + if (ret < 0) { + comp_err(dev, "setup failed."); + return ret; + } + + cd->stft_process_func = stft_process_find_proc_func(source_format); + if (!cd->stft_process_func) { + comp_err(dev, "No processing function found for format %d.", + source_format); + return -EINVAL; + } + + return 0; +} + +/** + * stft_process_reset() - Reset the component. + * @mod: Pointer to module data. + * + * The component reset is called when pipeline is stopped. The reset + * should return the component to same state as init. + * + * Return: Value zero, always success. + */ +static int stft_process_reset(struct processing_module *mod) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + + comp_dbg(mod->dev, "reset"); + + stft_process_free_buffers(mod); + memset(cd, 0, sizeof(*cd)); + return 0; +} + +/** + * stft_process_free() - Free dynamic allocations. + * @mod: Pointer to module data. + * + * Component free is called when the pipelines are deleted. All + * dynamic allocations need to be freed here. The macro __cold + * instructs the build to locate this performance wise non-critical + * function to large and slower DRAM. + * + * Return: Value zero, always success. + */ +__cold static int stft_process_free(struct processing_module *mod) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + + assert_can_be_cold(); + + comp_dbg(mod->dev, "free"); + mod_free(mod, cd); + +#if STFT_DEBUG + fclose(stft_debug_fft_in_fh); + fclose(stft_debug_fft_out_fh); + fclose(stft_debug_ifft_out_fh); +#endif + return 0; +} + +/* This defines the module operations */ +static const struct module_interface stft_process_interface = { + .init = stft_process_init, + .prepare = stft_process_prepare, + .process = stft_process_process, + .set_configuration = stft_process_set_config, + .get_configuration = stft_process_get_config, + .reset = stft_process_reset, + .free = stft_process_free +}; + +/* This controls build of the module. If COMP_MODULE is selected in kconfig + * this is build as dynamically loadable module. + */ +#if CONFIG_COMP_STFT_PROCESS_MODULE + +#include +#include +#include + +static const struct sof_man_module_manifest mod_manifest __section(".module") __used = + SOF_LLEXT_MODULE_MANIFEST("STFT_PROCESS", &stft_process_interface, 1, + SOF_REG_UUID(stft_process), 40); + +SOF_LLEXT_BUILDINFO; + +#else + +DECLARE_TR_CTX(stft_process_tr, SOF_UUID(stft_process_uuid), LOG_LEVEL_INFO); +DECLARE_MODULE_ADAPTER(stft_process_interface, stft_process_uuid, stft_process_tr); +SOF_MODULE_INIT(stft_process, sys_comp_module_stft_process_interface_init); + +#endif diff --git a/src/audio/stft_process/stft_process.h b/src/audio/stft_process/stft_process.h new file mode 100644 index 000000000000..f42313844dca --- /dev/null +++ b/src/audio/stft_process/stft_process.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + * + */ +#ifndef __SOF_AUDIO_STFT_PROCESS_H__ +#define __SOF_AUDIO_STFT_PROCESS_H__ + +#include +#include +#include +#include + +#include +#include + +#if CONFIG_LIBRARY +#define STFT_DEBUG 0 /* Keep zero, produces large files with fprintf() */ +#else +#define STFT_DEBUG 0 +#endif + +#define SOF_STFT_PROCESS_CONFIG_MAX_SIZE 256 /* Max size for configuration data in bytes */ + +enum sof_stft_process_fft_pad_type { + STFT_PAD_END = 0, + STFT_PAD_CENTER = 1, + STFT_PAD_START = 2, +}; + +enum sof_stft_process_fft_window_type { + STFT_RECTANGULAR_WINDOW = 0, + STFT_BLACKMAN_WINDOW = 1, + STFT_HAMMING_WINDOW = 2, + STFT_HANN_WINDOW = 3, + STFT_POVEY_WINDOW = 4, +}; + +struct sof_stft_process_config { + uint32_t size; /**< Size of this struct in bytes */ + uint32_t reserved[8]; + int32_t sample_frequency; /**< Hz. e.g. 16000 */ + int32_t window_gain_comp; /**< Q1.31 gain for IFFT */ + int32_t reserved_32; + int16_t channel; /**< -1 expect mono, 0 left, 1 right, ... */ + int16_t frame_length; /**< samples, e.g. 400 for 25 ms @ 16 kHz*/ + int16_t frame_shift; /**< samples, e.g. 160 for 10 ms @ 16 kHz */ + int16_t reserved_16; + enum sof_stft_process_fft_pad_type pad; /**< Use PAD_END, PAD_CENTER, PAD_START */ + enum sof_stft_process_fft_window_type window; /**< Use RECTANGULAR_WINDOW, etc. */ +} __attribute__((packed)); + +struct stft_process_buffer { + int32_t *addr; + int32_t *end_addr; + int32_t *r_ptr; + int32_t *w_ptr; + int s_avail; /**< samples count */ + int s_free; /**< samples count */ + int s_length; /**< length in samples for wrap */ +}; + +struct stft_process_fft { + struct icomplex32 *fft_buf; /**< fft_padded_size */ + struct icomplex32 *fft_out; /**< fft_padded_size */ + struct fft_multi_plan *fft_plan; + struct fft_multi_plan *ifft_plan; + int fft_fill_start_idx; /**< Set to 0 for pad left, etc. */ + int fft_size; + int fft_padded_size; + int fft_hop_size; + int fft_buf_size; + int half_fft_size; + size_t fft_buffer_size; /**< bytes */ +}; + +struct stft_process_state { + struct stft_process_buffer ibuf[PLATFORM_MAX_CHANNELS]; /**< Buffer for input data */ + struct stft_process_buffer obuf[PLATFORM_MAX_CHANNELS]; /**< Buffer for output data */ + struct stft_process_fft fft; /**< FFT related */ + int32_t *prev_data[PLATFORM_MAX_CHANNELS]; /**< prev_data_size */ + int32_t gain_comp; /**< Gain to compensate window gain */ + int32_t *buffers; + int32_t *window; /**< fft_size */ + int source_channel; + int prev_data_size; + int sample_rate; + bool waiting_fill; /**< booleans */ + bool prev_samples_valid; +}; + +/** + * struct stft_process_func - Function call pointer for process function + * @mod: Pointer to module data. + * @source: Source for PCM samples data. + * @sink: Sink for PCM samples data. + * @frames: Number of audio data frames to process. + */ +typedef int (*stft_process_func)(const struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink, + uint32_t frames); + +/** + * struct stft_comp_data + * @stft_process_func: Pointer to used processing function. + * @channels_order[]: Vector with desired sink channels order. + * @source_format: Source samples format. + * @frame_bytes: Number of bytes in an audio frame. + * @channels: Channels count. + * @enable: Control processing on/off, on - reorder channels + */ +struct stft_comp_data { + stft_process_func stft_process_func; /**< processing function */ + struct stft_process_state state; + struct sof_stft_process_config *config; + size_t frame_bytes; + int source_channel; + int max_frames; + int channels; + bool fft_done; +}; + +static inline int stft_process_buffer_samples_without_wrap(struct stft_process_buffer *buffer, + int32_t *ptr) +{ + return buffer->end_addr - ptr; +} + +static inline int32_t *stft_process_buffer_wrap(struct stft_process_buffer *buffer, int32_t *ptr) +{ + if (ptr >= buffer->end_addr) + ptr -= buffer->s_length; + + return ptr; +} + +/** + * struct stft_process_proc_fnmap - processing functions for frame formats + * @frame_fmt: Current frame format + * @stft_process_proc_func: Function pointer for the suitable processing function + */ +struct stft_process_proc_fnmap { + enum sof_ipc_frame frame_fmt; + stft_process_func stft_process_function; +}; + +/** + * stft_process_find_proc_func() - Find suitable processing function. + * @src_fmt: Enum value for PCM format. + * + * This function finds the suitable processing function to use for + * the used PCM format. If not found, return NULL. + * + * Return: Pointer to processing function for the requested PCM format. + */ +stft_process_func stft_process_find_proc_func(enum sof_ipc_frame src_fmt); + +#if CONFIG_IPC_MAJOR_4 +/** + * stft_process_set_config() - Handle controls set + * @mod: Pointer to module data. + * @param_id: Id to know control type, used to know ALSA control type. + * @pos: Position of the fragment in the large message. + * @data_offset_size: Size of the whole configuration if it is the first or only + * fragment. Otherwise it is offset of the fragment. + * @fragment: Message payload data. + * @fragment_size: Size of this fragment. + * @response_size: Size of response. + * + * This function handles the real-time controls. The ALSA controls have the + * param_id set to indicate the control type. The control ID, from topology, + * is used to separate the controls instances of same type. In control payload + * the num_elems defines to how many channels the control is applied to. + * + * Return: Zero if success, otherwise error code. + */ +int stft_process_set_config(struct processing_module *mod, uint32_t param_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, + uint8_t *response, size_t response_size); +/** + * stft_process_set_config() - Handle controls get + * @mod: Pointer to module data. + * @config_id: Configuration ID. + * @data_offset_size: Size of the whole configuration if it is the first or only + * fragment. Otherwise it is offset of the fragment. + * @fragment: Message payload data. + * @fragment_size: Size of this fragment. + * + * This function is used for controls get. + * + * Return: Zero if success, otherwise error code. + */ +int stft_process_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size); +#else +static inline int stft_process_set_config(struct processing_module *mod, uint32_t param_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, + uint8_t *response, size_t response_size) +{ + return 0; +} + +static inline int stft_process_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, + size_t fragment_size) +{ + return 0; +} +#endif + +int stft_process_setup(struct processing_module *mod, int max_frames, int rate, int channels); + +int stft_process_source_s16(struct stft_comp_data *cd, struct sof_source *source, int frames); + +int stft_process_sink_s16(struct stft_comp_data *cd, struct sof_sink *sink, int frames); + +int stft_process_source_s32(struct stft_comp_data *cd, struct sof_source *source, int frames); + +int stft_process_sink_s32(struct stft_comp_data *cd, struct sof_sink *sink, int frames); + +void stft_process_free_buffers(struct processing_module *mod); + +void stft_process_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, int frames); + +void stft_process_fill_prev_samples(struct stft_process_buffer *buf, int32_t *prev_data, + int prev_data_length); + +void stft_process_fill_fft_buffer(struct stft_process_state *state, int ch); + +void stft_process_apply_window(struct stft_process_state *state); + +void stft_process_overlap_add_ifft_buffer(struct stft_process_state *state, int ch); + +#endif // __SOF_AUDIO_STFT_PROCESS_H__ diff --git a/src/audio/stft_process/stft_process.toml b/src/audio/stft_process/stft_process.toml new file mode 100644 index 000000000000..5e0f3b805c7d --- /dev/null +++ b/src/audio/stft_process/stft_process.toml @@ -0,0 +1,21 @@ +#ifndef LOAD_TYPE +#define LOAD_TYPE "0" +#endif + + REM # Template component module config + [[module.entry]] + name = "STFTPROC" + uuid = UUIDREG_STR_STFT_PROCESS + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = LOAD_TYPE + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + REM # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + REM # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + index = __COUNTER__ diff --git a/src/audio/stft_process/stft_process_common.c b/src/audio/stft_process/stft_process_common.c new file mode 100644 index 000000000000..1eb31934ae0c --- /dev/null +++ b/src/audio/stft_process/stft_process_common.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stft_process.h" + +#include +#include +#include + +#if STFT_DEBUG +extern FILE *stft_debug_fft_in_fh; +extern FILE *stft_debug_fft_out_fh; +extern FILE *stft_debug_ifft_out_fh; + +static void debug_print_to_file_real(FILE *fh, struct icomplex32 *c, int n) +{ + for (int i = 0; i < n; i++) + fprintf(fh, "%d\n", c[i].real); +} + +static void debug_print_to_file_complex(FILE *fh, struct icomplex32 *c, int n) +{ + for (int i = 0; i < n; i++) + fprintf(fh, "%d %d\n", c[i].real, c[i].imag); +} +#endif + +LOG_MODULE_REGISTER(stft_process_common, CONFIG_SOF_LOG_LEVEL); + +/* + * The main processing function for STFT_PROCESS + */ + +static int stft_prepare_fft(struct stft_process_state *state, int channel) +{ + struct stft_process_buffer *ibuf = &state->ibuf[channel]; + struct stft_process_fft *fft = &state->fft; + + /* Wait for FFT hop size of new data */ + if (ibuf->s_avail < fft->fft_hop_size) + return 0; + + return 1; +} + +static void stft_do_fft(struct stft_process_state *state, int ch) +{ + struct stft_process_fft *fft = &state->fft; + + /* Copy data to FFT input buffer from overlap buffer and from new samples buffer */ + stft_process_fill_fft_buffer(state, ch); + + /* Window function */ + stft_process_apply_window(state); + +#if STFT_DEBUG + debug_print_to_file_real(stft_debug_fft_in_fh, fft->fft_buf, fft->fft_size); +#endif + + /* Compute FFT. A full scale s16 sine input with 2^N samples period in low + * part of s32 real part and zero imaginary part gives to output about 0.5 + * full scale 32 bit output to real and imaginary. The scaling is same for + * all FFT sizes. + */ + fft_multi_execute_32(fft->fft_plan, false); + +#if STFT_DEBUG + debug_print_to_file_complex(stft_debug_fft_out_fh, fft->fft_out, fft->fft_size); +#endif +} + +static void stft_do_ifft(struct stft_process_state *state, int ch) +{ + struct stft_process_fft *fft = &state->fft; + + /* Compute IFFT */ + fft_multi_execute_32(fft->ifft_plan, true); + +#if STFT_DEBUG + debug_print_to_file_complex(stft_debug_ifft_out_fh, fft->fft_buf, fft->fft_size); +#endif + + /* Window function */ + stft_process_apply_window(state); + + /* Copy to output buffer */ + stft_process_overlap_add_ifft_buffer(state, ch); +} + +static void stft_do_fft_ifft(const struct processing_module *mod) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct stft_process_state *state = &cd->state; + int num_fft; + int ch; + + for (ch = 0; ch < cd->channels; ch++) { + num_fft = stft_prepare_fft(state, ch); + + if (num_fft) { + stft_do_fft(state, ch); + + /* stft_process(state) */ + + stft_do_ifft(state, ch); + cd->fft_done = true; + } + } +} + +#if CONFIG_FORMAT_S32LE +static int stft_process_output_zeros_s32(struct stft_comp_data *cd, struct sof_sink *sink, + int frames) +{ + int32_t *y, *y_start, *y_end; + int samples = frames * cd->channels; + size_t bytes = samples * sizeof(int32_t); + int samples_without_wrap; + int y_size; + int ret; + + /* Get pointer to sink data in circular buffer, buffer start and size. */ + ret = sink_get_buffer_s32(sink, bytes, &y, &y_start, &y_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + y_end = y_start + y_size; + while (samples) { + /* Find out samples to process before first wrap or end of data. */ + samples_without_wrap = y_end - y; + samples_without_wrap = MIN(samples_without_wrap, samples); + memset(y, 0, samples_without_wrap * sizeof(int32_t)); + y += samples_without_wrap; + + /* Check for wrap */ + if (y >= y_end) + y -= y_size; + + /* Update processed samples count for next loop iteration. */ + samples -= samples_without_wrap; + } + + /* Update the source and sink for bytes consumed and produced. Return success. */ + sink_commit_buffer(sink, bytes); + return 0; +} + +static int stft_process_s32(const struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, uint32_t frames) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + + /* Get samples from source buffer */ + stft_process_source_s32(cd, source, frames); + + /* Do STFT, processing and inverse STFT */ + stft_do_fft_ifft(mod); + + /* Get samples from source buffer */ + if (cd->fft_done) + stft_process_sink_s32(cd, sink, frames); + else + stft_process_output_zeros_s32(cd, sink, frames); + + return 0; +} +#endif /* CONFIG_FORMAT_S32LE */ + +#if CONFIG_FORMAT_S16LE +static int stft_process_output_zeros_s16(struct stft_comp_data *cd, struct sof_sink *sink, + int frames) +{ + int16_t *y, *y_start, *y_end; + int samples = frames * cd->channels; + size_t bytes = samples * sizeof(int16_t); + int samples_without_wrap; + int y_size; + int ret; + + /* Get pointer to sink data in circular buffer, buffer start and size. */ + ret = sink_get_buffer_s16(sink, bytes, &y, &y_start, &y_size); + if (ret) + return ret; + + /* Set helper pointers to buffer end for wrap check. Then loop until all + * samples are processed. + */ + y_end = y_start + y_size; + while (samples) { + /* Find out samples to process before first wrap or end of data. */ + samples_without_wrap = y_end - y; + samples_without_wrap = MIN(samples_without_wrap, samples); + memset(y, 0, samples_without_wrap * sizeof(int16_t)); + y += samples_without_wrap; + + /* Check for wrap */ + if (y >= y_end) + y -= y_size; + + /* Update processed samples count for next loop iteration. */ + samples -= samples_without_wrap; + } + + /* Update the source and sink for bytes consumed and produced. Return success. */ + sink_commit_buffer(sink, bytes); + return 0; +} + +static int stft_process_s16(const struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, uint32_t frames) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + + /* Get samples from source buffer */ + stft_process_source_s16(cd, source, frames); + + /* Do STFT, processing and inverse STFT */ + stft_do_fft_ifft(mod); + + /* Get samples from source buffer */ + if (cd->fft_done) + stft_process_sink_s16(cd, sink, frames); + else + stft_process_output_zeros_s16(cd, sink, frames); + + return 0; +} +#endif /* CONFIG_FORMAT_S16LE */ + +#if CONFIG_FORMAT_S24LE +#endif /* CONFIG_FORMAT_S24LE */ + +/* This struct array defines the used processing functions for + * the PCM formats + */ +const struct stft_process_proc_fnmap stft_process_functions[] = { +#if CONFIG_FORMAT_S16LE + { SOF_IPC_FRAME_S16_LE, stft_process_s16 }, + { SOF_IPC_FRAME_S32_LE, stft_process_s32 }, +#endif +}; + +/** + * stft_process_find_proc_func() - Find suitable processing function. + * @src_fmt: Enum value for PCM format. + * + * This function finds the suitable processing function to use for + * the used PCM format. If not found, return NULL. + * + * Return: Pointer to processing function for the requested PCM format. + */ +stft_process_func stft_process_find_proc_func(enum sof_ipc_frame src_fmt) +{ + int i; + + /* Find suitable processing function from map */ + for (i = 0; i < ARRAY_SIZE(stft_process_functions); i++) + if (src_fmt == stft_process_functions[i].frame_fmt) + return stft_process_functions[i].stft_process_function; + + return NULL; +} diff --git a/src/audio/stft_process/stft_process_setup.c b/src/audio/stft_process/stft_process_setup.c new file mode 100644 index 000000000000..09a59b1f39f6 --- /dev/null +++ b/src/audio/stft_process/stft_process_setup.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include "stft_process.h" + +#include +#include +#include + +/* Definitions for cepstral lifter */ +#define PI_Q23 Q_CONVERT_FLOAT(3.1415926536, 23) +#define TWO_PI_Q23 Q_CONVERT_FLOAT(6.2831853072, 23) +#define ONE_Q9 Q_CONVERT_FLOAT(1, 9) + +#define STFT_MAX_ALLOC_SIZE 65536 + +LOG_MODULE_REGISTER(stft_process_setup, CONFIG_SOF_LOG_LEVEL); + +static void stft_process_init_buffer(struct stft_process_buffer *buf, int32_t *base, int size) +{ + buf->addr = base; + buf->end_addr = base + size; + buf->r_ptr = base; + buf->w_ptr = base; + buf->s_free = size; + buf->s_avail = 0; + buf->s_length = size; +} + +static int stft_process_get_window(struct stft_process_state *state, + enum sof_stft_process_fft_window_type name) +{ + struct stft_process_fft *fft = &state->fft; + + switch (name) { + case STFT_RECTANGULAR_WINDOW: + win_rectangular_32b(state->window, fft->fft_size); + return 0; + case STFT_BLACKMAN_WINDOW: + win_blackman_32b(state->window, fft->fft_size, WIN_BLACKMAN_A0_Q31); + return 0; + case STFT_HAMMING_WINDOW: + win_hamming_32b(state->window, fft->fft_size); + return 0; + case STFT_HANN_WINDOW: + win_hann_32b(state->window, fft->fft_size); + return 0; + + default: + return -EINVAL; + } +} + +/* TODO stft_process setup needs to use the config blob, not hard coded parameters. + * Also this is a too long function. Split to STFT, Mel filter, etc. parts. + */ +int stft_process_setup(struct processing_module *mod, int max_frames, + int sample_rate, int channels) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + struct sof_stft_process_config *config = cd->config; + struct stft_process_state *state = &cd->state; + struct stft_process_fft *fft = &state->fft; + size_t sample_buffers_size; + size_t ibuf_size; + size_t obuf_size; + size_t prev_size; + int32_t *addr; + int ret; + int i; + + comp_dbg(dev, "entry"); + + /* Check size */ + if (config->size != sizeof(struct sof_stft_process_config)) { + comp_err(dev, "Illegal configuration size %d.", config->size); + return -EINVAL; + } + + if (config->sample_frequency != sample_rate) { + comp_err(dev, "Config sample_frequency does not match stream"); + return -EINVAL; + } + + cd->max_frames = max_frames; + state->sample_rate = sample_rate; + + comp_info(dev, "source_channel = %d, stream_channels = %d", + config->channel, channels); + if (config->channel >= channels) { + comp_err(dev, "Illegal channel"); + return -EINVAL; + } + + if (config->channel < 0) + state->source_channel = 0; + else + state->source_channel = config->channel; + + fft->fft_size = config->frame_length; + fft->fft_padded_size = fft->fft_size; /* Same */ + fft->fft_hop_size = config->frame_shift; + fft->half_fft_size = (fft->fft_padded_size >> 1) + 1; + + comp_info(dev, "fft_size = %d, fft_hop_size = %d, window = %d", + fft->fft_size, fft->fft_hop_size, config->window); + + /* Calculated parameters */ + state->prev_data_size = fft->fft_size - fft->fft_hop_size; + ibuf_size = fft->fft_hop_size + cd->max_frames; + obuf_size = fft->fft_size + cd->max_frames; + prev_size = state->prev_data_size; + + /* Allocate buffer input samples, overlap buffer, window */ + sample_buffers_size = sizeof(int32_t) * cd->channels * + (ibuf_size + obuf_size + prev_size + fft->fft_size); + + if (sample_buffers_size > STFT_MAX_ALLOC_SIZE || sample_buffers_size < 0) { + comp_err(dev, "Illegal allocation size"); + return -EINVAL; + } + + state->buffers = mod_balloc(mod, sample_buffers_size); + if (!state->buffers) { + comp_err(dev, "Failed buffer allocate"); + ret = -ENOMEM; + goto exit; + } + + bzero(state->buffers, sample_buffers_size); + addr = state->buffers; + for (i = 0; i < cd->channels; i++) { + stft_process_init_buffer(&state->ibuf[i], addr, ibuf_size); + addr += ibuf_size; + stft_process_init_buffer(&state->obuf[i], addr, obuf_size); + addr += obuf_size; + state->prev_data[i] = addr; + addr += prev_size; + } + state->window = addr; + + /* Allocate buffers for FFT input and output data */ + fft->fft_buffer_size = fft->fft_padded_size * sizeof(struct icomplex32); + fft->fft_buf = mod_balloc(mod, fft->fft_buffer_size); + if (!fft->fft_buf) { + comp_err(dev, "Failed FFT buffer allocate"); + ret = -ENOMEM; + goto free_buffers; + } + + fft->fft_out = mod_balloc(mod, fft->fft_buffer_size); + if (!fft->fft_out) { + comp_err(dev, "Failed FFT output allocate"); + ret = -ENOMEM; + goto free_fft_buf; + } + + fft->fft_fill_start_idx = 0; /* From config pad_type */ + + /* Setup FFT */ + fft->fft_plan = mod_fft_multi_plan_new(mod, fft->fft_buf, fft->fft_out, + fft->fft_padded_size, 32); + if (!fft->fft_plan) { + comp_err(dev, "Failed FFT init"); + ret = -EINVAL; + goto free_fft_out; + } + + fft->ifft_plan = mod_fft_multi_plan_new(mod, fft->fft_out, fft->fft_buf, + fft->fft_padded_size, 32); + if (!fft->ifft_plan) { + comp_err(dev, "Failed IFFT init"); + ret = -EINVAL; + goto free_ifft_out; + } + + /* Setup window */ + ret = stft_process_get_window(state, config->window); + if (ret < 0) { + comp_err(dev, "Failed Window function"); + goto free_window_out; + } + + /* Need to compensate the window function gain */ + state->gain_comp = config->window_gain_comp; + + /* Set initial state for STFT */ + state->waiting_fill = true; + state->prev_samples_valid = false; + + comp_dbg(dev, "done"); + return 0; + +free_window_out: + mod_free(mod, fft->ifft_plan); + +free_ifft_out: + mod_free(mod, fft->fft_plan); + +free_fft_out: + mod_free(mod, fft->fft_out); + +free_fft_buf: + mod_free(mod, fft->fft_buf); + +free_buffers: + mod_free(mod, state->buffers); + +exit: + return ret; +} + +void stft_process_free_buffers(struct processing_module *mod) +{ + struct stft_comp_data *cd = module_get_private_data(mod); + struct stft_process_state *state = &cd->state; + struct stft_process_fft *fft = &state->fft; + + mod_fft_multi_plan_free(mod, fft->ifft_plan); + mod_fft_multi_plan_free(mod, fft->fft_plan); + mod_free(mod, cd->state.fft.fft_buf); + mod_free(mod, cd->state.fft.fft_out); + mod_free(mod, cd->state.buffers); +} diff --git a/src/audio/stft_process/tune/setup_stft_process.m b/src/audio/stft_process/tune/setup_stft_process.m new file mode 100644 index 000000000000..4018a1d7aeb7 --- /dev/null +++ b/src/audio/stft_process/tune/setup_stft_process.m @@ -0,0 +1,185 @@ +% setup_stft_process() +% +% Create binary configuration blob for STFT_PROCESS component. The hex data +% is written to tools/topology/topology1/m4/stft_process/stft_process_config.m4 + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright (c) 2025, Intel Corporation. + +function setup_stft_process(cfg) + + cfg.tools_path = '../../../../tools/'; + cfg.tplg_path = [cfg.tools_path 'topology/topology2/include/components/stft_process/']; + cfg.common_path = [cfg.tools_path 'tune/common']; + cfg.tplg_ver = 2; + cfg.ipc_ver = 4; + cfg.channel = 0; + cfg.sample_frequency = 48000; + + cfg.frame_length = 192; % 4 ms + cfg.frame_shift = 48; % 1 ms + cfg.window_type = 'hann'; + cfg.tplg_fn = 'hann_192_48.conf'; + export_stft_process_setup(cfg); + + cfg.frame_length = 512; % 10.7 ms + cfg.frame_shift = 128; % 2.7 ms + cfg.window_type = 'hann'; + cfg.tplg_fn = 'hann_512_128.conf'; + export_stft_process_setup(cfg); + + cfg.frame_length = 768; % 16 ms + cfg.frame_shift = 120; % 2.5 ms + cfg.window_type = 'hann'; + cfg.tplg_fn = 'hann_768_120.conf'; + export_stft_process_setup(cfg); + + cfg.frame_length = 1024; % 21.3 ms + cfg.frame_shift = 256; % 5.3 ms + cfg.window_type = 'hann'; + cfg.tplg_fn = 'hann_1024_256.conf'; + export_stft_process_setup(cfg); + + cfg.frame_length = 1536; % 32 ms + cfg.frame_shift = 240; % 5 ms + cfg.window_type = 'hann'; + cfg.tplg_fn = 'hann_1536_240.conf'; + export_stft_process_setup(cfg); + +end + +function export_stft_process_setup(cfg) + + % Use blob tool from EQ + addpath(cfg.common_path); + + % Blob size, size plus reserved(8) + current parameters + nbytes_data = 64; + + % Get ABI information + [abi_bytes, nbytes_abi] = sof_get_abi(nbytes_data, cfg.ipc_ver); + + % Initialize correct size uint8 array + nbytes = nbytes_abi + nbytes_data; + b8 = uint8(zeros(1,nbytes)); + + % Insert ABI header + fprintf(1, 'STFT_PROCESS blob size is %d, ABI header is %d, data is %d\n',nbytes, nbytes_abi, nbytes_data); + b8(1:nbytes_abi) = abi_bytes; + j = nbytes_abi + 1; + + % Apply default STFT_PROCESS configuration, first struct header and reserved, then data + [b8, j] = add_w32b(nbytes_data, b8, j); + for i = 1:8 + [b8, j] = add_w32b(0, b8, j); + end + + fft_length = cfg.frame_length; + fft_hop = cfg.frame_shift; + [window_idx, window_gain_comp] = get_window(cfg, fft_length, fft_hop); + + v = q_convert(cfg.sample_frequency, 0); [b8, j] = add_w32b(v, b8, j); + v = q_convert(window_gain_comp, 31); [b8, j] = add_w32b(v, b8, j); + v = 0; [b8, j] = add_w32b(v, b8, j); % reserved + v = cfg.channel; [b8, j] = add_w16b(v, b8, j); + v = fft_length; [b8, j] = add_w16b(v, b8, j); + v = fft_hop; [b8, j] = add_w16b(v, b8, j); + v = 0; [b8, j] = add_w16b(v, b8, j); % reserved + v = 0; [b8, j] = add_w32b(v, b8, j); % enum pad + v = window_idx; [b8, j] = add_w32b(v, b8, j); % enum window + + % Export + switch cfg.tplg_ver + case 2 + sof_tplg2_write([cfg.tplg_path cfg.tplg_fn], b8, "stft_process_config", ... + "Exported STFT_PROCESS configuration", ... + "cd tools/tune/stft_process; octave setup_stft_process.m"); + otherwise + error("Illegal cfg.tplg_ver, use 2 topology v2."); + end + + rmpath(cfg.common_path); + +end + +%% Helper functions + +function [idx, iwg] = get_window(cfg, len, hop) + switch lower(cfg.window_type) + case 'rectangular' + win = boxcar(len); + idx = 0; + case 'blackman' + win = blackman(len); + idx = 1; + case 'hamming' + win = hamming(len); + idx = 2; + case 'hann' + win = hann(len); + idx = 3; + case 'povey' + idx = 4; + n = 0:(len-1); + win = ((1 - cos(2 * pi * n / len)) / 2).^0.85; + otherwise + error('Unknown window type'); + end + iwg = hop / sum(win.^2); +end + +function bytes = w8b(word) + bytes = uint8(zeros(1,1)); + bytes(1) = bitand(word, 255); +end + +function bytes = w16b(word) + sh = [0 -8]; + bytes = uint8(zeros(1,2)); + bytes(1) = bitand(bitshift(word, sh(1)), 255); + bytes(2) = bitand(bitshift(word, sh(2)), 255); +end + +function bytes = w32b(word) + sh = [0 -8 -16 -24]; + bytes = uint8(zeros(1,4)); + bytes(1) = bitand(bitshift(word, sh(1)), 255); + bytes(2) = bitand(bitshift(word, sh(2)), 255); + bytes(3) = bitand(bitshift(word, sh(3)), 255); + bytes(4) = bitand(bitshift(word, sh(4)), 255); +end + +function n = q_convert(val, q) + n = round(val * 2^q); +end + +function [blob8, j] = add_w8b(v, blob8, j) + if j > length(blob8) + error('Blob size is not sufficient'); + end + blob8(j) = w8b(v); + j = j + 1; +end + +function [blob8, j] = add_w16b(v, blob8, j) + if j + 1 > length(blob8) + error('Blob size is not sufficient'); + end + if v < 0 + v = 2^16 + v; + end + blob8(j : j + 1) = w16b(v); + j = j + 2; +end + +function [blob8, j] = add_w32b(v, blob8, j) + if j + 3 > length(blob8) + error('Blob size is not sufficient'); + end + if v < 0 + v = 2^32 + v; + end + blob8(j : j + 3) = w32b(v); + j = j + 4; +end diff --git a/src/audio/tdfb/tdfb.c b/src/audio/tdfb/tdfb.c index 9fc04820ff75..ad88025f7250 100644 --- a/src/audio/tdfb/tdfb.c +++ b/src/audio/tdfb/tdfb.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -44,8 +43,6 @@ LOG_MODULE_REGISTER(tdfb, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(tdfb); -DECLARE_TR_CTX(tdfb_tr, SOF_UUID(tdfb_uuid), LOG_LEVEL_INFO); - static inline int set_func(struct processing_module *mod, enum sof_ipc_frame fmt) { struct tdfb_comp_data *cd = module_get_private_data(mod); @@ -53,24 +50,24 @@ static inline int set_func(struct processing_module *mod, enum sof_ipc_frame fmt switch (fmt) { #if CONFIG_FORMAT_S16LE case SOF_IPC_FRAME_S16_LE: - comp_dbg(mod->dev, "set_func(), SOF_IPC_FRAME_S16_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S16_LE"); cd->tdfb_func = tdfb_fir_s16; break; #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE case SOF_IPC_FRAME_S24_4LE: - comp_dbg(mod->dev, "set_func(), SOF_IPC_FRAME_S24_4LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S24_4LE"); cd->tdfb_func = tdfb_fir_s24; break; #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE case SOF_IPC_FRAME_S32_LE: - comp_dbg(mod->dev, "set_func(), SOF_IPC_FRAME_S32_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S32_LE"); cd->tdfb_func = tdfb_fir_s32; break; #endif /* CONFIG_FORMAT_S32LE */ default: - comp_err(mod->dev, "set_func(), invalid frame_fmt"); + comp_err(mod->dev, "invalid frame_fmt"); return -EINVAL; } return 0; @@ -234,24 +231,24 @@ static inline int set_pass_func(struct processing_module *mod, enum sof_ipc_fram switch (fmt) { #if CONFIG_FORMAT_S16LE case SOF_IPC_FRAME_S16_LE: - comp_dbg(mod->dev, "set_pass_func(), SOF_IPC_FRAME_S16_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S16_LE"); cd->tdfb_func = tdfb_pass_s16; break; #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE case SOF_IPC_FRAME_S24_4LE: - comp_dbg(mod->dev, "set_pass_func(), SOF_IPC_FRAME_S24_4LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S24_4LE"); cd->tdfb_func = tdfb_pass_s24; break; #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE case SOF_IPC_FRAME_S32_LE: - comp_dbg(mod->dev, "set_pass_func(), SOF_IPC_FRAME_S32_LE"); + comp_dbg(mod->dev, "SOF_IPC_FRAME_S32_LE"); cd->tdfb_func = tdfb_pass_s32; break; #endif /* CONFIG_FORMAT_S32LE */ default: - comp_err(mod->dev, "set_pass_func(), invalid frame_fmt"); + comp_err(mod->dev, "invalid frame_fmt"); return -EINVAL; } return 0; @@ -261,15 +258,16 @@ static inline int set_pass_func(struct processing_module *mod, enum sof_ipc_fram * Control code functions next. The processing is in fir_ C modules. */ -static void tdfb_free_delaylines(struct tdfb_comp_data *cd) +static void tdfb_free_delaylines(struct processing_module *mod) { + struct tdfb_comp_data *cd = module_get_private_data(mod); struct fir_state_32x16 *fir = cd->fir; int i = 0; /* Free the common buffer for all EQs and point then * each FIR channel delay line to NULL. */ - rfree(cd->fir_delay); + mod_free(mod, cd->fir_delay); cd->fir_delay = NULL; cd->fir_delay_size = 0; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -327,37 +325,37 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, /* Sanity checks */ if (config->num_output_channels > PLATFORM_MAX_CHANNELS || !config->num_output_channels) { - comp_err(dev, "tdfb_init_coef(), invalid num_output_channels %d", + comp_err(dev, "invalid num_output_channels %d", config->num_output_channels); return -EINVAL; } if (config->num_output_channels != sink_nch) { - comp_err(dev, "tdfb_init_coef(), stream output channels count %d does not match configuration %d", + comp_err(dev, "stream output channels count %d does not match configuration %d", sink_nch, config->num_output_channels); return -EINVAL; } if (config->num_filters > SOF_TDFB_FIR_MAX_COUNT) { - comp_err(dev, "tdfb_init_coef(), invalid num_filters %d", + comp_err(dev, "invalid num_filters %d", config->num_filters); return -EINVAL; } if (config->num_angles > SOF_TDFB_MAX_ANGLES) { - comp_err(dev, "tdfb_init_coef(), invalid num_angles %d", + comp_err(dev, "invalid num_angles %d", config->num_angles); return -EINVAL; } if (config->beam_off_defined > 1) { - comp_err(dev, "tdfb_init_coef(), invalid beam_off_defined %d", + comp_err(dev, "invalid beam_off_defined %d", config->beam_off_defined); return -EINVAL; } if (config->num_mic_locations > SOF_TDFB_MAX_MICROPHONES) { - comp_err(dev, "tdfb_init_coef(), invalid num_mic_locations %d", + comp_err(dev, "invalid num_mic_locations %d", config->num_mic_locations); return -EINVAL; } @@ -367,7 +365,7 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, * A most basic blob has num_angles equals 1. Mic locations data is optional. */ if (config->num_angles == 0 && config->num_mic_locations == 0) { - comp_err(dev, "tdfb_init_coef(), ABI version less than 3.19.1 is not supported."); + comp_err(dev, "ABI version less than 3.19.1 is not supported."); return -EINVAL; } @@ -395,7 +393,7 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, (&cd->filter_angles[config->num_angles]); if ((uint8_t *)&cd->mic_locations[config->num_mic_locations] != (uint8_t *)config + config->size) { - comp_err(dev, "tdfb_init_coef(), invalid config size"); + comp_err(dev, "invalid config size"); return -EINVAL; } @@ -414,14 +412,14 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, idx = cd->filter_angles[min_delta_idx].filter_index; if (cd->beam_on) { - comp_info(dev, "tdfb_init_coef(), angle request %d, found %d, idx %d", + comp_info(dev, "angle request %d, found %d, idx %d", target_az, cd->filter_angles[min_delta_idx].azimuth, idx); } else if (config->beam_off_defined) { cd->output_channel_mix = output_channel_mix_beam_off; idx = config->num_filters * config->num_angles; - comp_info(dev, "tdfb_init_coef(), configure beam off"); + comp_info(dev, "configure beam off"); } else { - comp_info(dev, "tdfb_init_coef(), beam off is not defined, using filter %d, idx %d", + comp_info(dev, "beam off is not defined, using filter %d, idx %d", cd->filter_angles[min_delta_idx].azimuth, idx); } @@ -436,7 +434,7 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, if (s > 0) { size_sum += s; } else { - comp_err(dev, "tdfb_init_coef(), FIR length %d is invalid", + comp_err(dev, "FIR length %d is invalid", coef_data->length); return -EINVAL; } @@ -459,7 +457,7 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch, * used for filters input. */ if (max_ch + 1 > source_nch) { - comp_err(dev, "tdfb_init_coef(), stream input channels count %d is not sufficient for configuration %d", + comp_err(dev, "stream input channels count %d is not sufficient for configuration %d", source_nch, max_ch + 1); return -EINVAL; } @@ -511,12 +509,12 @@ static int tdfb_setup(struct processing_module *mod, int source_nch, int sink_nc if (delay_size > cd->fir_delay_size) { /* Free existing FIR channels data if it was allocated */ - tdfb_free_delaylines(cd); + tdfb_free_delaylines(mod); /* Allocate all FIR channels data in a big chunk and clear it */ - cd->fir_delay = rballoc(SOF_MEM_FLAG_USER, delay_size); + cd->fir_delay = mod_balloc(mod, delay_size); if (!cd->fir_delay) { - comp_err(mod->dev, "tdfb_setup(), delay allocation failed for size %d", + comp_err(mod->dev, "delay allocation failed for size %d", delay_size); return -ENOMEM; } @@ -545,16 +543,16 @@ static int tdfb_init(struct processing_module *mod) int ret; int i; - comp_info(dev, "tdfb_init()"); + comp_info(dev, "entry"); /* Check first that configuration blob size is sane */ if (bs > SOF_TDFB_MAX_SIZE) { - comp_err(dev, "tdfb_init() error: configuration blob size = %zu > %d", + comp_err(dev, "error: configuration blob size = %zu > %d", bs, SOF_TDFB_MAX_SIZE); return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -574,9 +572,9 @@ static int tdfb_init(struct processing_module *mod) goto err_free_cd; /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; goto err; } @@ -599,11 +597,12 @@ static int tdfb_init(struct processing_module *mod) err: /* These are null if not used for IPC version */ - rfree(cd->ctrl_data); + mod_free(mod, cd->ctrl_data); ipc_msg_free(cd->msg); + mod_data_blob_handler_free(mod, cd->model_handler); err_free_cd: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -612,14 +611,14 @@ static int tdfb_free(struct processing_module *mod) { struct tdfb_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "tdfb_free()"); + comp_dbg(mod->dev, "entry"); ipc_msg_free(cd->msg); - tdfb_free_delaylines(cd); - comp_data_blob_handler_free(cd->model_handler); - tdfb_direction_free(cd); - rfree(cd->ctrl_data); - rfree(cd); + tdfb_free_delaylines(mod); + mod_data_blob_handler_free(mod, cd->model_handler); + tdfb_direction_free(mod); + mod_free(mod, cd->ctrl_data); + mod_free(mod, cd); return 0; } @@ -654,7 +653,7 @@ static int tdfb_process(struct processing_module *mod, int frame_count = input_buffers[0].size; int ret; - comp_dbg(dev, "tdfb_process()"); + comp_dbg(dev, "entry"); /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { @@ -663,7 +662,7 @@ static int tdfb_process(struct processing_module *mod, audio_stream_get_channels(sink), audio_stream_get_frm_fmt(source)); if (ret < 0) { - comp_err(dev, "tdfb_process(), failed FIR setup"); + comp_err(dev, "failed FIR setup"); return ret; } } @@ -675,7 +674,7 @@ static int tdfb_process(struct processing_module *mod, audio_stream_get_channels(sink), audio_stream_get_frm_fmt(source)); if (ret < 0) { - comp_err(dev, "tdfb_process(), failed FIR setup"); + comp_err(dev, "failed FIR setup"); return ret; } } @@ -729,7 +728,7 @@ static int tdfb_prepare(struct processing_module *mod, int rate; int ret; - comp_info(dev, "tdfb_prepare()"); + comp_info(dev, "entry"); /* Find source and sink buffers */ sourceb = comp_dev_get_first_data_producer(dev); @@ -761,7 +760,7 @@ static int tdfb_prepare(struct processing_module *mod, ret = tdfb_setup(mod, source_channels, sink_channels, frame_fmt); if (ret < 0) { - comp_err(dev, "tdfb_prepare() error: tdfb_setup failed."); + comp_err(dev, "error: tdfb_setup failed."); goto out; } @@ -780,7 +779,7 @@ static int tdfb_prepare(struct processing_module *mod, comp_dbg(dev, "dev_frames = %d, max_frames = %d", dev->frames, cd->max_frames); /* Initialize tracking */ - ret = tdfb_direction_init(cd, rate, source_channels); + ret = tdfb_direction_init(mod, rate, source_channels); if (!ret) { comp_info(dev, "max_lag = %d, xcorr_size = %zu", cd->direction.max_lag, cd->direction.d_size); @@ -801,9 +800,9 @@ static int tdfb_reset(struct processing_module *mod) struct tdfb_comp_data *cd = module_get_private_data(mod); int i; - comp_dbg(mod->dev, "tdfb_reset()"); + comp_dbg(mod->dev, "entry"); - tdfb_free_delaylines(cd); + tdfb_free_delaylines(mod); cd->tdfb_func = NULL; for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) @@ -840,6 +839,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(tdfb_tr, SOF_UUID(tdfb_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(tdfb_interface, tdfb_uuid, tdfb_tr); SOF_MODULE_INIT(tdfb, sys_comp_module_tdfb_interface_init); diff --git a/src/audio/tdfb/tdfb_comp.h b/src/audio/tdfb/tdfb_comp.h index e2d5075e06b5..ef33f28fa612 100644 --- a/src/audio/tdfb/tdfb_comp.h +++ b/src/audio/tdfb/tdfb_comp.h @@ -118,10 +118,10 @@ void tdfb_fir_s32(struct tdfb_comp_data *cd, struct output_stream_buffer *bsink, int frames); #endif -int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int channels); +int tdfb_direction_init(struct processing_module *mod, int32_t fs, int channels); void tdfb_direction_copy_emphasis(struct tdfb_comp_data *cd, int channels, int *channel, int32_t x); void tdfb_direction_estimate(struct tdfb_comp_data *cd, int frames, int channels); -void tdfb_direction_free(struct tdfb_comp_data *cd); +void tdfb_direction_free(struct processing_module *mod); static inline void tdfb_cinc_s16(int16_t **ptr, int16_t *end, size_t size) { diff --git a/src/audio/tdfb/tdfb_direction.c b/src/audio/tdfb/tdfb_direction.c index 640fe4eaa06e..f83337c9caa4 100644 --- a/src/audio/tdfb/tdfb_direction.c +++ b/src/audio/tdfb/tdfb_direction.c @@ -8,7 +8,6 @@ #include "tdfb_comp.h" #include -#include #include #include #include @@ -176,8 +175,9 @@ static bool line_array_mode_check(struct tdfb_comp_data *cd) return true; } -int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int ch_count) +int tdfb_direction_init(struct processing_module *mod, int32_t fs, int ch_count) { + struct tdfb_comp_data *cd = module_get_private_data(mod); struct sof_eq_iir_header *filt; int32_t *delay; int32_t d_max; @@ -200,7 +200,7 @@ int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int ch_count) /* Allocate delay lines for IIR filters and initialize them */ size = ch_count * iir_delay_size_df1(filt); - delay = rzalloc(SOF_MEM_FLAG_USER, size); + delay = mod_zalloc(mod, size); if (!delay) return -ENOMEM; @@ -225,7 +225,7 @@ int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int ch_count) cd->direction.max_lag = Q_MULTSR_32X32((int64_t)fs, t_max, 0, 15, 0) + 1; n = (cd->max_frames + (2 * cd->direction.max_lag + 1)) * ch_count; cd->direction.d_size = n * sizeof(int16_t); - cd->direction.d = rzalloc(SOF_MEM_FLAG_USER, cd->direction.d_size); + cd->direction.d = mod_zalloc(mod, cd->direction.d_size); if (!cd->direction.d) goto err_free_iir; @@ -238,7 +238,7 @@ int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int ch_count) /* xcorr result is temporary but too large for stack so it is allocated here */ cd->direction.r_size = (2 * cd->direction.max_lag + 1) * sizeof(int32_t); - cd->direction.r = rzalloc(SOF_MEM_FLAG_USER, cd->direction.r_size); + cd->direction.r = mod_zalloc(mod, cd->direction.r_size); if (!cd->direction.r) goto err_free_all; @@ -251,20 +251,22 @@ int tdfb_direction_init(struct tdfb_comp_data *cd, int32_t fs, int ch_count) return 0; err_free_all: - rfree(cd->direction.d); + mod_free(mod, cd->direction.d); cd->direction.d = NULL; err_free_iir: - rfree(cd->direction.df1_delay); + mod_free(mod, cd->direction.df1_delay); cd->direction.df1_delay = NULL; return -ENOMEM; } -void tdfb_direction_free(struct tdfb_comp_data *cd) +void tdfb_direction_free(struct processing_module *mod) { - rfree(cd->direction.df1_delay); - rfree(cd->direction.d); - rfree(cd->direction.r); + struct tdfb_comp_data *cd = module_get_private_data(mod); + + mod_free(mod, cd->direction.df1_delay); + mod_free(mod, cd->direction.d); + mod_free(mod, cd->direction.r); } /* Measure level of one channel */ diff --git a/src/audio/tdfb/tdfb_ipc3.c b/src/audio/tdfb/tdfb_ipc3.c index 52662a141e56..544acbe9a41f 100644 --- a/src/audio/tdfb/tdfb_ipc3.c +++ b/src/audio/tdfb/tdfb_ipc3.c @@ -30,7 +30,7 @@ static int init_get_ctl_ipc(struct processing_module *mod) struct tdfb_comp_data *cd = module_get_private_data(mod); int comp_id = dev_comp_id(mod->dev); - cd->ctrl_data = rzalloc(SOF_MEM_FLAG_USER, TDFB_GET_CTRL_DATA_SIZE); + cd->ctrl_data = mod_zalloc(mod, TDFB_GET_CTRL_DATA_SIZE); if (!cd->ctrl_data) return -ENOMEM; @@ -114,16 +114,16 @@ static int tdfb_cmd_get_value(struct processing_module *mod, struct sof_ipc_ctrl switch (cdata->cmd) { case SOF_CTRL_CMD_ENUM: - comp_dbg(mod->dev, "tdfb_cmd_get_value(), SOF_CTRL_CMD_ENUM index=%d", + comp_dbg(mod->dev, "SOF_CTRL_CMD_ENUM index=%d", cdata->index); return tdfb_cmd_enum_get(cdata, cd); case SOF_CTRL_CMD_SWITCH: - comp_dbg(mod->dev, "tdfb_cmd_get_value(), SOF_CTRL_CMD_SWITCH index=%d", + comp_dbg(mod->dev, "SOF_CTRL_CMD_SWITCH index=%d", cdata->index); return tdfb_cmd_switch_get(cdata, cd); } - comp_err(mod->dev, "tdfb_cmd_get_value() error: invalid cdata->cmd"); + comp_err(mod->dev, "error: invalid cdata->cmd"); return -EINVAL; } @@ -137,7 +137,7 @@ int tdfb_get_ipc_config(struct processing_module *mod, if (cdata->cmd != SOF_CTRL_CMD_BINARY) return tdfb_cmd_get_value(mod, cdata); - comp_dbg(mod->dev, "tdfb_get_ipc_config(), binary"); + comp_dbg(mod->dev, "binary"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -190,16 +190,16 @@ static int tdfb_cmd_set_value(struct processing_module *mod, struct sof_ipc_ctrl switch (cdata->cmd) { case SOF_CTRL_CMD_ENUM: - comp_dbg(mod->dev, "tdfb_cmd_set_value(), SOF_CTRL_CMD_ENUM index=%d", + comp_dbg(mod->dev, "SOF_CTRL_CMD_ENUM index=%d", cdata->index); return tdfb_cmd_enum_set(cdata, cd); case SOF_CTRL_CMD_SWITCH: - comp_dbg(mod->dev, "tdfb_cmd_set_value(), SOF_CTRL_CMD_SWITCH index=%d", + comp_dbg(mod->dev, "SOF_CTRL_CMD_SWITCH index=%d", cdata->index); return tdfb_cmd_switch_set(cdata, cd); } - comp_err(mod->dev, "tdfb_cmd_set_value() error: invalid cdata->cmd"); + comp_err(mod->dev, "error: invalid cdata->cmd"); return -EINVAL; } @@ -215,7 +215,7 @@ int tdfb_set_ipc_config(struct processing_module *mod, uint32_t param_id, if (cdata->cmd != SOF_CTRL_CMD_BINARY) { ret = tdfb_cmd_set_value(mod, cdata); } else { - comp_info(mod->dev, "tdfb_set_ipc_config(), binary"); + comp_info(mod->dev, "binary"); ret = comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); } diff --git a/src/audio/tdfb/tdfb_ipc4.c b/src/audio/tdfb/tdfb_ipc4.c index dd8ddec714c2..2f7e7e865214 100644 --- a/src/audio/tdfb/tdfb_ipc4.c +++ b/src/audio/tdfb/tdfb_ipc4.c @@ -109,7 +109,7 @@ int tdfb_get_ipc_config(struct processing_module *mod, uint32_t param_id, uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) { - comp_err(mod->dev, "tdfb_get_ipc_config, Not supported, should not happen"); + comp_err(mod->dev, "Not supported, should not happen"); return -EINVAL; } @@ -175,7 +175,7 @@ int tdfb_set_ipc_config(struct processing_module *mod, uint32_t param_id, ctl->id, ctl->num_elems); return tdfb_cmd_enum_set(ctl, cd); default: - comp_info(mod->dev, "tdfb_set_ipc_config(), binary"); + comp_info(mod->dev, "binary"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); } diff --git a/src/audio/template/template-ipc3.c b/src/audio/template/template-ipc3.c index 30398b841bcf..ad35389341f6 100644 --- a/src/audio/template/template-ipc3.c +++ b/src/audio/template/template-ipc3.c @@ -25,7 +25,7 @@ __cold int template_set_config(struct processing_module *mod, uint32_t param_id, assert_can_be_cold(); - comp_dbg(dev, "template_set_config()"); + comp_dbg(dev, "entry"); switch (cdata->cmd) { case SOF_CTRL_CMD_SWITCH: @@ -65,7 +65,7 @@ __cold int template_get_config(struct processing_module *mod, assert_can_be_cold(); - comp_info(dev, "template_get_config()"); + comp_info(dev, "entry"); switch (cdata->cmd) { case SOF_CTRL_CMD_SWITCH: diff --git a/src/audio/template/template.c b/src/audio/template/template.c index 20911df27bb2..1bef6668b75e 100644 --- a/src/audio/template/template.c +++ b/src/audio/template/template.c @@ -17,11 +17,6 @@ SOF_DEFINE_REG_UUID(template); /* Creates logging data for the component */ LOG_MODULE_REGISTER(template, CONFIG_SOF_LOG_LEVEL); -/* Creates the compont trace. Traces show in trace console the component - * info, warning, and error messages. - */ -DECLARE_TR_CTX(template_tr, SOF_UUID(template_uuid), LOG_LEVEL_INFO); - /** * template_init() - Initialize the template component. * @mod: Pointer to module data. @@ -38,9 +33,9 @@ __cold static int template_init(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct template_comp_data *cd; - comp_info(dev, "template_init()"); + comp_info(dev, "entry"); - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -74,7 +69,7 @@ static int template_process(struct processing_module *mod, int frames = source_get_data_frames_available(source); int sink_frames = sink_get_free_frames(sink); - comp_dbg(dev, "template_process()"); + comp_dbg(dev, "entry"); frames = MIN(frames, sink_frames); if (cd->enable) @@ -110,7 +105,7 @@ static int template_prepare(struct processing_module *mod, enum sof_ipc_frame source_format; int i; - comp_dbg(dev, "template_prepare()"); + comp_dbg(dev, "entry"); /* The processing example in this component supports one input and one * output. Generally there can be more. @@ -150,7 +145,7 @@ static int template_reset(struct processing_module *mod) { struct template_comp_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "template_reset()"); + comp_dbg(mod->dev, "entry"); memset(cd, 0, sizeof(*cd)); return 0; } @@ -172,8 +167,8 @@ __cold static int template_free(struct processing_module *mod) assert_can_be_cold(); - comp_dbg(mod->dev, "template_free()"); - rfree(cd); + comp_dbg(mod->dev, "entry"); + mod_free(mod, cd); return 0; } @@ -205,6 +200,8 @@ SOF_LLEXT_BUILDINFO; #else +/* Only used for the module adapter trace context, soon to be deprecated */ +DECLARE_TR_CTX(template_tr, SOF_UUID(template_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(template_interface, template_uuid, template_tr); SOF_MODULE_INIT(template, sys_comp_module_template_interface_init); diff --git a/src/audio/tensorflow/tflm-classify.c b/src/audio/tensorflow/tflm-classify.c index 29b4b6a1af74..827f6711bc41 100644 --- a/src/audio/tensorflow/tflm-classify.c +++ b/src/audio/tensorflow/tflm-classify.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -36,8 +35,6 @@ SOF_DEFINE_REG_UUID(tflmcly); LOG_MODULE_REGISTER(tflmcly, CONFIG_SOF_LOG_LEVEL); -DECLARE_TR_CTX(tflm_tr, SOF_UUID(tflmcly_uuid), LOG_LEVEL_INFO); -EXPORT_SYMBOL(tflm_tr); EXPORT_SYMBOL(tflmcly_uuid); EXPORT_SYMBOL(log_const_tflmcly); @@ -59,27 +56,27 @@ __cold static int tflm_init(struct processing_module *mod) assert_can_be_cold(); - comp_info(dev, "tflm_init()"); + comp_info(dev, "entry"); - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; md->private = cd; /* Handler for configuration data */ - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { - comp_err(dev, "comp_data_blob_handler_new() failed."); + comp_err(dev, "mod_data_blob_handler_new() failed."); ret = -ENOMEM; - goto cd_fail; + goto fail; } /* Get configuration data and reset DRC state */ ret = comp_init_data_blob(cd->model_handler, bs, cfg->data); if (ret < 0) { comp_err(dev, "comp_init_data_blob() failed."); - goto cd_fail; + goto fail; } /* hard coded atm */ @@ -89,20 +86,22 @@ __cold static int tflm_init(struct processing_module *mod) ret = TF_SetModel(&cd->tfc, NULL); if (!ret) { comp_err(dev, "failed to set model"); - return ret; + goto fail; } /* initialise ops */ ret = TF_InitOps(&cd->tfc); if (!ret) { comp_err(dev, "failed to init ops"); - return ret; + goto fail; } return ret; -cd_fail: - rfree(cd); +fail: + /* Passing NULL pointer to free functions is Ok */ + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return ret; } @@ -112,8 +111,8 @@ __cold static int tflm_free(struct processing_module *mod) assert_can_be_cold(); - comp_data_blob_handler_free(cd->model_handler); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); return 0; } @@ -128,11 +127,11 @@ __cold static int tflm_set_config(struct processing_module *mod, uint32_t param_ assert_can_be_cold(); - comp_dbg(dev, "tflm_set_config()"); + comp_dbg(dev, "entry"); struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; - comp_info(dev, "tflm_set_config(), bytes control"); + comp_info(dev, "bytes control"); ret = comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -187,7 +186,7 @@ static int tflm_process(struct processing_module *mod, int features = input_buffers[0].size; int ret; - comp_dbg(dev, "tflm_process()"); + comp_dbg(dev, "entry"); /* Window size is TFLM_FEATURE_ELEM_COUNT and we increment * by TFLM_FEATURE_SIZE until buffer empty. @@ -234,6 +233,7 @@ static const struct module_interface tflmcly_interface = { .free = tflm_free }; +DECLARE_TR_CTX(tflm_tr, SOF_UUID(tflmcly_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(tflmcly_interface, tflmcly_uuid, tflm_tr); SOF_MODULE_INIT(tflmcly, sys_comp_module_tflmcly_interface_init); diff --git a/src/audio/tone.c b/src/audio/tone.c deleted file mode 100644 index 39c2ad820581..000000000000 --- a/src/audio/tone.c +++ /dev/null @@ -1,743 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2016 Intel Corporation. All rights reserved. -// -// Author: Seppo Ingalsuo -// Liam Girdwood -// Keyon Jie - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for SHARED_DATA */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Convert float frequency in Hz to Q16.16 fractional format */ -#define TONE_FREQ(f) Q_CONVERT_FLOAT(f, 16) - -/* Convert float gain to Q1.31 fractional format */ -#define TONE_GAIN(v) Q_CONVERT_FLOAT(v, 31) - -/* Set default tone amplitude and frequency */ -#define TONE_AMPLITUDE_DEFAULT TONE_GAIN(0.1) /* -20 dB */ -#define TONE_FREQUENCY_DEFAULT TONE_FREQ(997.0) -#define TONE_NUM_FS 13 /* Table size for 8-192 kHz range */ - -static const struct comp_driver comp_tone; - -LOG_MODULE_REGISTER(tone, CONFIG_SOF_LOG_LEVEL); - -SOF_DEFINE_REG_UUID(tone); - -DECLARE_TR_CTX(tone_tr, SOF_UUID(tone_uuid), LOG_LEVEL_INFO); - -/* 2*pi/Fs lookup tables in Q1.31 for each Fs */ -static const int32_t tone_fs_list[TONE_NUM_FS] = { - 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, - 64000, 88200, 96000, 176400, 192000 -}; - -static const int32_t tone_pi2_div_fs[TONE_NUM_FS] = { - 1686630, 1223858, 843315, 611929, 562210, 421657, 305965, - 281105, 210829, 152982, 140552, 76491, 70276 -}; - -/* tone component private data */ - -struct tone_state { - int mute; - int32_t a; /* Current amplitude Q1.31 */ - int32_t a_target; /* Target amplitude Q1.31 */ - int32_t ampl_coef; /* Amplitude multiplier Q2.30 */ - int32_t c; /* Coefficient 2*pi/Fs Q1.31 */ - int32_t f; /* Frequency Q16.16 */ - int32_t freq_coef; /* Frequency multiplier Q2.30 */ - int32_t fs; /* Sample rate in Hertz Q32.0 */ - int32_t ramp_step; /* Amplitude ramp step Q1.31 */ - int32_t w; /* Angle radians Q4.28 */ - int32_t w_step; /* Angle step Q4.28 */ - uint32_t block_count; - uint32_t repeat_count; - uint32_t repeats; /* Number of repeats for tone (sweep steps) */ - uint32_t sample_count; - uint32_t samples_in_block; /* Samples in 125 us block */ - uint32_t tone_length; /* Active length in 125 us blocks */ - uint32_t tone_period; /* Active + idle time in 125 us blocks */ -}; - -struct comp_data { - uint32_t period_bytes; - uint32_t channels; - uint32_t frame_bytes; - uint32_t rate; - struct tone_state sg[PLATFORM_MAX_CHANNELS]; - void (*tone_func)(struct comp_dev *dev, struct audio_stream *sink, - uint32_t frames); -}; - -static int32_t tonegen(struct tone_state *sg); -static void tonegen_control(struct tone_state *sg); -static void tonegen_update_f(struct tone_state *sg, int32_t f); - -/* - * Tone generator algorithm code - */ - -static inline void tone_circ_inc_wrap(int32_t **ptr, int32_t *end, size_t size) -{ - if (*ptr >= end) - *ptr = (int32_t *)((size_t)*ptr - size); -} - -static void tone_s32_default(struct comp_dev *dev, struct audio_stream *sink, - uint32_t frames) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int32_t *dest = audio_stream_get_wptr(sink); - int i; - int n; - int n_wrap_dest; - int n_min; - int nch = cd->channels; - - n = frames * nch; - while (n > 0) { - n_wrap_dest = (int32_t *)audio_stream_get_end_addr(sink) - dest; - n_min = (n < n_wrap_dest) ? n : n_wrap_dest; - /* Process until wrap or completed n */ - while (n_min > 0) { - n -= nch; - n_min -= nch; - for (i = 0; i < nch; i++) { - tonegen_control(&cd->sg[i]); - *dest = tonegen(&cd->sg[i]); - dest++; - } - } - tone_circ_inc_wrap(&dest, audio_stream_get_end_addr(sink), - audio_stream_get_size(sink)); - } -} - -static int32_t tonegen(struct tone_state *sg) -{ - int64_t sine; - int64_t w; - /* sg->w is angle in Q4.28 radians format, sin() returns Q1.31 */ - /* sg->a is amplitude as Q1.31 */ - sine = - q_mults_32x32(sin_fixed_32b(sg->w), sg->a, - Q_SHIFT_BITS_64(31, 31, 31)); - - /* Next point */ - w = (int64_t)sg->w + sg->w_step; - sg->w = (w > PI_MUL2_Q4_28) - ? (int32_t)(w - PI_MUL2_Q4_28) : (int32_t)w; - - if (sg->mute) - return 0; - else - return (int32_t)sine; /* Q1.31 no saturation need */ -} - -static void tonegen_control(struct tone_state *sg) -{ - int64_t a; - int64_t p; - - /* Count samples, 125 us blocks */ - sg->sample_count++; - if (sg->sample_count < sg->samples_in_block) - return; - - sg->sample_count = 0; - if (sg->block_count < INT32_MAX) - sg->block_count++; - - /* Fade-in ramp during tone */ - if (sg->block_count < sg->tone_length) { - if (sg->a == 0) - sg->w = 0; /* Reset phase to have less clicky ramp */ - - if (sg->a > sg->a_target) { - a = (int64_t)sg->a - sg->ramp_step; - if (a < sg->a_target) - a = sg->a_target; - - } else { - a = (int64_t)sg->a + sg->ramp_step; - if (a > sg->a_target) - a = sg->a_target; - } - sg->a = (int32_t)a; - } - - /* Fade-out ramp after tone*/ - if (sg->block_count > sg->tone_length) { - a = (int64_t)sg->a - sg->ramp_step; - if (a < 0) - a = 0; - - sg->a = (int32_t)a; - } - - /* New repeated tone, update for frequency or amplitude sweep */ - if ((sg->block_count > sg->tone_period) && - (sg->repeat_count + 1 < sg->repeats)) { - sg->block_count = 0; - if (sg->ampl_coef > 0) { - sg->a_target = - sat_int32(q_multsr_32x32(sg->a_target, - sg->ampl_coef, Q_SHIFT_BITS_64(31, 30, 31))); - sg->a = (sg->ramp_step > sg->a_target) - ? sg->a_target : sg->ramp_step; - } - if (sg->freq_coef > 0) { - /* f is Q16.16, freq_coef is Q2.30 */ - p = q_multsr_32x32(sg->f, sg->freq_coef, - Q_SHIFT_BITS_64(16, 30, 16)); - tonegen_update_f(sg, (int32_t)p); /* No saturation */ - } - sg->repeat_count++; - } -} - -/* Set sine amplitude */ -static inline void tonegen_set_a(struct tone_state *sg, int32_t a) -{ - sg->a_target = a; -} - -/* Repeated number of beeps */ -static void tonegen_set_repeats(struct tone_state *sg, uint32_t r) -{ - sg->repeats = r; -} - -/* The next functions support zero as shortcut for defaults to get - * make a nicer API without need to remember the neutral steady - * non-swept tone settings. - */ - -/* Multiplication factor for frequency as Q2.30 for logarithmic change */ -static void tonegen_set_freq_mult(struct tone_state *sg, int32_t fm) -{ - sg->freq_coef = (fm > 0) ? fm : ONE_Q2_30; /* Set freq mult to 1.0 */ -} - -/* Multiplication factor for amplitude as Q2.30 for logarithmic change */ -static void tonegen_set_ampl_mult(struct tone_state *sg, int32_t am) -{ - sg->ampl_coef = (am > 0) ? am : ONE_Q2_30; /* Set ampl mult to 1.0 */ -} - -/* Tone length in samples, this is the active length of tone */ -static void tonegen_set_length(struct tone_state *sg, uint32_t tl) -{ - sg->tone_length = (tl > 0) ? tl : INT32_MAX; /* Count rate 125 us */ -} - -/* Tone period in samples, this is the length including the pause after beep */ -static void tonegen_set_period(struct tone_state *sg, uint32_t tp) -{ - sg->tone_period = (tp > 0) ? tp : INT32_MAX; /* Count rate 125 us */ -} - -/* Tone ramp parameters: - * step - Value that is added or subtracted to amplitude. A zero or negative - * number disables the ramp and amplitude is immediately modified to - * final value. - */ - -static inline void tonegen_set_linramp(struct tone_state *sg, int32_t step) -{ - sg->ramp_step = (step > 0) ? step : INT32_MAX; -} - -static inline int32_t tonegen_get_f(struct tone_state *sg) -{ - return sg->f; -} - -static inline int32_t tonegen_get_a(struct tone_state *sg) -{ - return sg->a_target; -} - -static inline void tonegen_mute(struct tone_state *sg) -{ - sg->mute = 1; -} - -static inline void tonegen_unmute(struct tone_state *sg) -{ - sg->mute = 0; -} - -static void tonegen_update_f(struct tone_state *sg, int32_t f) -{ - int64_t w_tmp; - int64_t f_max; - - /* Calculate Fs/2, fs is Q32.0, f is Q16.16 */ - f_max = Q_SHIFT_LEFT((int64_t)sg->fs, 0, 16 - 1); - f_max = (f_max > INT32_MAX) ? INT32_MAX : f_max; - sg->f = (f > f_max) ? f_max : f; - /* Q16 x Q31 -> Q28 */ - w_tmp = q_multsr_32x32(sg->f, sg->c, Q_SHIFT_BITS_64(16, 31, 28)); - w_tmp = (w_tmp > PI_Q4_28) ? PI_Q4_28 : w_tmp; /* Limit to pi Q4.28 */ - sg->w_step = (int32_t)w_tmp; -} - -static void tonegen_reset(struct tone_state *sg) -{ - sg->mute = 1; - sg->a = 0; - sg->a_target = TONE_AMPLITUDE_DEFAULT; - sg->c = 0; - sg->f = TONE_FREQUENCY_DEFAULT; - sg->w = 0; - sg->w_step = 0; - - sg->block_count = 0; - sg->repeat_count = 0; - sg->repeats = 0; - sg->sample_count = 0; - sg->samples_in_block = 0; - - /* Continuous tone */ - sg->freq_coef = ONE_Q2_30; /* Set freq multiplier to 1.0 */ - sg->ampl_coef = ONE_Q2_30; /* Set ampl multiplier to 1.0 */ - sg->tone_length = INT32_MAX; - sg->tone_period = INT32_MAX; - sg->ramp_step = ONE_Q1_31; /* Set lin ramp modification to max */ -} - -static int tonegen_init(struct tone_state *sg, int32_t fs, int32_t f, int32_t a) -{ - int idx; - int i; - - sg->a_target = a; - sg->a = (sg->ramp_step > sg->a_target) ? sg->a_target : sg->ramp_step; - - idx = -1; - sg->mute = 1; - sg->fs = 0; - - /* Find index of current sample rate and then get from lookup table the - * corresponding 2*pi/Fs value. - */ - for (i = 0; i < TONE_NUM_FS; i++) { - if (fs == tone_fs_list[i]) - idx = i; - } - - if (idx < 0) { - sg->w_step = 0; - return -EINVAL; - } - - sg->fs = fs; - sg->c = tone_pi2_div_fs[idx]; /* Store 2*pi/Fs */ - sg->mute = 0; - tonegen_update_f(sg, f); - - /* 125us as Q1.31 is 268435, calculate fs * 125e-6 in Q31.0 */ - sg->samples_in_block = - (int32_t) q_multsr_32x32(fs, 268435, Q_SHIFT_BITS_64(0, 31, 0)); - - return 0; -} - -/* - * End of algorithm code. Next the standard component methods. - */ - -static struct comp_dev *tone_new(const struct comp_driver *drv, - const struct comp_ipc_config *config, - const void *spec) -{ - struct comp_dev *dev; - const struct ipc_config_tone *ipc_tone = spec; - struct comp_data *cd; - int i; - - comp_cl_info(&comp_tone, "tone_new()"); - - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) - return NULL; - dev->ipc_config = *config; - - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); - if (!cd) { - rfree(dev); - return NULL; - } - - comp_set_drvdata(dev, cd); - cd->tone_func = tone_s32_default; - - cd->rate = ipc_tone->sample_rate; - - /* Reset tone generator and set channels volumes to default */ - for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - tonegen_reset(&cd->sg[i]); - - dev->state = COMP_STATE_READY; - return dev; -} - -static void tone_free(struct comp_dev *dev) -{ - struct tone_data *td = comp_get_drvdata(dev); - - comp_info(dev, "tone_free()"); - - rfree(td); - rfree(dev); -} - -/* set component audio stream parameters */ -static int tone_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) -{ - struct comp_data *cd = comp_get_drvdata(dev); - struct comp_buffer *sourceb, *sinkb; - - sourceb = comp_dev_get_first_data_producer(dev); - sinkb = comp_dev_get_first_data_consumer(dev); - if (!sourceb || !sinkb) { - comp_err(dev, "no source or sink buffer"); - return -ENOTCONN; - } - - comp_info(dev, "tone_params(), config->frame_fmt = %u", - dev->ipc_config.frame_fmt); - - /* Tone supports only S32_LE PCM format atm */ - if (dev->ipc_config.frame_fmt != SOF_IPC_FRAME_S32_LE) - return -EINVAL; - - audio_stream_set_frm_fmt(&sourceb->stream, dev->ipc_config.frame_fmt); - audio_stream_set_frm_fmt(&sinkb->stream, dev->ipc_config.frame_fmt); - - /* calculate period size based on config */ - cd->period_bytes = dev->frames * - audio_stream_frame_bytes(&sourceb->stream); - - return 0; -} - -#if CONFIG_IPC_MAJOR_3 -static int tone_cmd_get_value(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int max_size) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int j; - - comp_info(dev, "tone_cmd_get_value()"); - - if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_GET) { - comp_err(dev, "wrong cdata->type: %u", - cdata->type); - return -EINVAL; - } - - if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { - for (j = 0; j < cdata->num_elems; j++) { - cdata->chanv[j].channel = j; - cdata->chanv[j].value = !cd->sg[j].mute; - comp_info(dev, "tone_cmd_get_value(), j = %u, cd->sg[j].mute = %u", - j, cd->sg[j].mute); - } - } - return 0; -} - -static int tone_cmd_set_value(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int j; - uint32_t ch; - bool val; - - if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_SET) { - comp_err(dev, "wrong cdata->type: %u", - cdata->type); - return -EINVAL; - } - - if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { - comp_info(dev, "tone_cmd_set_value(), SOF_CTRL_CMD_SWITCH"); - for (j = 0; j < cdata->num_elems; j++) { - ch = cdata->chanv[j].channel; - val = cdata->chanv[j].value; - comp_info(dev, "tone_cmd_set_value(), SOF_CTRL_CMD_SWITCH, ch = %u, val = %u", - ch, val); - if (ch >= PLATFORM_MAX_CHANNELS) { - comp_err(dev, "ch >= PLATFORM_MAX_CHANNELS"); - return -EINVAL; - } - - if (val) - tonegen_unmute(&cd->sg[ch]); - else - tonegen_mute(&cd->sg[ch]); - } - } else { - comp_err(dev, "invalid cdata->cmd"); - return -EINVAL; - } - - return 0; -} - -static int tone_cmd_set_data(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) -{ - struct comp_data *cd = comp_get_drvdata(dev); - struct sof_ipc_ctrl_value_comp *compv; - int i; - uint32_t ch; - uint32_t val; - - comp_info(dev, "tone_cmd_set_data()"); - - if (cdata->type != SOF_CTRL_TYPE_VALUE_COMP_SET) { - comp_err(dev, "wrong cdata->type: %u", - cdata->type); - return -EINVAL; - } - - switch (cdata->cmd) { - case SOF_CTRL_CMD_ENUM: - comp_info(dev, "tone_cmd_set_data(), SOF_CTRL_CMD_ENUM, cdata->index = %u", - cdata->index); - compv = (struct sof_ipc_ctrl_value_comp *)ASSUME_ALIGNED(&cdata->data->data, 4); - - for (i = 0; i < (int)cdata->num_elems; i++) { - ch = compv[i].index; - val = compv[i].svalue; - comp_info(dev, "tone_cmd_set_data(), SOF_CTRL_CMD_ENUM, ch = %u, val = %u", - ch, val); - switch (cdata->index) { - case SOF_TONE_IDX_FREQUENCY: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_FREQUENCY"); - tonegen_update_f(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_AMPLITUDE: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_AMPLITUDE"); - tonegen_set_a(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_FREQ_MULT: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_FREQ_MULT"); - tonegen_set_freq_mult(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_AMPL_MULT: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_AMPL_MULT"); - tonegen_set_ampl_mult(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_LENGTH: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_LENGTH"); - tonegen_set_length(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_PERIOD: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_PERIOD"); - tonegen_set_period(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_REPEATS: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_REPEATS"); - tonegen_set_repeats(&cd->sg[ch], val); - break; - case SOF_TONE_IDX_LIN_RAMP_STEP: - comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_LIN_RAMP_STEP"); - tonegen_set_linramp(&cd->sg[ch], val); - break; - default: - comp_err(dev, "invalid cdata->index"); - return -EINVAL; - } - } - break; - default: - comp_err(dev, "invalid cdata->cmd"); - return -EINVAL; - } - - return 0; -} - -/* used to pass standard and bespoke commands (with data) to component */ -static int tone_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) -{ - struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); - int ret = 0; - - comp_info(dev, "tone_cmd()"); - - switch (cmd) { - case COMP_CMD_SET_DATA: - ret = tone_cmd_set_data(dev, cdata); - break; - case COMP_CMD_SET_VALUE: - ret = tone_cmd_set_value(dev, cdata); - break; - case COMP_CMD_GET_VALUE: - ret = tone_cmd_get_value(dev, cdata, max_data_size); - break; - } - - return ret; -} -#endif - -static int tone_trigger(struct comp_dev *dev, int cmd) -{ - comp_info(dev, "tone_trigger()"); - - return comp_set_state(dev, cmd); -} - -/* copy and process stream data from source to sink buffers */ -static int tone_copy(struct comp_dev *dev) -{ - struct comp_buffer *sink; - struct comp_data *cd = comp_get_drvdata(dev); - uint32_t free; - int ret = 0; - - comp_dbg(dev, "tone_copy()"); - - /* tone component sink buffer */ - sink = comp_dev_get_first_data_consumer(dev); - free = audio_stream_get_free_bytes(&sink->stream); - - /* Test that sink has enough free frames. Then run once to maintain - * low latency and steady load for tones. - */ - if (free >= cd->period_bytes) { - /* create tone */ - cd->tone_func(dev, &sink->stream, dev->frames); - buffer_stream_writeback(sink, cd->period_bytes); - - /* calc new free and available */ - comp_update_buffer_produce(sink, cd->period_bytes); - - ret = dev->frames; - } - - return ret; -} - -static int tone_prepare(struct comp_dev *dev) -{ - struct comp_data *cd = comp_get_drvdata(dev); - struct comp_buffer *sourceb; - int32_t f; - int32_t a; - int ret; - int i; - - comp_info(dev, "tone_prepare()"); - - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); - if (ret < 0) - return ret; - - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; - - sourceb = comp_dev_get_first_data_producer(dev); - if (!sourceb) { - comp_err(dev, "no source buffer"); - return -ENOTCONN; - } - - cd->channels = audio_stream_get_channels(&sourceb->stream); - comp_info(dev, "tone_prepare(), cd->channels = %u, cd->rate = %u", - cd->channels, cd->rate); - - for (i = 0; i < cd->channels; i++) { - f = tonegen_get_f(&cd->sg[i]); - a = tonegen_get_a(&cd->sg[i]); - if (tonegen_init(&cd->sg[i], cd->rate, f, a) < 0) { - comp_set_state(dev, COMP_TRIGGER_RESET); - return -EINVAL; - } - } - - return 0; -} - -static int tone_reset(struct comp_dev *dev) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int i; - - comp_info(dev, "tone_reset()"); - - /* Initialize with the defaults */ - for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - tonegen_reset(&cd->sg[i]); - - comp_set_state(dev, COMP_TRIGGER_RESET); - - return 0; -} - -static const struct comp_driver comp_tone = { - .type = SOF_COMP_TONE, - .uid = SOF_RT_UUID(tone_uuid), - .tctx = &tone_tr, - .ops = { - .create = tone_new, - .free = tone_free, - .params = tone_params, -#if CONFIG_IPC_MAJOR_3 - .cmd = tone_cmd, -#endif - .trigger = tone_trigger, - .copy = tone_copy, - .prepare = tone_prepare, - .reset = tone_reset, - }, -}; - -static SHARED_DATA struct comp_driver_info comp_tone_info = { - .drv = &comp_tone, -}; - -UT_STATIC void sys_comp_tone_init(void) -{ - comp_register(platform_shared_get(&comp_tone_info, - sizeof(comp_tone_info))); -} - -DECLARE_MODULE(sys_comp_tone_init); -SOF_MODULE_INIT(tone, sys_comp_tone_init); diff --git a/src/audio/tone/CMakeLists.txt b/src/audio/tone/CMakeLists.txt new file mode 100644 index 000000000000..58f22ec6c59e --- /dev/null +++ b/src/audio/tone/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause + +if(CONFIG_COMP_TONE STREQUAL "m" AND DEFINED CONFIG_LLEXT) + add_subdirectory(llext ${PROJECT_BINARY_DIR}/tone_llext) + add_dependencies(app tone) +else() + if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof tone.c tone-ipc3.c) + elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof tone.c tone-ipc4.c) + endif() +endif() diff --git a/src/audio/tone/Kconfig b/src/audio/tone/Kconfig new file mode 100644 index 000000000000..8cb6f7302497 --- /dev/null +++ b/src/audio/tone/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause + +config COMP_TONE + tristate "Tone component" + default m if LIBRARY_DEFAULT_MODULAR + default y + depends on COMP_MODULE_ADAPTER + depends on IPC_MAJOR_4 + select CORDIC_FIXED + help + Select for Tone component. This component is used to generate + audio tones (sine waves) at specified frequencies when the Tone + mode is enabled. The two other modes it supports are silence where + it generates 0s and passthrough where the input is passed to the + output. Warning: This component is untested with IPC_MAJOR_3 and + is unavailable. diff --git a/src/audio/tone/llext/CMakeLists.txt b/src/audio/tone/llext/CMakeLists.txt new file mode 100644 index 000000000000..39b0894a013a --- /dev/null +++ b/src/audio/tone/llext/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +sof_llext_build("tone" + SOURCES ../tone.c ../tone-ipc4.c + LIB openmodules +) diff --git a/src/audio/tone/llext/llext.toml.h b/src/audio/tone/llext/llext.toml.h new file mode 100644 index 000000000000..20f5940c3555 --- /dev/null +++ b/src/audio/tone/llext/llext.toml.h @@ -0,0 +1,6 @@ +#include +#define LOAD_TYPE "2" +#include "../tone.toml" + +[module] +count = __COUNTER__ diff --git a/src/audio/tone/tone-ipc3.c b/src/audio/tone/tone-ipc3.c new file mode 100644 index 000000000000..b2f153696c20 --- /dev/null +++ b/src/audio/tone/tone-ipc3.c @@ -0,0 +1,409 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2016 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for SHARED_DATA */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tone.h" + +SOF_DEFINE_REG_UUID(tone); +LOG_MODULE_DECLARE(tone, CONFIG_SOF_LOG_LEVEL); + +static const struct comp_driver comp_tone; + +static struct comp_dev *tone_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct comp_dev *dev; + const struct ipc_config_tone *ipc_tone = spec; + struct comp_data *cd; + int i; + + comp_cl_info(&comp_tone, "tone_new()"); + + dev = comp_alloc(drv, sizeof(*dev)); + if (!dev) + return NULL; + dev->ipc_config = *config; + + cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + if (!cd) { + comp_free_device(dev); + return NULL; + } + + comp_set_drvdata(dev, cd); + cd->tone_func = tone_s32_default; + + cd->rate = ipc_tone->sample_rate; + + /* Reset tone generator and set channels volumes to default */ + for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) + tonegen_reset(&cd->sg[i]); + + dev->state = COMP_STATE_READY; + return dev; +} + +static void tone_free(struct comp_dev *dev) +{ + struct tone_data *td = comp_get_drvdata(dev); + + comp_info(dev, "entry"); + + rfree(td); + comp_free_device(dev); +} + +/* set component audio stream parameters */ +static int tone_params(struct comp_dev *dev, + struct sof_ipc_stream_params *params) +{ + struct comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer *sourceb, *sinkb; + + sourceb = comp_dev_get_first_data_producer(dev); + sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + + comp_info(dev, "config->frame_fmt = %u", + dev->ipc_config.frame_fmt); + + /* Tone supports only S32_LE PCM format atm */ + if (dev->ipc_config.frame_fmt != SOF_IPC_FRAME_S32_LE) + return -EINVAL; + + audio_stream_set_frm_fmt(&sourceb->stream, dev->ipc_config.frame_fmt); + audio_stream_set_frm_fmt(&sinkb->stream, dev->ipc_config.frame_fmt); + + /* calculate period size based on config */ + cd->period_bytes = dev->frames * + audio_stream_frame_bytes(&sourceb->stream); + + return 0; +} + +#if CONFIG_IPC_MAJOR_3 +static int tone_cmd_get_value(struct comp_dev *dev, + struct sof_ipc_ctrl_data *cdata, int max_size) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int j; + + comp_info(dev, "entry"); + + if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_GET) { + comp_err(dev, "wrong cdata->type: %u", + cdata->type); + return -EINVAL; + } + + if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { + for (j = 0; j < cdata->num_elems; j++) { + cdata->chanv[j].channel = j; + cdata->chanv[j].value = !cd->sg[j].mute; + comp_info(dev, "j = %u, cd->sg[j].mute = %u", + j, cd->sg[j].mute); + } + } + return 0; +} + +static int tone_cmd_set_value(struct comp_dev *dev, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int j; + uint32_t ch; + bool val; + + if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_SET) { + comp_err(dev, "wrong cdata->type: %u", + cdata->type); + return -EINVAL; + } + + if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { + comp_info(dev, "SOF_CTRL_CMD_SWITCH"); + for (j = 0; j < cdata->num_elems; j++) { + ch = cdata->chanv[j].channel; + val = cdata->chanv[j].value; + comp_info(dev, "SOF_CTRL_CMD_SWITCH, ch = %u, val = %u", + ch, val); + if (ch >= PLATFORM_MAX_CHANNELS) { + comp_err(dev, "ch >= PLATFORM_MAX_CHANNELS"); + return -EINVAL; + } + + if (val) + tonegen_unmute(&cd->sg[ch]); + else + tonegen_mute(&cd->sg[ch]); + } + } else { + comp_err(dev, "invalid cdata->cmd"); + return -EINVAL; + } + + return 0; +} + +static int tone_cmd_set_data(struct comp_dev *dev, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_data *cd = comp_get_drvdata(dev); + struct sof_ipc_ctrl_value_comp *compv; + int i; + uint32_t ch; + uint32_t val; + + comp_info(dev, "entry"); + + if (cdata->type != SOF_CTRL_TYPE_VALUE_COMP_SET) { + comp_err(dev, "wrong cdata->type: %u", + cdata->type); + return -EINVAL; + } + + switch (cdata->cmd) { + case SOF_CTRL_CMD_ENUM: + comp_info(dev, "SOF_CTRL_CMD_ENUM, cdata->index = %u", + cdata->index); + compv = (struct sof_ipc_ctrl_value_comp *)ASSUME_ALIGNED(&cdata->data->data, 4); + + for (i = 0; i < (int)cdata->num_elems; i++) { + ch = compv[i].index; + val = compv[i].svalue; + comp_info(dev, "SOF_CTRL_CMD_ENUM, ch = %u, val = %u", + ch, val); + switch (cdata->index) { + case SOF_TONE_IDX_FREQUENCY: + comp_info(dev, "SOF_TONE_IDX_FREQUENCY"); + tonegen_update_f(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_AMPLITUDE: + comp_info(dev, "SOF_TONE_IDX_AMPLITUDE"); + tonegen_set_a(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_FREQ_MULT: + comp_info(dev, "SOF_TONE_IDX_FREQ_MULT"); + tonegen_set_freq_mult(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_AMPL_MULT: + comp_info(dev, "SOF_TONE_IDX_AMPL_MULT"); + tonegen_set_ampl_mult(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_LENGTH: + comp_info(dev, "SOF_TONE_IDX_LENGTH"); + tonegen_set_length(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_PERIOD: + comp_info(dev, "SOF_TONE_IDX_PERIOD"); + tonegen_set_period(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_REPEATS: + comp_info(dev, "SOF_TONE_IDX_REPEATS"); + tonegen_set_repeats(&cd->sg[ch], val); + break; + case SOF_TONE_IDX_LIN_RAMP_STEP: + comp_info(dev, "SOF_TONE_IDX_LIN_RAMP_STEP"); + tonegen_set_linramp(&cd->sg[ch], val); + break; + default: + comp_err(dev, "invalid cdata->index"); + return -EINVAL; + } + } + break; + default: + comp_err(dev, "invalid cdata->cmd"); + return -EINVAL; + } + + return 0; +} + +/* used to pass standard and bespoke commands (with data) to component */ +static int tone_cmd(struct comp_dev *dev, int cmd, void *data, + int max_data_size) +{ + struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); + int ret = 0; + + comp_info(dev, "entry"); + + switch (cmd) { + case COMP_CMD_SET_DATA: + ret = tone_cmd_set_data(dev, cdata); + break; + case COMP_CMD_SET_VALUE: + ret = tone_cmd_set_value(dev, cdata); + break; + case COMP_CMD_GET_VALUE: + ret = tone_cmd_get_value(dev, cdata, max_data_size); + break; + } + + return ret; +} +#endif + +static int tone_trigger(struct comp_dev *dev, int cmd) +{ + comp_info(dev, "entry"); + + return comp_set_state(dev, cmd); +} + +/* copy and process stream data from source to sink buffers */ +static int tone_copy(struct comp_dev *dev) +{ + struct comp_buffer *sink; + struct comp_data *cd = comp_get_drvdata(dev); + uint32_t free; + int ret = 0; + + comp_dbg(dev, "entry"); + + /* tone component sink buffer */ + sink = comp_dev_get_first_data_consumer(dev); + free = audio_stream_get_free_bytes(&sink->stream); + + /* Test that sink has enough free frames. Then run once to maintain + * low latency and steady load for tones. + */ + if (free >= cd->period_bytes) { + /* create tone */ + cd->tone_func(dev, &sink->stream, dev->frames); + buffer_stream_writeback(sink, cd->period_bytes); + + /* calc new free and available */ + comp_update_buffer_produce(sink, cd->period_bytes); + + ret = dev->frames; + } + + return ret; +} + +static int tone_prepare(struct comp_dev *dev) +{ + struct comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer *sourceb; + int32_t f; + int32_t a; + int ret; + int i; + + comp_info(dev, "entry"); + + ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + if (ret < 0) + return ret; + + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb) { + comp_err(dev, "no source buffer"); + return -ENOTCONN; + } + + cd->channels = audio_stream_get_channels(&sourceb->stream); + comp_info(dev, "cd->channels = %u, cd->rate = %u", + cd->channels, cd->rate); + + for (i = 0; i < cd->channels; i++) { + f = tonegen_get_f(&cd->sg[i]); + a = tonegen_get_a(&cd->sg[i]); + if (tonegen_init(&cd->sg[i], cd->rate, f, a) < 0) { + comp_set_state(dev, COMP_TRIGGER_RESET); + return -EINVAL; + } + } + + return 0; +} + +static int tone_reset(struct comp_dev *dev) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int i; + + comp_info(dev, "entry"); + + /* Initialize with the defaults */ + for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) + tonegen_reset(&cd->sg[i]); + + comp_set_state(dev, COMP_TRIGGER_RESET); + + return 0; +} + +DECLARE_TR_CTX(tone_tr, SOF_UUID(tone_uuid), LOG_LEVEL_INFO); + +static const struct comp_driver comp_tone = { + .type = SOF_COMP_TONE, + .uid = SOF_RT_UUID(tone_uuid), + .tctx = &tone_tr, + .ops = { + .create = tone_new, + .free = tone_free, + .params = tone_params, +#if CONFIG_IPC_MAJOR_3 + .cmd = tone_cmd, +#endif + .trigger = tone_trigger, + .copy = tone_copy, + .prepare = tone_prepare, + .reset = tone_reset, + }, +}; + +static SHARED_DATA struct comp_driver_info comp_tone_info = { + .drv = &comp_tone, +}; + +UT_STATIC void sys_comp_tone_init(void) +{ + comp_register(platform_shared_get(&comp_tone_info, + sizeof(comp_tone_info))); +} + +DECLARE_MODULE(sys_comp_tone_init); +SOF_MODULE_INIT(tone, sys_comp_tone_init); diff --git a/src/audio/tone/tone-ipc4.c b/src/audio/tone/tone-ipc4.c new file mode 100644 index 000000000000..30d99058a3d6 --- /dev/null +++ b/src/audio/tone/tone-ipc4.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2016 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for SHARED_DATA */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tone.h" + +SOF_DEFINE_REG_UUID(tone); +LOG_MODULE_DECLARE(tone, CONFIG_SOF_LOG_LEVEL); + +static int tone_init(struct processing_module *mod) +{ + struct module_data *mod_data = &mod->priv; + struct module_config *mod_config = &mod->priv.cfg; + struct comp_dev *dev = mod->dev; + struct comp_data *cd; + int i; + + cd = mod_alloc(mod, sizeof(*cd)); + if (!cd) + return -ENOMEM; + + mod_data->private = cd; + + /* Tnoe only supports 32-bit format */ + cd->tone_func = tone_s32_default; + + /* + * set direction for the comp. In the case of the tone generator being used for + * echo reference, the number of input pins will be non-zero + */ + if (mod_config->nb_input_pins > 0) { + dev->direction = SOF_IPC_STREAM_CAPTURE; + cd->mode = TONE_MODE_SILENCE; + + } else { + dev->direction = SOF_IPC_STREAM_PLAYBACK; + cd->mode = TONE_MODE_TONEGEN; + } + + dev->direction_set = true; + + /* Reset tone generator and set channels volumes to default */ + for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) + tonegen_reset(&cd->sg[i]); + + return 0; +} + +static int tone_free(struct processing_module *mod) +{ + struct comp_data *cd = module_get_private_data(mod); + + comp_info(mod->dev, "entry"); + + mod_free(mod, cd); + return 0; +} + +/* set component audio stream parameters */ +static int tone_params(struct processing_module *mod) +{ + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + struct comp_buffer *sinkb; + enum sof_ipc_frame frame_fmt, valid_fmt; + + sinkb = comp_dev_get_first_data_consumer(dev); + if (!sinkb) { + comp_err(dev, "no sink buffer found for tone component"); + return -ENOTCONN; + } + + audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, + mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, + &frame_fmt, &valid_fmt, + mod->priv.cfg.base_cfg.audio_fmt.s_type); + cd->rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; + + /* Tone supports only S32_LE PCM format atm */ + if (frame_fmt != SOF_IPC_FRAME_S32_LE) { + comp_err(dev, "unsupported frame_fmt = %u", frame_fmt); + return -EINVAL; + } + + return 0; +} + +/* copy and process stream data from source to sink buffers */ +static int tone_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + struct comp_data *cd = module_get_private_data(mod); + + if (num_of_sources > 0) + return cd->tone_func(mod, sinks[0], sources[0]); + + return cd->tone_func(mod, sinks[0], NULL); +} + +static int tone_prepare(struct processing_module *mod, struct sof_source **sources, + int num_of_sources, struct sof_sink **sinks, int num_of_sinks) +{ + struct comp_data *cd = module_get_private_data(mod); + int32_t f; + int32_t a; + int ret; + int i; + + ret = tone_params(mod); + if (ret < 0) + return ret; + + cd->channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; + + for (i = 0; i < cd->channels; i++) { + f = tonegen_get_f(&cd->sg[i]); + a = tonegen_get_a(&cd->sg[i]); + if (tonegen_init(&cd->sg[i], cd->rate, f, a) < 0) + return -EINVAL; + } + + return 0; +} + +static int tone_reset(struct processing_module *mod) +{ + struct comp_data *cd = module_get_private_data(mod); + int i; + + /* Initialize with the defaults */ + for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) + tonegen_reset(&cd->sg[i]); + + return 0; +} + +static int tone_bind(struct processing_module *mod, struct bind_info *bind_data) +{ + struct comp_data *cd = module_get_private_data(mod); + + /* nothing to do when tone is not the sink */ + if (bind_data->bind_type != COMP_BIND_TYPE_SOURCE) + return 0; + + /* set passthrough mode when tone generator is bound as a sink */ + cd->mode = TONE_MODE_PASSTHROUGH; + + return 0; +} + +static int tone_unbind(struct processing_module *mod, struct bind_info *unbind_data) +{ + struct comp_data *cd = module_get_private_data(mod); + + /* nothing to do when tone is not the sink */ + if (unbind_data->bind_type != COMP_BIND_TYPE_SOURCE) + return 0; + + /* set silence mode when tone generator is unbound from a source module */ + cd->mode = TONE_MODE_SILENCE; + + return 0; +} + +static const struct module_interface tone_interface = { + .init = tone_init, + .prepare = tone_prepare, + .process = tone_process, + .reset = tone_reset, + .free = tone_free, + .bind = tone_bind, + .unbind = tone_unbind, +}; + +#if CONFIG_COMP_TONE_MODULE +/* modular: llext dynamic link */ + +#include +#include +#include + +static const struct sof_man_module_manifest mod_manifest[] __section(".module") __used = { + SOF_LLEXT_MODULE_MANIFEST("TONE", &tone_interface, 1, SOF_REG_UUID(tone), 30), +}; + +SOF_LLEXT_BUILDINFO; + +#else + +DECLARE_TR_CTX(tone_tr, SOF_UUID(tone_uuid), LOG_LEVEL_INFO); +DECLARE_MODULE_ADAPTER(tone_interface, tone_uuid, tone_tr); +SOF_MODULE_INIT(tone, sys_comp_module_tone_interface_init); + +#endif diff --git a/src/audio/tone/tone.c b/src/audio/tone/tone.c new file mode 100644 index 000000000000..975e4ee06bc8 --- /dev/null +++ b/src/audio/tone/tone.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2016 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for SHARED_DATA */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tone.h" + +LOG_MODULE_REGISTER(tone, CONFIG_SOF_LOG_LEVEL); + +static int32_t tonegen(struct tone_state *sg) +{ + int64_t sine; + int64_t w; + /* sg->w is angle in Q4.28 radians format, sin() returns Q1.31 */ + /* sg->a is amplitude as Q1.31 */ + sine = + q_mults_32x32(sin_fixed_32b(sg->w), sg->a, + Q_SHIFT_BITS_64(31, 31, 31)); + + /* Next point */ + w = (int64_t)sg->w + sg->w_step; + sg->w = (w > PI_MUL2_Q4_28) + ? (int32_t)(w - PI_MUL2_Q4_28) : (int32_t)w; + + if (sg->mute) + return 0; + else + return (int32_t)sine; /* Q1.31 no saturation need */ +} + +static void tonegen_control(struct tone_state *sg) +{ + int64_t a; + int64_t p; + + /* Count samples, 125 us blocks */ + sg->sample_count++; + if (sg->sample_count < sg->samples_in_block) + return; + + sg->sample_count = 0; + if (sg->block_count < INT32_MAX) + sg->block_count++; + + /* Fade-in ramp during tone */ + if (sg->block_count < sg->tone_length) { + if (sg->a == 0) + sg->w = 0; /* Reset phase to have less clicky ramp */ + + if (sg->a > sg->a_target) { + a = (int64_t)sg->a - sg->ramp_step; + if (a < sg->a_target) + a = sg->a_target; + + } else { + a = (int64_t)sg->a + sg->ramp_step; + if (a > sg->a_target) + a = sg->a_target; + } + sg->a = (int32_t)a; + } + + /* Fade-out ramp after tone*/ + if (sg->block_count > sg->tone_length) { + a = (int64_t)sg->a - sg->ramp_step; + if (a < 0) + a = 0; + + sg->a = (int32_t)a; + } + + /* New repeated tone, update for frequency or amplitude sweep */ + if (sg->block_count > sg->tone_period && + (sg->repeat_count + 1 < sg->repeats)) { + sg->block_count = 0; + if (sg->ampl_coef > 0) { + sg->a_target = + sat_int32(q_multsr_32x32(sg->a_target, + sg->ampl_coef, + Q_SHIFT_BITS_64(31, 30, 31))); + sg->a = (sg->ramp_step > sg->a_target) + ? sg->a_target : sg->ramp_step; + } + if (sg->freq_coef > 0) { + /* f is Q16.16, freq_coef is Q2.30 */ + p = q_multsr_32x32(sg->f, sg->freq_coef, + Q_SHIFT_BITS_64(16, 30, 16)); + tonegen_update_f(sg, (int32_t)p); /* No saturation */ + } + sg->repeat_count++; + } +} + +static int tone_s32_passthrough(struct processing_module *mod, struct sof_sink *sink, + struct sof_source *source) +{ + struct comp_data *cd = module_get_private_data(mod); + size_t output_frame_bytes, output_frames; + size_t input_frame_bytes, input_frames; + int32_t *output_pos, *output_start, output_cirbuf_size; + int32_t const *input_pos, *input_start, *input_end; + int32_t *output_end, input_cirbuf_size; + uint32_t frames, bytes; + int nch = cd->channels; + int n; + int ret; + + /* tone generator only ever has 1 sink */ + output_frames = sink_get_free_frames(sink); + output_frame_bytes = sink_get_frame_bytes(sink); + output_frames = mod->period_bytes / output_frame_bytes; + + ret = sink_get_buffer_s32(sink, output_frames * output_frame_bytes, + &output_pos, &output_start, &output_cirbuf_size); + if (ret) { + comp_err(mod->dev, "sink_get_buffer_s32() failed"); + return -ENODATA; + } + + input_frames = source_get_data_frames_available(source); + input_frame_bytes = source_get_frame_bytes(source); + + ret = source_get_data_s32(source, input_frames * input_frame_bytes, + &input_pos, &input_start, &input_cirbuf_size); + if (ret) { + comp_err(mod->dev, "source_get_data_s32() failed"); + return -ENODATA; + } + input_end = input_start + input_cirbuf_size; + + frames = MIN(output_frames, input_frames); + + if (frames * output_frame_bytes >= mod->period_bytes) + frames = mod->period_bytes / output_frame_bytes; + bytes = frames * output_frame_bytes; + + output_end = output_start + output_cirbuf_size; + + n = frames * nch; + + while (n > 0) { + int n_wrap_source, n_wrap_dest, n_min; + int i; + + n_wrap_dest = output_end - output_pos; + n_wrap_source = input_end - input_pos; + + /* Process until source/dest wrap or completed n */ + n_min = (n < n_wrap_dest) ? n : n_wrap_dest; + n_min = (n_min < n_wrap_source) ? n_min : n_wrap_source; + while (n_min > 0) { + n -= nch; + n_min -= nch; + for (i = 0; i < nch; i++) { + *output_pos = *input_pos; + output_pos++; + input_pos++; + } + } + + /* Wrap destination/source buffer */ + if (output_pos >= output_end) + output_pos = output_start; + if (input_pos >= input_end) + input_pos = input_start; + } + + ret = sink_commit_buffer(sink, bytes); + if (ret) + return ret; + + return source_release_data(source, bytes); +} + +/* + * Tone generator algorithm code + */ +int tone_s32_default(struct processing_module *mod, struct sof_sink *sink, + struct sof_source *source) +{ + struct comp_data *cd = module_get_private_data(mod); + size_t output_frame_bytes, output_frames; + int32_t *output_pos, *output_start, output_cirbuf_size; + int32_t *output_end; + uint32_t frames, bytes; + int nch = cd->channels; + int i; + int n; + int n_wrap_dest; + int n_min; + int ret; + + if (cd->mode == TONE_MODE_PASSTHROUGH) + return tone_s32_passthrough(mod, sink, source); + + /* tone generator only ever has 1 sink */ + output_frames = sink_get_free_frames(sink); + output_frame_bytes = sink_get_frame_bytes(sink); + output_frames = mod->period_bytes / output_frame_bytes; + + ret = sink_get_buffer_s32(sink, output_frames * output_frame_bytes, + &output_pos, &output_start, &output_cirbuf_size); + if (ret) + return -ENODATA; + + frames = output_frames; + + if (frames * output_frame_bytes >= mod->period_bytes) + frames = mod->period_bytes / output_frame_bytes; + bytes = frames * output_frame_bytes; + + output_end = output_start + output_cirbuf_size; + + n = frames * nch; + if (!source) { + while (n > 0) { + n_wrap_dest = output_end - output_pos; + + /* Process until wrap or completed n */ + n_min = (n < n_wrap_dest) ? n : n_wrap_dest; + while (n_min > 0) { + n -= nch; + n_min -= nch; + for (i = 0; i < nch; i++) { + switch (cd->mode) { + case TONE_MODE_TONEGEN: + tonegen_control(&cd->sg[i]); + *output_pos = tonegen(&cd->sg[i]); + break; + case TONE_MODE_SILENCE: + *output_pos = 0; + break; + default: + break; + } + output_pos++; + } + } + + /* Wrap destination buffer */ + output_pos = output_start; + } + } + + return sink_commit_buffer(sink, bytes); +} + +void tonegen_update_f(struct tone_state *sg, int32_t f) +{ + int64_t w_tmp; + int64_t f_max; + + /* Calculate Fs/2, fs is Q32.0, f is Q16.16 */ + f_max = Q_SHIFT_LEFT((int64_t)sg->fs, 0, 16 - 1); + f_max = (f_max > INT32_MAX) ? INT32_MAX : f_max; + sg->f = (f > f_max) ? f_max : f; + /* Q16 x Q31 -> Q28 */ + w_tmp = q_multsr_32x32(sg->f, sg->c, Q_SHIFT_BITS_64(16, 31, 28)); + w_tmp = (w_tmp > PI_Q4_28) ? PI_Q4_28 : w_tmp; /* Limit to pi Q4.28 */ + sg->w_step = (int32_t)w_tmp; +} + +void tonegen_reset(struct tone_state *sg) +{ + sg->mute = 1; + sg->a = 0; + sg->a_target = TONE_AMPLITUDE_DEFAULT; + sg->c = 0; + sg->f = TONE_FREQUENCY_DEFAULT; + sg->w = 0; + sg->w_step = 0; + + sg->block_count = 0; + sg->repeat_count = 0; + sg->repeats = 0; + sg->sample_count = 0; + sg->samples_in_block = 0; + + /* Continuous tone */ + sg->freq_coef = ONE_Q2_30; /* Set freq multiplier to 1.0 */ + sg->ampl_coef = ONE_Q2_30; /* Set ampl multiplier to 1.0 */ + sg->tone_length = INT32_MAX; + sg->tone_period = INT32_MAX; + sg->ramp_step = ONE_Q1_31; /* Set lin ramp modification to max */ +} + +int tonegen_init(struct tone_state *sg, int32_t fs, int32_t f, int32_t a) +{ + int idx; + int i; + + sg->a_target = a; + sg->a = (sg->ramp_step > sg->a_target) ? sg->a_target : sg->ramp_step; + + idx = -1; + sg->mute = 1; + sg->fs = 0; + + /* Find index of current sample rate and then get from lookup table the + * corresponding 2*pi/Fs value. + */ + for (i = 0; i < TONE_NUM_FS; i++) { + if (fs == tone_fs_list[i]) + idx = i; + } + + if (idx < 0) { + sg->w_step = 0; + return -EINVAL; + } + + sg->fs = fs; + sg->c = tone_pi2_div_fs[idx]; /* Store 2*pi/Fs */ + sg->mute = 0; + tonegen_update_f(sg, f); + + /* 125us as Q1.31 is 268435, calculate fs * 125e-6 in Q31.0 */ + sg->samples_in_block = + (int32_t)q_multsr_32x32(fs, 268435, Q_SHIFT_BITS_64(0, 31, 0)); + + return 0; +} diff --git a/src/audio/tone/tone.h b/src/audio/tone/tone.h new file mode 100644 index 000000000000..4183543e0beb --- /dev/null +++ b/src/audio/tone/tone.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for SHARED_DATA */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Convert float frequency in Hz to Q16.16 fractional format */ +#define TONE_FREQ(f) Q_CONVERT_FLOAT(f, 16) + +/* Convert float gain to Q1.31 fractional format */ +#define TONE_GAIN(v) Q_CONVERT_FLOAT(v, 31) + +/* Set default tone amplitude and frequency */ +#define TONE_AMPLITUDE_DEFAULT TONE_GAIN(0.1) /* -20 dB */ +#define TONE_FREQUENCY_DEFAULT TONE_FREQ(997.0) +#define TONE_NUM_FS 13 /* Table size for 8-192 kHz range */ + +#define TONE_MODE_TONEGEN 0 +#define TONE_MODE_PASSTHROUGH 1 +#define TONE_MODE_SILENCE 2 + +extern struct tr_ctx tone_tr; +extern const struct sof_uuid tone; + +/* 2*pi/Fs lookup tables in Q1.31 for each Fs */ +static const int32_t tone_fs_list[TONE_NUM_FS] = { + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, + 64000, 88200, 96000, 176400, 192000 +}; + +static const int32_t tone_pi2_div_fs[TONE_NUM_FS] = { + 1686630, 1223858, 843315, 611929, 562210, 421657, 305965, + 281105, 210829, 152982, 140552, 76491, 70276 +}; + +/* tone component private data */ + +struct tone_state { + int mute; + int32_t a; /* Current amplitude Q1.31 */ + int32_t a_target; /* Target amplitude Q1.31 */ + int32_t ampl_coef; /* Amplitude multiplier Q2.30 */ + int32_t c; /* Coefficient 2*pi/Fs Q1.31 */ + int32_t f; /* Frequency Q16.16 */ + int32_t freq_coef; /* Frequency multiplier Q2.30 */ + int32_t fs; /* Sample rate in Hertz Q32.0 */ + int32_t ramp_step; /* Amplitude ramp step Q1.31 */ + int32_t w; /* Angle radians Q4.28 */ + int32_t w_step; /* Angle step Q4.28 */ + uint32_t block_count; + uint32_t repeat_count; + uint32_t repeats; /* Number of repeats for tone (sweep steps) */ + uint32_t sample_count; + uint32_t samples_in_block; /* Samples in 125 us block */ + uint32_t tone_length; /* Active length in 125 us blocks */ + uint32_t tone_period; /* Active + idle time in 125 us blocks */ +}; + +struct comp_data { + uint32_t channels; + uint32_t rate; + struct tone_state sg[PLATFORM_MAX_CHANNELS]; + int (*tone_func)(struct processing_module *mod, struct sof_sink *sink, + struct sof_source *source); + int mode; +}; + +void tonegen_reset(struct tone_state *sg); +int tonegen_init(struct tone_state *sg, int32_t fs, int32_t f, int32_t a); +void tonegen_update_f(struct tone_state *sg, int32_t f); +int tone_s32_default(struct processing_module *mod, struct sof_sink *sink, + struct sof_source *source); + +/* Set sine amplitude */ +static inline void tonegen_set_a(struct tone_state *sg, int32_t a) +{ + sg->a_target = a; +} + +/* Repeated number of beeps */ +static inline void tonegen_set_repeats(struct tone_state *sg, uint32_t r) +{ + sg->repeats = r; +} + +/* The next functions support zero as shortcut for defaults to get + * make a nicer API without need to remember the neutral steady + * non-swept tone settings. + */ + +/* Multiplication factor for frequency as Q2.30 for logarithmic change */ +static inline void tonegen_set_freq_mult(struct tone_state *sg, int32_t fm) +{ + sg->freq_coef = (fm > 0) ? fm : ONE_Q2_30; /* Set freq mult to 1.0 */ +} + +/* Multiplication factor for amplitude as Q2.30 for logarithmic change */ +static inline void tonegen_set_ampl_mult(struct tone_state *sg, int32_t am) +{ + sg->ampl_coef = (am > 0) ? am : ONE_Q2_30; /* Set ampl mult to 1.0 */ +} + +/* Tone length in samples, this is the active length of tone */ +static inline void tonegen_set_length(struct tone_state *sg, uint32_t tl) +{ + sg->tone_length = (tl > 0) ? tl : INT32_MAX; /* Count rate 125 us */ +} + +/* Tone period in samples, this is the length including the pause after beep */ +static inline void tonegen_set_period(struct tone_state *sg, uint32_t tp) +{ + sg->tone_period = (tp > 0) ? tp : INT32_MAX; /* Count rate 125 us */ +} + +/* Tone ramp parameters: + * step - Value that is added or subtracted to amplitude. A zero or negative + * number disables the ramp and amplitude is immediately modified to + * final value. + */ + +static inline void tonegen_set_linramp(struct tone_state *sg, int32_t step) +{ + sg->ramp_step = (step > 0) ? step : INT32_MAX; +} + +static inline int32_t tonegen_get_f(struct tone_state *sg) +{ + return sg->f; +} + +static inline int32_t tonegen_get_a(struct tone_state *sg) +{ + return sg->a_target; +} + +static inline void tonegen_mute(struct tone_state *sg) +{ + sg->mute = 1; +} + +static inline void tonegen_unmute(struct tone_state *sg) +{ + sg->mute = 0; +} diff --git a/src/audio/tone/tone.toml b/src/audio/tone/tone.toml new file mode 100644 index 000000000000..02d6e5dca96b --- /dev/null +++ b/src/audio/tone/tone.toml @@ -0,0 +1,22 @@ +#ifndef LOAD_TYPE +#define LOAD_TYPE "0" +#endif + + REM # Template component module config + [[module.entry]] + name = "TONE" + uuid = UUIDREG_STR_TONE + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = LOAD_TYPE + init_config = "1" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + REM # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + REM # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + index = __COUNTER__ diff --git a/src/audio/up_down_mixer/up_down_mixer.c b/src/audio/up_down_mixer/up_down_mixer.c index 3cc8308ad62d..a5843026710a 100644 --- a/src/audio/up_down_mixer/up_down_mixer.c +++ b/src/audio/up_down_mixer/up_down_mixer.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -33,9 +32,6 @@ LOG_MODULE_REGISTER(up_down_mixer, CONFIG_SOF_LOG_LEVEL); /* these ids aligns windows driver requirement to support windows driver */ SOF_DEFINE_REG_UUID(up_down_mixer); -DECLARE_TR_CTX(up_down_mixer_comp_tr, SOF_UUID(up_down_mixer_uuid), - LOG_LEVEL_INFO); - int32_t custom_coeffs[UP_DOWN_MIX_COEFFS_LENGTH]; static int set_downmix_coefficients(struct processing_module *mod, @@ -326,9 +322,9 @@ static int up_down_mixer_free(struct processing_module *mod) { struct up_down_mixer_data *cd = module_get_private_data(mod); - rfree(cd->buf_in); - rfree(cd->buf_out); - rfree(cd); + mod_free(mod, cd->buf_in); + mod_free(mod, cd->buf_out); + mod_free(mod, cd); return 0; } @@ -342,7 +338,7 @@ static int up_down_mixer_init(struct processing_module *mod) struct up_down_mixer_data *cd; int ret; - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) { comp_free(dev); return -ENOMEM; @@ -350,8 +346,8 @@ static int up_down_mixer_init(struct processing_module *mod) mod_data->private = cd; - cd->buf_in = rballoc(SOF_MEM_FLAG_USER, mod->priv.cfg.base_cfg.ibs); - cd->buf_out = rballoc(SOF_MEM_FLAG_USER, mod->priv.cfg.base_cfg.obs); + cd->buf_in = mod_balloc(mod, mod->priv.cfg.base_cfg.ibs); + cd->buf_out = mod_balloc(mod, mod->priv.cfg.base_cfg.obs); if (!cd->buf_in || !cd->buf_out) { ret = -ENOMEM; goto err; @@ -408,7 +404,7 @@ up_down_mixer_process(struct processing_module *mod, const uint8_t *input0_pos, *input0_start; uint8_t *output_pos, *output_start; - comp_dbg(dev, "up_down_mixer_process()"); + comp_dbg(dev, "entry"); output_frames = sink_get_free_frames(output_buffers[0]); input_frames = source_get_data_frames_available(input_buffers[0]); @@ -448,5 +444,6 @@ static const struct module_interface up_down_mixer_interface = { .free = up_down_mixer_free }; +DECLARE_TR_CTX(up_down_mixer_comp_tr, SOF_UUID(up_down_mixer_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(up_down_mixer_interface, up_down_mixer_uuid, up_down_mixer_comp_tr); SOF_MODULE_INIT(up_down_mixer, sys_comp_module_up_down_mixer_interface_init); diff --git a/src/audio/up_down_mixer/up_down_mixer.toml b/src/audio/up_down_mixer/up_down_mixer.toml index f233e44fa6aa..713cff7a87d8 100644 --- a/src/audio/up_down_mixer/up_down_mixer.toml +++ b/src/audio/up_down_mixer/up_down_mixer.toml @@ -65,7 +65,7 @@ 16, 0, 0, 0, 216, 4596000, 768, 1152, 0, 4596, 0, 17, 0, 0, 0, 216, 5572000, 1536, 1152, 0, 5572, 0, 18, 0, 0, 0, 216, 4896000, 384, 1536, 0, 4896, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 216, 4841000, 384, 192, 0, 4841, 0, 1, 0, 0, 0, 216, 4355000, 384, 384, 0, 4355, 0, 2, 0, 0, 0, 216, 5079000, 576, 384, 0, 5079, 0, diff --git a/src/audio/volume/llext/CMakeLists.txt b/src/audio/volume/llext/CMakeLists.txt index ca33117f0a67..edaeec449450 100644 --- a/src/audio/volume/llext/CMakeLists.txt +++ b/src/audio/volume/llext/CMakeLists.txt @@ -5,9 +5,11 @@ sof_llext_build("volume" SOURCES ../volume_generic.c ../volume_hifi3.c ../volume_hifi4.c + ../volume_hifi5.c ../volume_generic_with_peakvol.c ../volume_hifi3_with_peakvol.c ../volume_hifi4_with_peakvol.c + ../volume_hifi5_with_peakvol.c ../volume.c ../volume_ipc4.c LIB openmodules diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index 9f8aff265226..aed356a3ec83 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -490,14 +489,14 @@ int volume_set_chan(struct processing_module *mod, int chan, */ if (v < cd->vol_min) { /* No need to fail, just trace the event. */ - comp_warn(mod->dev, "volume_set_chan: Limited request %d to min. %d", + comp_warn(mod->dev, "Limited request %d to min. %d", v, cd->vol_min); v = cd->vol_min; } if (v > cd->vol_max) { /* No need to fail, just trace the event. */ - comp_warn(mod->dev, "volume_set_chan: Limited request %d to max. %d", + comp_warn(mod->dev, "Limited request %d to max. %d", v, cd->vol_max); v = cd->vol_max; } @@ -561,7 +560,7 @@ static int volume_process(struct processing_module *mod, uint32_t frames; int64_t prev_sum = 0; - comp_dbg(mod->dev, "volume_process()"); + comp_dbg(mod->dev, "entry"); while (avail_frames) { #if CONFIG_COMP_PEAK_VOL @@ -671,7 +670,7 @@ static int volume_prepare(struct processing_module *mod, int ret; int i; - comp_dbg(dev, "volume_prepare()"); + comp_dbg(dev, "entry"); /* volume component will only ever have 1 sink and source buffer */ sinkb = comp_dev_get_first_data_consumer(dev); @@ -761,7 +760,7 @@ static int volume_reset(struct processing_module *mod) { struct vol_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "volume_reset()"); + comp_dbg(mod->dev, "entry"); volume_reset_state(cd); return 0; } @@ -774,11 +773,11 @@ static int volume_free(struct processing_module *mod) { struct vol_data *cd = module_get_private_data(mod); - comp_dbg(mod->dev, "volume_free()"); + comp_dbg(mod->dev, "entry"); - volume_peak_free(cd); - rfree(cd->vol); - rfree(cd); + volume_peak_free(mod); + mod_free(mod, cd->vol); + mod_free(mod, cd); return 0; } diff --git a/src/audio/volume/volume.h b/src/audio/volume/volume.h index 7e7c41ea00d7..9d1d08a280fe 100644 --- a/src/audio/volume/volume.h +++ b/src/audio/volume/volume.h @@ -300,7 +300,7 @@ void sys_comp_module_volume_interface_init(void); /* source_or_sink, true means source, false means sink */ void set_volume_process(struct vol_data *cd, struct comp_dev *dev, bool source_or_sink); -void volume_peak_free(struct vol_data *cd); +void volume_peak_free(struct processing_module *mod); int volume_peak_prepare(struct vol_data *cd, struct processing_module *mod); diff --git a/src/audio/volume/volume.toml b/src/audio/volume/volume.toml index fed4defb37de..0c30281def81 100644 --- a/src/audio/volume/volume.toml +++ b/src/audio/volume/volume.toml @@ -31,7 +31,7 @@ 2, 0, 0, 0, 480, 6846000, 720, 720, 0, 6846, 0, 3, 0, 0, 0, 480, 7212000, 768, 768, 0, 7212, 0, 4, 0, 0, 0, 480, 9532000, 1536, 1536, 0, 9532, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 480, 6993000, 384, 384, 0, 6993, 0, 1, 0, 0, 0, 480, 6385000, 192, 192, 0, 6385, 0, 2, 0, 0, 0, 480, 10887000, 720, 720, 0, 10887, 0, @@ -71,7 +71,7 @@ 2, 0, 0, 0, 416, 7882000, 512, 512, 0, 7882, 0, 3, 0, 0, 0, 416, 5170000, 128, 128, 0, 5170, 0, 4, 0, 0, 0, 416, 5908000, 768, 768, 0, 0, 0] -#elif CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 mod_cfg = [0, 0, 0, 0, 416, 11865000, 1536, 1536, 0, 11865, 0, 1, 0, 0, 0, 416, 7797000, 384, 384, 1, 7797, 1, 2, 0, 0, 0, 416, 12083000, 512, 512, 2, 12083, 2, diff --git a/src/audio/volume/volume_ipc3.c b/src/audio/volume/volume_ipc3.c index e83ebf25cff1..99a9a9c57ce1 100644 --- a/src/audio/volume/volume_ipc3.c +++ b/src/audio/volume/volume_ipc3.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -81,7 +80,7 @@ int volume_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct vol_data)); + cd = mod_zalloc(mod, sizeof(struct vol_data)); if (!cd) return -ENOMEM; @@ -89,9 +88,9 @@ int volume_init(struct processing_module *mod) * malloc memory to store current volume 4 times to ensure the address * is 8-byte aligned for multi-way xtensa intrinsic operations. */ - cd->vol = rmalloc(SOF_MEM_FLAG_USER, vol_size); + cd->vol = mod_alloc_align(mod, vol_size, SOF_FRAME_BYTE_ALIGN); if (!cd->vol) { - rfree(cd); + mod_free(mod, cd); comp_err(dev, "Failed to allocate %zu", vol_size); return -ENOMEM; } @@ -158,8 +157,8 @@ int volume_init(struct processing_module *mod) break; default: comp_err(dev, "invalid ramp type %d", vol->ramp); - rfree(cd); - rfree(cd->vol); + mod_free(mod, cd); + mod_free(mod, cd->vol); return -EINVAL; } @@ -168,7 +167,7 @@ int volume_init(struct processing_module *mod) return 0; } -void volume_peak_free(struct vol_data *cd) +void volume_peak_free(struct processing_module *mod) { } @@ -185,7 +184,7 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, int j; int ret = 0; - comp_dbg(dev, "volume_set_config()"); + comp_dbg(dev, "entry"); /* validate */ if (cdata->num_elems == 0 || cdata->num_elems > SOF_IPC_MAX_CHANNELS) { @@ -195,16 +194,16 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, switch (cdata->cmd) { case SOF_CTRL_CMD_VOLUME: - comp_dbg(dev, "volume_set_config(), SOF_CTRL_CMD_VOLUME, cdata->comp_id = %u", + comp_dbg(dev, "SOF_CTRL_CMD_VOLUME, cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { ch = cdata->chanv[j].channel; val = cdata->chanv[j].value; - comp_dbg(dev, "volume_set_config(), channel = %d, value = %u", + comp_dbg(dev, "channel = %d, value = %u", ch, val); if (ch >= SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "volume_set_config(), illegal channel = %d", + comp_err(dev, "illegal channel = %d", ch); return -EINVAL; } @@ -223,15 +222,15 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, break; case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "volume_set_config(), SOF_CTRL_CMD_SWITCH, cdata->comp_id = %u", + comp_dbg(dev, "SOF_CTRL_CMD_SWITCH, cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { ch = cdata->chanv[j].channel; val = cdata->chanv[j].value; - comp_dbg(dev, "volume_set_config(), channel = %d, value = %u", + comp_dbg(dev, "channel = %d, value = %u", ch, val); if (ch >= SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "volume_set_config(), illegal channel = %d", + comp_err(dev, "illegal channel = %d", ch); return -EINVAL; } @@ -262,7 +261,7 @@ int volume_get_config(struct processing_module *mod, struct comp_dev *dev = mod->dev; int j; - comp_dbg(dev, "volume_get_config()"); + comp_dbg(dev, "entry"); /* validate */ if (cdata->num_elems == 0 || cdata->num_elems > SOF_IPC_MAX_CHANNELS) { @@ -276,7 +275,7 @@ int volume_get_config(struct processing_module *mod, for (j = 0; j < cdata->num_elems; j++) { cdata->chanv[j].channel = j; cdata->chanv[j].value = cd->tvolume[j]; - comp_dbg(dev, "volume_get_config(), channel = %u, value = %u", + comp_dbg(dev, "channel = %u, value = %u", cdata->chanv[j].channel, cdata->chanv[j].value); } @@ -285,7 +284,7 @@ int volume_get_config(struct processing_module *mod, for (j = 0; j < cdata->num_elems; j++) { cdata->chanv[j].channel = j; cdata->chanv[j].value = !cd->muted[j]; - comp_dbg(dev, "volume_get_config(), channel = %u, value = %u", + comp_dbg(dev, "channel = %u, value = %u", cdata->chanv[j].channel, cdata->chanv[j].value); } diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 889008657e8e..57a5f427903e 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -128,7 +127,7 @@ int volume_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct vol_data)); + cd = mod_zalloc(mod, sizeof(struct vol_data)); if (!cd) return -ENOMEM; @@ -136,9 +135,9 @@ int volume_init(struct processing_module *mod) * malloc memory to store current volume 4 times to ensure the address * is 8-byte aligned for multi-way xtensa intrinsic operations. */ - cd->vol = rmalloc(SOF_MEM_FLAG_USER, vol_size); + cd->vol = mod_alloc_align(mod, vol_size, SOF_FRAME_BYTE_ALIGN); if (!cd->vol) { - rfree(cd); + mod_free(mod, cd); comp_err(dev, "Failed to allocate %d", vol_size); return -ENOMEM; } @@ -146,10 +145,10 @@ int volume_init(struct processing_module *mod) /* malloc memory to store temp peak volume 4 times to ensure the address * is 8-byte aligned for multi-way xtensa intrinsic operations. */ - cd->peak_vol = rzalloc(SOF_MEM_FLAG_USER, vol_size); + cd->peak_vol = mod_zalloc(mod, vol_size); if (!cd->peak_vol) { - rfree(cd->vol); - rfree(cd); + mod_free(mod, cd->vol); + mod_free(mod, cd); comp_err(dev, "Failed to allocate %d for peak_vol", vol_size); return -ENOMEM; } @@ -189,14 +188,15 @@ int volume_init(struct processing_module *mod) return 0; } -void volume_peak_free(struct vol_data *cd) +void volume_peak_free(struct processing_module *mod) { + struct vol_data *cd = module_get_private_data(mod); struct ipc4_peak_volume_regs regs; /* clear mailbox */ memset_s(®s, sizeof(regs), 0, sizeof(regs)); mailbox_sw_regs_write(cd->mailbox_offset, ®s, sizeof(regs)); - rfree(cd->peak_vol); + mod_free(mod, cd->peak_vol); } static int volume_set_volume(struct processing_module *mod, const uint8_t *data, int data_size) @@ -351,7 +351,7 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "volume_set_config()"); + comp_dbg(dev, "entry"); ret = module_set_configuration(mod, config_id, pos, data_offset_size, fragment, fragment_size, response, response_size); @@ -413,7 +413,7 @@ static int volume_params(struct processing_module *mod) struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - comp_dbg(dev, "volume_params()"); + comp_dbg(dev, "entry"); ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); diff --git a/src/debug/debug_stream/CMakeLists.txt b/src/debug/debug_stream/CMakeLists.txt index 4d353128a819..36de0d24a46d 100644 --- a/src/debug/debug_stream/CMakeLists.txt +++ b/src/debug/debug_stream/CMakeLists.txt @@ -3,3 +3,5 @@ add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_SLOT sof debug_stream_slot.c) add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_THREAD_INFO sof debug_stream_thread_info.c) + +add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_TEXT_MSG sof debug_stream_text_msg.c) diff --git a/src/debug/debug_stream/Kconfig b/src/debug/debug_stream/Kconfig index 3a5f3d1f49cf..8756c83ef8da 100644 --- a/src/debug/debug_stream/Kconfig +++ b/src/debug/debug_stream/Kconfig @@ -7,7 +7,8 @@ config SOF_DEBUG_STREAM_SLOT information from SOF system that are streamed from SOF DSP to the host side for decoding and presentation. This option enables transferring the records from DSP to host over a - debug window slot. + debug window slot. To extract the debugstream see + tools/debug_stream/debug_stream.py. if SOF_DEBUG_STREAM_SLOT @@ -44,4 +45,13 @@ config SOF_DEBUG_STREAM_THREAD_INFO_INTERVAL Decides how often thread info runs and checks execution cycle statistics and stack usage. +config SOF_DEBUG_STREAM_TEXT_MSG + bool "Enable text message sending through Debug-Stream" + help + Enable debug message sending over debug stream. To use this + feature one only needs to enable debug stream with this + config option and print the debug messages with + ds_msg(). See include/user/debug_stream_text_msg.h for + prototype. + endif diff --git a/src/debug/debug_stream/debug_stream_slot.c b/src/debug/debug_stream/debug_stream_slot.c index dbfde134b438..388b7852e6ed 100644 --- a/src/debug/debug_stream/debug_stream_slot.c +++ b/src/debug/debug_stream/debug_stream_slot.c @@ -20,11 +20,26 @@ struct cpu_mutex { /* CPU specific mutexes for each circular buffer */ static struct cpu_mutex cpu_mutex[CONFIG_MP_MAX_NUM_CPUS]; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static struct debug_stream_slot_hdr *dbg_stream_slot; +#else static const int debug_stream_slot = CONFIG_SOF_DEBUG_STREAM_SLOT_NUMBER; +#endif static struct debug_stream_slot_hdr *debug_stream_get_slot(void) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + if (!dbg_stream_slot) { + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_DEBUG_STREAM, }; + + dbg_stream_slot = (struct debug_stream_slot_hdr *) + adsp_dw_request_slot(&slot_desc, NULL); + } + + return dbg_stream_slot; +#else return (struct debug_stream_slot_hdr *)ADSP_DW->slots[debug_stream_slot]; +#endif } static @@ -113,10 +128,15 @@ static int debug_stream_slot_init(void) CONFIG_MP_MAX_NUM_CPUS, section_size, hdr_size, section_area_size); +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + if (!hdr) + return -ENOMEM; +#else if (ADSP_DW->descs[debug_stream_slot].type != 0) LOG_WRN("Slot %d was not free: %u", debug_stream_slot, ADSP_DW->descs[debug_stream_slot].type); ADSP_DW->descs[debug_stream_slot].type = ADSP_DW_SLOT_DEBUG_STREAM; +#endif hdr->hdr.magic = DEBUG_STREAM_IDENTIFIER; hdr->hdr.hdr_size = hdr_size; diff --git a/src/debug/debug_stream/debug_stream_text_msg.c b/src/debug/debug_stream/debug_stream_text_msg.c new file mode 100644 index 000000000000..8933df03e6bb --- /dev/null +++ b/src/debug/debug_stream/debug_stream_text_msg.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2024 Intel Corporation. + +#include +#include +#include +#include +#include +#include + +#include + +void ds_msg(const char *format, ...) +{ + va_list args; + struct { + struct debug_stream_text_msg msg; + char text[128]; + } __packed buf = { 0 }; + ssize_t len; + + va_start(args, format); + len = vsnprintf(buf.text, sizeof(buf.text), format, args); + va_end(args); + + if (len < 0) + return; + len = MIN(len, sizeof(buf.text)); + + buf.msg.hdr.id = DEBUG_STREAM_RECORD_ID_TEXT_MSG; + buf.msg.hdr.size_words = SOF_DIV_ROUND_UP(sizeof(buf.msg) + len, + sizeof(buf.msg.hdr.data[0])); + debug_stream_slot_send_record(&buf.msg.hdr); +} diff --git a/src/debug/telemetry/Kconfig b/src/debug/telemetry/Kconfig index 6e6a55d18f3c..f380a90e1808 100644 --- a/src/debug/telemetry/Kconfig +++ b/src/debug/telemetry/Kconfig @@ -3,6 +3,7 @@ config SOF_TELEMETRY bool "enable telemetry" default n + depends on !SOF_USERSPACE_LL help Enables telemetry. Enables performance measurements and debug utilities that use memory window 2 (debug window) as interface. Measurements include diff --git a/src/debug/telemetry/performance_monitor.c b/src/debug/telemetry/performance_monitor.c index dc5e80c7c253..cd81781a6edc 100644 --- a/src/debug/telemetry/performance_monitor.c +++ b/src/debug/telemetry/performance_monitor.c @@ -211,10 +211,17 @@ int get_performance_data(struct global_perf_data * const global_perf_data) size_t slots_count; size_t slot_idx = 0; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct system_tick_info *systick_info = telemetry_get_systick_info_ptr(); + + if (!systick_info) + return 0; +#else struct telemetry_wnd_data *wnd_data = (struct telemetry_wnd_data *)ADSP_DW->slots[SOF_DW_TELEMETRY_SLOT]; struct system_tick_info *systick_info = (struct system_tick_info *)wnd_data->system_tick_info; +#endif /* Fill one performance record with performance stats per core */ for (int core_id = 0; core_id < CONFIG_MAX_CORE_COUNT; ++core_id) { @@ -369,10 +376,17 @@ int reset_performance_counters(void) if (perf_measurements_state == IPC4_PERF_MEASUREMENTS_DISABLED) return -EINVAL; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct system_tick_info *systick_info = telemetry_get_systick_info_ptr(); + + if (!systick_info) + return 0; +#else struct telemetry_wnd_data *wnd_data = (struct telemetry_wnd_data *)ADSP_DW->slots[SOF_DW_TELEMETRY_SLOT]; struct system_tick_info *systick_info = (struct system_tick_info *)wnd_data->system_tick_info; +#endif for (int core_id = 0; core_id < CONFIG_MAX_CORE_COUNT; ++core_id) { if (!(cpu_enabled_cores() & BIT(core_id))) diff --git a/src/debug/telemetry/telemetry.c b/src/debug/telemetry/telemetry.c index 3cbd28774543..1e4c522dfee0 100644 --- a/src/debug/telemetry/telemetry.c +++ b/src/debug/telemetry/telemetry.c @@ -27,6 +27,10 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); /* Systic variables, one set per core */ static int telemetry_systick_counter[CONFIG_MAX_CORE_COUNT]; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static struct telemetry_wnd_data *wnd_data; +#endif + #ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS static int telemetry_prev_ccount[CONFIG_MAX_CORE_COUNT]; static int telemetry_perf_period_sum[CONFIG_MAX_CORE_COUNT]; @@ -68,19 +72,45 @@ static size_t telemetry_perf_queue_avg(struct telemetry_perf_queue *q) } #endif +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +struct system_tick_info *telemetry_get_systick_info_ptr(void) +{ + if (!wnd_data) + return NULL; + + return (struct system_tick_info *)wnd_data->system_tick_info; +} +#endif + int telemetry_init(void) { /* systick_init */ +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TELEMETRY, }; + struct system_tick_info *systick_info; + + if (wnd_data) + return 0; + + wnd_data = (struct telemetry_wnd_data *)adsp_dw_request_slot(&slot_desc, + NULL); + if (!wnd_data) + return -ENOMEM; + + systick_info = (struct system_tick_info *)wnd_data->system_tick_info; +#else uint8_t slot_num = SOF_DW_TELEMETRY_SLOT; volatile struct adsp_debug_window *window = ADSP_DW; struct telemetry_wnd_data *wnd_data = (struct telemetry_wnd_data *)ADSP_DW->slots[slot_num]; struct system_tick_info *systick_info = (struct system_tick_info *)wnd_data->system_tick_info; - tr_info(&ipc_tr, "Telemetry enabled. May affect performance"); - window->descs[slot_num].type = ADSP_DW_SLOT_TELEMETRY; window->descs[slot_num].resource_id = 0; +#endif + + tr_info(&ipc_tr, "Telemetry enabled. May affect performance"); + wnd_data->separator_1 = 0x0000C0DE; /* Zero values per core */ @@ -101,13 +131,19 @@ int telemetry_init(void) void telemetry_update(uint32_t begin_stamp, uint32_t current_stamp) { int prid = cpu_get_id(); +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct system_tick_info *systick_info = telemetry_get_systick_info_ptr(); - ++telemetry_systick_counter[prid]; - + if (!systick_info) + return; +#else struct telemetry_wnd_data *wnd_data = (struct telemetry_wnd_data *)ADSP_DW->slots[SOF_DW_TELEMETRY_SLOT]; struct system_tick_info *systick_info = (struct system_tick_info *)wnd_data->system_tick_info; +#endif + + ++telemetry_systick_counter[prid]; systick_info[prid].count = telemetry_systick_counter[prid]; systick_info[prid].last_time_elapsed = current_stamp - begin_stamp; diff --git a/src/debug/tester/CMakeLists.txt b/src/debug/tester/CMakeLists.txt index e207a0547f6d..85bf026b5ed3 100644 --- a/src/debug/tester/CMakeLists.txt +++ b/src/debug/tester/CMakeLists.txt @@ -14,7 +14,7 @@ if(zephyr) ### Zephyr ### add_subdirectory(llext ${PROJECT_BINARY_DIR}/tester_llext) add_dependencies(app tester) - elseif(CONFIG_COMP_TESTER) + elseif(CONFIG_COMP_TESTER STREQUAL "y") zephyr_library_sources(${base_files}) diff --git a/src/debug/tester/tester.c b/src/debug/tester/tester.c index 869b7d9b2a7a..161b90a7d3f3 100644 --- a/src/debug/tester/tester.c +++ b/src/debug/tester/tester.c @@ -40,8 +40,6 @@ LOG_MODULE_REGISTER(tester, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(tester); -DECLARE_TR_CTX(tester_tr, SOF_UUID(tester_uuid), LOG_LEVEL_INFO); - struct tester_init_config { struct ipc4_base_module_cfg ipc4_cfg; int32_t test_type; @@ -250,6 +248,7 @@ SOF_LLEXT_BUILDINFO; #else +DECLARE_TR_CTX(tester_tr, SOF_UUID(tester_uuid), LOG_LEVEL_INFO); DECLARE_MODULE_ADAPTER(tester_interface, tester_uuid, tester_tr); SOF_MODULE_INIT(tester, sys_comp_module_tester_interface_init); diff --git a/src/debug/tester/tester.toml b/src/debug/tester/tester.toml index a8c233166608..586bf2c3046b 100644 --- a/src/debug/tester/tester.toml +++ b/src/debug/tester/tester.toml @@ -45,8 +45,8 @@ 23, 0, 0, 0, 12832, 27696000, 180, 256, 0, 27696, 0, 24, 0, 0, 0, 12832, 18368000, 256, 512, 0, 18368, 0, 25, 0, 0, 0, 12832, 15204000, 128, 256, 0, 15204, 0] -#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_ACE30) || \ + defined(CONFIG_SOC_ACE40) mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, diff --git a/src/drivers/amd/rembrandt/acp_hs_dai.c b/src/drivers/amd/rembrandt/acp_hs_dai.c index 780454f52c87..75d268887c90 100644 --- a/src/drivers/amd/rembrandt/acp_hs_dai.c +++ b/src/drivers/amd/rembrandt/acp_hs_dai.c @@ -60,7 +60,7 @@ static inline int hsdai_set_config(struct dai *dai, struct ipc_config_dai *commo i2stdm_mstrclkgen.bits.i2stdm_bclk_div_val = 0x20; break; default: - dai_err(dai, "hsdai_set_config unsupported slots"); + dai_err(dai, "unsupported slots"); return -EINVAL; } break; @@ -70,7 +70,7 @@ static inline int hsdai_set_config(struct dai *dai, struct ipc_config_dai *commo i2stdm_mstrclkgen.bits.i2stdm_bclk_div_val = 0x80; break; default: - dai_err(dai, "hsdai_set_config invalid format"); + dai_err(dai, "invalid format"); return -EINVAL; } @@ -109,7 +109,7 @@ static inline int hsdai_set_config(struct dai *dai, struct ipc_config_dai *commo io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IRER), hs_irer.u32all); break; default: - dai_err(dai, "hsdai_set_config invalid format"); + dai_err(dai, "invalid format"); return -EINVAL; } return 0; diff --git a/src/drivers/amd/rembrandt/acp_sw_audio_dai.c b/src/drivers/amd/rembrandt/acp_sw_audio_dai.c index 1b31cffd59d8..4e420a004e43 100644 --- a/src/drivers/amd/rembrandt/acp_sw_audio_dai.c +++ b/src/drivers/amd/rembrandt/acp_sw_audio_dai.c @@ -51,7 +51,7 @@ static int swaudiodai_remove(struct dai *dai) { struct acp_pdata *acp = dai_get_drvdata(dai); - dai_info(dai, "swaudiodai_remove"); + dai_info(dai, "entry"); rfree(acp); dai_set_drvdata(dai, NULL); diff --git a/src/drivers/amd/renoir/acp_sp_dai.c b/src/drivers/amd/renoir/acp_sp_dai.c index 0078b4d3a9d5..fbff87105ced 100644 --- a/src/drivers/amd/renoir/acp_sp_dai.c +++ b/src/drivers/amd/renoir/acp_sp_dai.c @@ -110,7 +110,7 @@ static int spdai_get_fifo(struct dai *dai, int direction, int stream_id) case DAI_DIR_CAPTURE: return dai_fifo(dai, direction); default: - dai_err(dai, "spdai_get_fifo(): Invalid direction"); + dai_err(dai, "Invalid direction"); return -EINVAL; } } diff --git a/src/drivers/amd/vangogh/acp_hs_dma.c b/src/drivers/amd/vangogh/acp_hs_dma.c index 361f74170932..b15a7f5e51b3 100644 --- a/src/drivers/amd/vangogh/acp_hs_dma.c +++ b/src/drivers/amd/vangogh/acp_hs_dma.c @@ -279,7 +279,7 @@ static int acp_dai_hs_dma_copy(struct dma_chan_data *channel, int bytes, .channel = channel, .elem.size = bytes, }; - tr_info(&acp_hs_tr, "acp_dai_hs_dma_copy "); + tr_info(&acp_hs_tr, "entry"); notifier_event(channel, NOTIFIER_ID_DMA_COPY, NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); return 0; diff --git a/src/drivers/dw/dma.c b/src/drivers/dw/dma.c index 97ac6ddabbad..102cbbe0d7ba 100644 --- a/src/drivers/dw/dma.c +++ b/src/drivers/dw/dma.c @@ -254,7 +254,7 @@ static void dw_dma_channel_put(struct dma_chan_data *channel) { k_spinlock_key_t key; - tr_info(&dwdma_tr, "dw_dma_channel_put(): dma %d channel %d put", + tr_info(&dwdma_tr, "dma %d channel %d put", channel->dma->plat_data.id, channel->index); key = k_spin_lock(&channel->dma->lock); @@ -273,7 +273,7 @@ static int dw_dma_start(struct dma_chan_data *channel) uint32_t words_per_tfr = 0; #endif - tr_dbg(&dwdma_tr, "dw_dma_start(): dma %d channel %d start", + tr_dbg(&dwdma_tr, "dma %d channel %d start", channel->dma->plat_data.id, channel->index); irq_local_disable(flags); @@ -282,7 +282,7 @@ static int dw_dma_start(struct dma_chan_data *channel) if ((channel->status != COMP_STATE_PREPARE && channel->status != COMP_STATE_PAUSED) || (dma_reg_read(dma, DW_DMA_CHAN_EN) & DW_CHAN(channel->index))) { - tr_err(&dwdma_tr, "dw_dma_start(): dma %d channel %d not ready ena 0x%x status 0x%x", + tr_err(&dwdma_tr, "dma %d channel %d not ready ena 0x%x status 0x%x", dma->plat_data.id, channel->index, dma_reg_read(dma, DW_DMA_CHAN_EN), channel->status); @@ -292,7 +292,7 @@ static int dw_dma_start(struct dma_chan_data *channel) /* is valid stream */ if (!dw_chan->lli) { - tr_err(&dwdma_tr, "dw_dma_start(): dma %d channel %d invalid stream", + tr_err(&dwdma_tr, "dma %d channel %d invalid stream", dma->plat_data.id, channel->index); ret = -EINVAL; goto out; @@ -348,7 +348,7 @@ static int dw_dma_release(struct dma_chan_data *channel) struct dw_dma_chan_data *dw_chan = dma_chan_get_data(channel); uint32_t flags; - tr_info(&dwdma_tr, "dw_dma_release(): dma %d channel %d release", + tr_info(&dwdma_tr, "dma %d channel %d release", channel->dma->plat_data.id, channel->index); irq_local_disable(flags); @@ -370,7 +370,7 @@ static int dw_dma_pause(struct dma_chan_data *channel) struct dma *dma = channel->dma; uint32_t flags; - tr_info(&dwdma_tr, "dw_dma_pause(): dma %d channel %d pause", + tr_info(&dwdma_tr, "dma %d channel %d pause", channel->dma->plat_data.id, channel->index); irq_local_disable(flags); @@ -405,7 +405,7 @@ static int dw_dma_stop(struct dma_chan_data *channel) int i; #endif - tr_info(&dwdma_tr, "dw_dma_stop(): dma %d channel %d stop", + tr_info(&dwdma_tr, "dma %d channel %d stop", dma->plat_data.id, channel->index); irq_local_disable(flags); @@ -428,7 +428,7 @@ static int dw_dma_stop(struct dma_chan_data *channel) DW_CFGL_FIFO_EMPTY, DW_DMA_TIMEOUT); if (ret < 0) - tr_err(&dwdma_tr, "dw_dma_stop(): dma %d channel %d timeout", + tr_err(&dwdma_tr, "dma %d channel %d timeout", dma->plat_data.id, channel->index); #endif @@ -438,7 +438,7 @@ static int dw_dma_stop(struct dma_chan_data *channel) ret = poll_for_register_delay(dma_base(dma) + DW_DMA_CHAN_EN, DW_CHAN(channel->index), 0, DW_DMA_TIMEOUT); if (ret < 0) { - tr_err(&dwdma_tr, "dw_dma_stop(): dma %d channel %d disable timeout", + tr_err(&dwdma_tr, "dma %d channel %d disable timeout", dma->plat_data.id, channel->index); return -ETIMEDOUT; } @@ -499,7 +499,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, int ret = 0; int i; - tr_dbg(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d config", + tr_dbg(&dwdma_tr, "dma %d channel %d config", channel->dma->plat_data.id, channel->index); irq_local_disable(flags); @@ -514,7 +514,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, dw_chan->cfg_hi = DW_CFG_HIGH_DEF; if (!config->elem_array.count) { - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d no elems", + tr_err(&dwdma_tr, "dma %d channel %d no elems", channel->dma->plat_data.id, channel->index); ret = -EINVAL; goto out; @@ -522,7 +522,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, if (config->irq_disabled && config->elem_array.count < DW_DMA_CFG_NO_IRQ_MIN_ELEMS) { - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d not enough elems for config with irq disabled %d", + tr_err(&dwdma_tr, "dma %d channel %d not enough elems for config with irq disabled %d", channel->dma->plat_data.id, channel->index, config->elem_array.count); ret = -EINVAL; @@ -548,7 +548,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, dw_chan->lli = rmalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, sizeof(struct dw_lli) * channel->desc_count); if (!dw_chan->lli) { - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d lli alloc failed", + tr_err(&dwdma_tr, "dma %d channel %d lli alloc failed", channel->dma->plat_data.id, channel->index); ret = -ENOMEM; @@ -600,7 +600,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(2); break; default: - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d invalid src width %d", + tr_err(&dwdma_tr, "dma %d channel %d invalid src width %d", channel->dma->plat_data.id, channel->index, config->src_width); ret = -EINVAL; @@ -628,7 +628,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(2); break; default: - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d invalid dest width %d", + tr_err(&dwdma_tr, "dma %d channel %d invalid dest width %d", channel->dma->plat_data.id, channel->index, config->dest_width); ret = -EINVAL; @@ -706,7 +706,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, DW_CFGH_DST(config->dest_dev); break; default: - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d invalid direction %d", + tr_err(&dwdma_tr, "dma %d channel %d invalid direction %d", channel->dma->plat_data.id, channel->index, config->direction); ret = -EINVAL; @@ -717,7 +717,7 @@ static int dw_dma_set_config(struct dma_chan_data *channel, lli_desc->dar = sg_elem->dest; if (sg_elem->size > DW_CTLH_BLOCK_TS_MASK) { - tr_err(&dwdma_tr, "dw_dma_set_config(): dma %d channel %d block size too big %d", + tr_err(&dwdma_tr, "dma %d channel %d block size too big %d", channel->dma->plat_data.id, channel->index, sg_elem->size); ret = -EINVAL; @@ -839,7 +839,7 @@ static int dw_dma_copy(struct dma_chan_data *channel, int bytes, }; k_spinlock_key_t key; - tr_dbg(&dwdma_tr, "dw_dma_copy(): dma %d channel %d copy", + tr_dbg(&dwdma_tr, "dma %d channel %d copy", channel->dma->plat_data.id, channel->index); notifier_event(channel, NOTIFIER_ID_DMA_COPY, @@ -859,7 +859,7 @@ static int dw_dma_copy(struct dma_chan_data *channel, int bytes, DW_CHAN(channel->index), 0, DW_DMA_TIMEOUT); if (ret < 0) { - tr_dbg(&dwdma_tr, "dw_dma_copy(): poll_for_register_delay timeout"); + tr_dbg(&dwdma_tr, "poll_for_register_delay timeout"); return ret; } } @@ -888,7 +888,7 @@ static int dw_dma_setup(struct dma *dma) break; if (!i) { - tr_err(&dwdma_tr, "dw_dma_setup(): dma %d setup failed", + tr_err(&dwdma_tr, "dma %d setup failed", dma->plat_data.id); return -EIO; } @@ -940,7 +940,7 @@ static int dw_dma_probe(struct dma *dma) sizeof(struct dma_chan_data) * dma->plat_data.channels); if (!dma->chan) { - tr_err(&dwdma_tr, "dw_dma_probe(): dma %d allocaction of channels failed", + tr_err(&dwdma_tr, "dma %d allocation of channels failed", dma->plat_data.id); goto out; } @@ -961,7 +961,7 @@ static int dw_dma_probe(struct dma *dma) sizeof(*dw_chan)); if (!dw_chan) { - tr_err(&dwdma_tr, "dw_dma_probe(): dma %d allocaction of channel %d private data failed", + tr_err(&dwdma_tr, "dma %d allocation of channel %d private data failed", dma->plat_data.id, i); goto out; } @@ -989,7 +989,7 @@ static int dw_dma_remove(struct dma *dma) { int i; - tr_dbg(&dwdma_tr, "dw_dma_remove(): dma %d remove", dma->plat_data.id); + tr_dbg(&dwdma_tr, "dma %d remove", dma->plat_data.id); pm_runtime_put_sync(DW_DMAC_CLK, dma->plat_data.id); @@ -1024,7 +1024,7 @@ static int dw_dma_avail_data_size(struct dma_chan_data *channel) if (delta) size = dw_chan->ptr_data.buffer_bytes; else - tr_info(&dwdma_tr, "dw_dma_avail_data_size() size is 0!"); + tr_info(&dwdma_tr, "size is 0!"); } tr_dbg(&dwdma_tr, "DAR %x reader 0x%x free 0x%x avail 0x%x", write_ptr, @@ -1055,7 +1055,7 @@ static int dw_dma_free_data_size(struct dma_chan_data *channel) if (delta) size = dw_chan->ptr_data.buffer_bytes; else - tr_info(&dwdma_tr, "dw_dma_free_data_size() size is 0!"); + tr_info(&dwdma_tr, "size is 0!"); } tr_dbg(&dwdma_tr, "SAR %x writer 0x%x free 0x%x avail 0x%x", read_ptr, @@ -1071,7 +1071,7 @@ static int dw_dma_get_data_size(struct dma_chan_data *channel, k_spinlock_key_t key; int ret = 0; - tr_dbg(&dwdma_tr, "dw_dma_get_data_size(): dma %d channel %d get data size", + tr_dbg(&dwdma_tr, "dma %d channel %d get data size", channel->dma->plat_data.id, channel->index); key = k_spin_lock(&channel->dma->lock); @@ -1090,7 +1090,7 @@ static int dw_dma_get_data_size(struct dma_chan_data *channel, #if CONFIG_DMA_HW_LLI if (!(dma_reg_read(channel->dma, DW_DMA_CHAN_EN) & DW_CHAN(channel->index))) { - tr_err(&dwdma_tr, "dw_dma_get_data_size(): xrun detected"); + tr_err(&dwdma_tr, "xrun detected"); return -ENODATA; } #endif diff --git a/src/drivers/imx/edma.c b/src/drivers/imx/edma.c index f8e3fb1dcf7c..b21c58bcb02c 100644 --- a/src/drivers/imx/edma.c +++ b/src/drivers/imx/edma.c @@ -391,7 +391,7 @@ static int edma_set_config(struct dma_chan_data *channel, doff = config->dest_width; break; default: - tr_err(&edma_tr, "edma_set_config() unsupported config direction"); + tr_err(&edma_tr, "unsupported config direction"); return -EINVAL; } @@ -541,7 +541,7 @@ static int edma_get_data_size(struct dma_chan_data *channel, *avail = ABS(capture_data_size) / 2; break; default: - tr_err(&edma_tr, "edma_get_data_size() unsupported direction %d", + tr_err(&edma_tr, "unsupported direction %d", channel->direction); return -EINVAL; } diff --git a/src/drivers/imx/esai.c b/src/drivers/imx/esai.c index 4c62009e56bc..60af9bef9e5a 100644 --- a/src/drivers/imx/esai.c +++ b/src/drivers/imx/esai.c @@ -367,7 +367,7 @@ static int esai_remove(struct dai *dai) { struct esai_pdata *pdata = dai_get_drvdata(dai); - dai_info(dai, "esai_remove()"); + dai_info(dai, "entry"); rfree(pdata); dai_set_drvdata(dai, NULL); @@ -391,7 +391,7 @@ static int esai_get_fifo(struct dai *dai, int direction, int stream_id) case DAI_DIR_CAPTURE: return dai_fifo(dai, direction); /* stream_id is unused */ default: - dai_err(dai, "esai_get_fifo(): Invalid direction"); + dai_err(dai, "Invalid direction"); return -EINVAL; } } @@ -403,7 +403,7 @@ static int esai_get_fifo_depth(struct dai *dai, int direction) case DAI_DIR_CAPTURE: return dai->plat_data.fifo[direction].depth; default: - dai_err(dai, "esai_get_fifo_depth(): Invalid direction"); + dai_err(dai, "Invalid direction"); return -EINVAL; } } @@ -420,7 +420,7 @@ static int esai_get_hw_params(struct dai *dai, params->buffer_fmt = 0; params->frame_fmt = SOF_IPC_FRAME_S24_4LE; - dai_info(dai, "esai_get_hw_params(): params->rate = %d, fsync_rate = %d", + dai_info(dai, "params->rate = %d, fsync_rate = %d", params->rate, esai->params.fsync_rate); return 0; diff --git a/src/drivers/imx/interrupt-irqsteer.c b/src/drivers/imx/interrupt-irqsteer.c index da45b4f109ba..e42dce923bc9 100644 --- a/src/drivers/imx/interrupt-irqsteer.c +++ b/src/drivers/imx/interrupt-irqsteer.c @@ -348,7 +348,7 @@ static inline void irq_handler(void *data, uint32_t line_index) if (!--tries) { tries = IRQ_MAX_TRIES; - tr_err(&irq_i_tr, "irq_handler(): IRQ storm, status 0x%08x%08x", + tr_err(&irq_i_tr, "IRQ storm, status 0x%08x%08x", (uint32_t)(status >> 32), (uint32_t)status); } } diff --git a/src/drivers/imx/micfil.c b/src/drivers/imx/micfil.c index 5cbf5c3e292b..0946ca165c57 100644 --- a/src/drivers/imx/micfil.c +++ b/src/drivers/imx/micfil.c @@ -50,7 +50,7 @@ static int micfil_get_hw_params(struct dai *dai, { struct micfil_pdata *micfil = dai_get_drvdata(dai); - dai_info(dai, "micfil_get_hw_params()"); + dai_info(dai, "entry"); params->rate = micfil->params.pdm_rate; params->channels = micfil->params.pdm_ch; @@ -184,7 +184,7 @@ static int micfil_set_config(struct dai *dai, struct ipc_config_dai *common_conf micfil->params = config->micfil; - dai_info(dai, "micfil_set_config() dai_idx %d channels %d sampling_freq %d", + dai_info(dai, "dai_idx %d channels %d sampling_freq %d", common_config->dai_index, micfil->params.pdm_ch, micfil->params.pdm_rate); /* disable the module */ @@ -232,7 +232,7 @@ static int micfil_get_fifo_depth(struct dai *dai, int direction) static void micfil_start(struct dai *dai) { - dai_info(dai, "micfil_start()"); + dai_info(dai, "entry"); micfil_reset(dai); @@ -252,7 +252,7 @@ static void micfil_start(struct dai *dai) static void micfil_stop(struct dai *dai) { - dai_info(dai, "micfil_stop()"); + dai_info(dai, "entry"); /* Disable the module */ dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_PDMIEN, 0); @@ -263,7 +263,7 @@ static void micfil_stop(struct dai *dai) static int micfil_trigger(struct dai *dai, int cmd, int direction) { - dai_info(dai, "micfil_trigger() cmd %d dir %d", cmd, direction); + dai_info(dai, "cmd %d dir %d", cmd, direction); switch (cmd) { case COMP_TRIGGER_START: @@ -288,7 +288,7 @@ static int micfil_probe(struct dai *dai) { struct micfil_pdata *micfil; - dai_info(dai, "micfil_probe()"); + dai_info(dai, "entry"); micfil = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, sizeof(*micfil)); if (!micfil) { @@ -307,7 +307,7 @@ static int micfil_remove(struct dai *dai) { struct micfil_pdata *micfil = dai_get_drvdata(dai); - dai_info(dai, "micfil_remove()"); + dai_info(dai, "entry"); rfree(micfil); dai_set_drvdata(dai, NULL); diff --git a/src/drivers/imx/sai.c b/src/drivers/imx/sai.c index eeb4555d3143..1d748c44a6e0 100644 --- a/src/drivers/imx/sai.c +++ b/src/drivers/imx/sai.c @@ -29,7 +29,7 @@ DECLARE_TR_CTX(sai_tr, SOF_UUID(sai_uuid), LOG_LEVEL_INFO); static void sai_start(struct dai *dai, int direction) { - dai_info(dai, "SAI: sai_start"); + dai_info(dai, "SAI: entry"); struct sai_pdata *sai = dai_get_drvdata(dai); int chan_idx = 0; @@ -139,7 +139,7 @@ static void sai_start(struct dai *dai, int direction) static void sai_release(struct dai *dai, int direction) { - dai_info(dai, "SAI: sai_release"); + dai_info(dai, "SAI: entry"); int chan_idx = 0; #ifdef CONFIG_IMX8ULP @@ -171,7 +171,7 @@ static void sai_release(struct dai *dai, int direction) static void sai_stop(struct dai *dai, int direction) { - dai_info(dai, "SAI: sai_stop"); + dai_info(dai, "SAI: entry"); uint32_t xcsr = 0U; int ret = 0; @@ -222,7 +222,7 @@ static void sai_stop(struct dai *dai, int direction) static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_config, const void *spec_config) { - dai_info(dai, "SAI: sai_set_config"); + dai_info(dai, "SAI: entry"); const struct sof_ipc_dai_config *config = spec_config; uint32_t val_cr2 = 0, val_cr4 = 0, val_cr5 = 0; uint32_t mask_cr2 = 0, mask_cr4 = 0, mask_cr5 = 0; @@ -438,7 +438,7 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ static int sai_trigger(struct dai *dai, int cmd, int direction) { - dai_info(dai, "SAI: sai_trigger"); + dai_info(dai, "SAI: entry"); switch (cmd) { case COMP_TRIGGER_START: @@ -465,12 +465,12 @@ static int sai_probe(struct dai *dai) { struct sai_pdata *sai; - dai_info(dai, "SAI: sai_probe"); + dai_info(dai, "SAI: entry"); /* allocate private data */ sai = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, sizeof(*sai)); if (!sai) { - dai_err(dai, "sai_probe(): alloc failed"); + dai_err(dai, "alloc failed"); return -ENOMEM; } dai_set_drvdata(dai, sai); @@ -504,7 +504,7 @@ static int sai_remove(struct dai *dai) { struct sai_pdata *sai = dai_get_drvdata(dai); - dai_info(dai, "sai_remove()"); + dai_info(dai, "entry"); rfree(sai); dai_set_drvdata(dai, NULL); @@ -524,7 +524,7 @@ static int sai_get_fifo(struct dai *dai, int direction, int stream_id) case DAI_DIR_CAPTURE: return dai_fifo(dai, direction); /* stream_id is unused */ default: - dai_err(dai, "sai_get_fifo(): Invalid direction"); + dai_err(dai, "Invalid direction"); return -EINVAL; } } @@ -536,7 +536,7 @@ static int sai_get_fifo_depth(struct dai *dai, int direction) case DAI_DIR_CAPTURE: return dai->plat_data.fifo[direction].depth; default: - dai_err(dai, "esai_get_fifo_depth(): Invalid direction"); + dai_err(dai, "Invalid direction"); return -EINVAL; } } diff --git a/src/drivers/imx/sdma.c b/src/drivers/imx/sdma.c index 3f47b34101b5..a613f98b40c5 100644 --- a/src/drivers/imx/sdma.c +++ b/src/drivers/imx/sdma.c @@ -85,8 +85,7 @@ struct sdma_pdata { static void sdma_set_overrides(struct dma_chan_data *channel, bool event_override, bool host_override) { - tr_dbg(&sdma_tr, "sdma_set_overrides(%d, %d)", event_override, - host_override); + tr_dbg(&sdma_tr, "event %d, host %d", event_override, host_override); dma_reg_update_bits(channel->dma, SDMA_EVTOVR, BIT(channel->index), event_override ? BIT(channel->index) : 0); dma_reg_update_bits(channel->dma, SDMA_HOSTOVR, BIT(channel->index), @@ -110,7 +109,7 @@ static int sdma_run_c0(struct dma *dma, uint8_t cmd, uint32_t buf_addr, struct sdma_chan *c0data = dma_chan_get_data(c0); int ret; - tr_dbg(&sdma_tr, "sdma_run_c0 cmd %d buf_addr 0x%08x sdma_addr 0x%04x count %d", + tr_dbg(&sdma_tr, "cmd %d buf_addr 0x%08x sdma_addr 0x%04x count %d", cmd, buf_addr, sdma_addr, count); c0data->desc[0].config = SDMA_BD_CMD(cmd) | SDMA_BD_COUNT(count) @@ -150,7 +149,7 @@ static int sdma_run_c0(struct dma *dma, uint8_t cmd, uint32_t buf_addr, dma_reg_update_bits(dma, SDMA_CONFIG, SDMA_CONFIG_CSM_MSK, SDMA_CONFIG_CSM_DYN); - tr_dbg(&sdma_tr, "sdma_run_c0 done, ret = %d", ret); + tr_dbg(&sdma_tr, "done, ret = %d", ret); return ret; } @@ -161,7 +160,7 @@ static int sdma_register_init(struct dma *dma) struct sdma_pdata *pdata = dma_get_drvdata(dma); int i; - tr_dbg(&sdma_tr, "sdma_register_init"); + tr_dbg(&sdma_tr, "entry"); dma_reg_write(dma, SDMA_RESET, 1); /* Wait for 10us */ ret = poll_for_register_delay(dma_base(dma) + SDMA_RESET, 1, 0, 1000); @@ -216,7 +215,7 @@ static void sdma_init_c0(struct dma *dma) struct sdma_pdata *sdma_pdata = dma_get_drvdata(dma); struct sdma_chan *pdata = &sdma_pdata->chan_pdata[0]; - tr_dbg(&sdma_tr, "sdma_init_c0"); + tr_dbg(&sdma_tr, "entry"); c0->status = COMP_STATE_READY; /* Reset channel 0 private data */ @@ -233,14 +232,14 @@ static int sdma_boot(struct dma *dma) { int ret; - tr_dbg(&sdma_tr, "sdma_boot"); + tr_dbg(&sdma_tr, "entry"); ret = sdma_register_init(dma); if (ret < 0) return ret; sdma_init_c0(dma); - tr_dbg(&sdma_tr, "sdma_boot done"); + tr_dbg(&sdma_tr, "done"); return 0; } @@ -251,7 +250,7 @@ static int sdma_upload_context(struct dma_chan_data *chan) /* Ensure context is ready for upload */ dcache_writeback_region(pdata->ctx, sizeof(*pdata->ctx)); - tr_dbg(&sdma_tr, "sdma_upload_context for channel %d", chan->index); + tr_dbg(&sdma_tr, "for channel %d", chan->index); /* Last parameters are unneeded for this command and are ignored; * set to 0. @@ -382,7 +381,7 @@ static int sdma_remove(struct dma *dma) return 0; } - tr_dbg(&sdma_tr, "sdma_remove"); + tr_dbg(&sdma_tr, "entry"); /* Prevent all channels except channel 0 from running */ dma_reg_write(dma, SDMA_HOSTOVR, 1); @@ -442,7 +441,7 @@ static void sdma_enable_event(struct dma_chan_data *channel, int eventnum) { struct sdma_chan *pdata = dma_chan_get_data(channel); - tr_dbg(&sdma_tr, "sdma_enable_event(%d, %d)", channel->index, eventnum); + tr_dbg(&sdma_tr, "channel %d, event %d", channel->index, eventnum); if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT) return; /* No change if request is invalid */ @@ -460,7 +459,7 @@ static void sdma_enable_event(struct dma_chan_data *channel, int eventnum) static void sdma_disable_event(struct dma_chan_data *channel, int eventnum) { - tr_dbg(&sdma_tr, "sdma_disable_event(%d, %d)", channel->index, eventnum); + tr_dbg(&sdma_tr, "channel %d, event %d", channel->index, eventnum); if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT) return; /* No change if request is invalid */ @@ -475,7 +474,7 @@ static void sdma_channel_put(struct dma_chan_data *channel) if (channel->status == COMP_STATE_INIT) return; /* Channel was already free */ - tr_dbg(&sdma_tr, "sdma_channel_put(%d)", channel->index); + tr_dbg(&sdma_tr, "channel %d", channel->index); dma_interrupt_legacy(channel, DMA_IRQ_CLEAR); sdma_disable_event(channel, pdata->hw_event); @@ -485,7 +484,7 @@ static void sdma_channel_put(struct dma_chan_data *channel) static int sdma_start(struct dma_chan_data *channel) { - tr_dbg(&sdma_tr, "sdma_start(%d)", channel->index); + tr_dbg(&sdma_tr, "channel %d", channel->index); if (channel->status != COMP_STATE_PREPARE && channel->status != COMP_STATE_PAUSED) @@ -507,7 +506,7 @@ static int sdma_stop(struct dma_chan_data *channel) channel->status = COMP_STATE_READY; - tr_dbg(&sdma_tr, "sdma_stop(%d)", channel->index); + tr_dbg(&sdma_tr, "channel %d", channel->index); sdma_disable_channel(channel->dma, channel->index); @@ -553,7 +552,7 @@ static int sdma_copy(struct dma_chan_data *channel, int bytes, uint32_t flags) }; int idx; - tr_dbg(&sdma_tr, "sdma_copy"); + tr_dbg(&sdma_tr, "entry"); idx = (pdata->next_bd + 1) % 2; pdata->next_bd = idx; @@ -581,7 +580,7 @@ static int sdma_status(struct dma_chan_data *channel, struct sdma_chan *pdata = dma_chan_get_data(channel); struct sdma_bd *bd; - tr_dbg(&sdma_tr, "sdma_status"); + tr_dbg(&sdma_tr, "entry"); if (channel->status == COMP_STATE_INIT) return -EINVAL; status->state = channel->status; @@ -689,13 +688,13 @@ static int sdma_read_config(struct dma_chan_data *channel, for (i = 0; i < config->elem_array.count; i++) { if (config->direction == SOF_DMA_DIR_MEM_TO_DEV && pdata->fifo_paddr != config->elem_array.elems[i].dest) { - tr_err(&sdma_tr, "sdma_read_config: FIFO changes address!"); + tr_err(&sdma_tr, "FIFO changes address!"); return -EINVAL; } if (config->direction == SOF_DMA_DIR_DEV_TO_MEM && pdata->fifo_paddr != config->elem_array.elems[i].src) { - tr_err(&sdma_tr, "sdma_read_config: FIFO changes address!"); + tr_err(&sdma_tr, "FIFO changes address!"); return -EINVAL; } @@ -868,7 +867,7 @@ static int sdma_set_config(struct dma_chan_data *channel, struct sdma_chan *pdata = dma_chan_get_data(channel); int ret; - tr_dbg(&sdma_tr, "sdma_set_config channel %d", channel->index); + tr_dbg(&sdma_tr, "channel %d", channel->index); ret = sdma_read_config(channel, config); if (ret < 0) @@ -925,7 +924,7 @@ static int sdma_interrupt(struct dma_chan_data *channel, enum dma_irq_cmd cmd) */ return 0; default: - tr_err(&sdma_tr, "sdma_interrupt unknown cmd %d", cmd); + tr_err(&sdma_tr, "unknown cmd %d", cmd); return -EINVAL; } } @@ -966,7 +965,7 @@ static int sdma_get_data_size(struct dma_chan_data *channel, uint32_t *avail, uint32_t result_data = 0; int i; - tr_dbg(&sdma_tr, "sdma_get_data_size(%d)", channel->index); + tr_dbg(&sdma_tr, "channel %d", channel->index); if (channel->index == 0) { /* Channel 0 shouldn't have this called anyway */ tr_err(&sdma_tr, "Please do not call get_data_size on SDMA channel 0!"); @@ -992,7 +991,7 @@ static int sdma_get_data_size(struct dma_chan_data *channel, uint32_t *avail, *avail = result_data; break; default: - tr_err(&sdma_tr, "sdma_get_data_size channel invalid direction"); + tr_err(&sdma_tr, "channel invalid direction"); return -EINVAL; } return 0; diff --git a/src/drivers/mediatek/afe/afe-drv.c b/src/drivers/mediatek/afe/afe-drv.c index bdf5bc1f5f07..5f09359117e6 100644 --- a/src/drivers/mediatek/afe/afe-drv.c +++ b/src/drivers/mediatek/afe/afe-drv.c @@ -251,7 +251,7 @@ int afe_dai_set_config(struct mtk_base_afe *afe, int id, unsigned int channel, u if (id >= afe->dais_size) return -EINVAL; - tr_info(&afedrv_tr, "afe_dai_set_config, id:%d\n", id); + tr_info(&afedrv_tr, "id:%d\n", id); dai = &afe->dais[id]; dai->channel = channel; @@ -271,10 +271,10 @@ int afe_dai_get_config(struct mtk_base_afe *afe, int id, unsigned int *channel, /* TODO 1. if need use dai->id to search target dai */ /* TODO 1. if need a status to control the dai status */ - tr_info(&afedrv_tr, "afe_dai_get_config, id:%d\n", id); + tr_info(&afedrv_tr, "id:%d\n", id); if (id >= afe->dais_size || id < 0) { - tr_err(&afedrv_tr, "afe_dai_get_config , invalid id:%d\n", id); + tr_err(&afedrv_tr, ", invalid id:%d\n", id); return -EINVAL; } dai = &afe->dais[id]; diff --git a/src/drivers/mediatek/afe/afe-memif.c b/src/drivers/mediatek/afe/afe-memif.c index 233eaec63748..1e57f5cf0289 100644 --- a/src/drivers/mediatek/afe/afe-memif.c +++ b/src/drivers/mediatek/afe/afe-memif.c @@ -192,7 +192,7 @@ static int memif_copy(struct dma_chan_data *channel, int bytes, uint32_t flags) memif->wptr = (memif->wptr + bytes) % memif->dma_size; else memif->rptr = (memif->rptr + bytes) % memif->dma_size; - tr_dbg(&memif_tr, "memif_copy: wptr:%u, rptr:%u", memif->wptr, memif->rptr); + tr_dbg(&memif_tr, "wptr:%u, rptr:%u", memif->wptr, memif->rptr); notifier_event(channel, NOTIFIER_ID_DMA_COPY, NOTIFIER_TARGET_CORE_LOCAL, &next, sizeof(next)); @@ -241,7 +241,7 @@ static int memif_set_config(struct dma_chan_data *channel, struct dma_sg_config channel->direction = config->direction; direction = afe_memif_get_direction(memif->afe, memif->memif_id); - tr_info(&memif_tr, "memif_set_config, direction:%d, afe_dir:%d", config->direction, + tr_info(&memif_tr, "direction:%d, afe_dir:%d", config->direction, direction); switch (config->direction) { @@ -263,7 +263,7 @@ static int memif_set_config(struct dma_chan_data *channel, struct dma_sg_config tr_dbg(&memif_tr, "capture: dai_id:%d, dma_addr:%u\n", dai_id, dma_addr); break; default: - tr_err(&memif_tr, "afe_memif_set_config() unsupported config direction"); + tr_err(&memif_tr, "afe_unsupported config direction"); return -EINVAL; } diff --git a/src/idc/idc.c b/src/idc/idc.c index 466f84eee63f..bafa44299073 100644 --- a/src/idc/idc.c +++ b/src/idc/idc.c @@ -184,20 +184,21 @@ static int idc_prepare(uint32_t comp_id) /* we're running LL on different core, so allocate our own task */ if (!dev->task && dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) { /* allocate task for shared component */ - dev->task = module_driver_heap_rzalloc(dev->drv->user_heap, SOF_MEM_FLAG_USER, - sizeof(*dev->task)); + dev->task = sof_heap_alloc(dev->drv->user_heap, SOF_MEM_FLAG_USER, + sizeof(*dev->task), 0); if (!dev->task) { ret = -ENOMEM; goto out; } + memset(dev->task, 0, sizeof(*dev->task)); ret = schedule_task_init_ll(dev->task, SOF_UUID(idc_task_uuid), SOF_SCHEDULE_LL_TIMER, dev->priority, comp_task, dev, dev->ipc_config.core, 0); if (ret < 0) { - module_driver_heap_free(dev->drv->user_heap, dev->task); + sof_heap_free(dev->drv->user_heap, dev->task); goto out; } } @@ -221,32 +222,12 @@ static int idc_trigger(uint32_t comp_id) struct idc *idc = *idc_get(); struct idc_payload *payload = idc_payload_get(idc, cpu_get_id()); uint32_t cmd = *(uint32_t *)payload; - int ret; ipc_dev = ipc_get_comp_by_id(ipc, comp_id); if (!ipc_dev) return -ENODEV; - ret = comp_trigger(ipc_dev->cd, cmd); - if (ret < 0) - goto out; - - /* schedule or cancel task */ - switch (cmd) { - case COMP_TRIGGER_START: - case COMP_TRIGGER_RELEASE: - schedule_task(ipc_dev->cd->task, 0, ipc_dev->cd->period); - break; - case COMP_TRIGGER_XRUN: - case COMP_TRIGGER_PAUSE: - case COMP_TRIGGER_STOP: - schedule_task_cancel(ipc_dev->cd->task); - break; - } - -out: - - return ret; + return comp_trigger(ipc_dev->cd, cmd); } /** diff --git a/src/idc/zephyr_idc.c b/src/idc/zephyr_idc.c index afd30628a5d3..f1af9d53a85b 100644 --- a/src/idc/zephyr_idc.c +++ b/src/idc/zephyr_idc.c @@ -185,6 +185,11 @@ void idc_init_thread(void) k_p4wq_enable_static_thread(q_zephyr_idc + cpu, _p4threads_q_zephyr_idc + cpu, BIT(cpu)); + /* + * Assign SOF system heap to the IDC thread. Otherwise by default it + * uses the Zephyr heap for DP stack allocation + */ + k_thread_heap_assign(_p4threads_q_zephyr_idc + cpu, sof_sys_heap_get()); } #endif /* CONFIG_MULTICORE */ diff --git a/src/include/ipc4/alh.h b/src/include/ipc4/alh.h index c15578514b2a..7691b9fe0a11 100644 --- a/src/include/ipc4/alh.h +++ b/src/include/ipc4/alh.h @@ -37,7 +37,7 @@ #endif #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) || \ - defined(CONFIG_SOC_INTEL_ACE15_MTPM) + defined(CONFIG_SOC_ACE15_MTPM) #define IPC4_DAI_NUM_ALH_BI_DIR_LINKS 16 #define IPC4_DAI_NUM_ALH_BI_DIR_LINKS_GROUP 4 #else diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index b95ecbd3e1f9..0c89d534637a 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -30,6 +30,8 @@ struct sof_ipc_stream_params; void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, struct sof_ipc_stream_params *params); +void ipc4_audio_format_to_stream_params(const struct ipc4_audio_format *audio_fmt, + struct sof_ipc_stream_params *params); struct comp_buffer; void ipc4_update_buffer_format(struct comp_buffer *buf_c, const struct ipc4_audio_format *fmt); diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index 25601b1209f0..289ab76830e3 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -17,10 +17,11 @@ #ifndef __SOF_IPC4_BASE_FW_H__ #define __SOF_IPC4_BASE_FW_H__ -/* Three clk src states :low power XTAL, low power ring - * and high power ring oscillator +/* SOF FW performs autonomous management of clock sources. + * Set MAX_CLK_STATES to 0 in order to propagate this information through IPC and thus + * prevent reception of unsupported clock configuration. */ -#define IPC4_MAX_CLK_STATES 3 +#define IPC4_MAX_CLK_STATES 0 /* Max src queue count count supported by ipc4 */ #define IPC4_MAX_SRC_QUEUE 8 @@ -373,12 +374,30 @@ enum ipc4_fw_config_params { IPC4_DMI_FORCE_L1_EXIT = 28, /* FW context save on D3 entry */ IPC4_FW_CONTEXT_SAVE = 29, + /* Minimum size of host buffer in ms */ + IPC4_FW_MIN_HOST_BUFFER_PERIODS = 33, + /* decoder/encoder codec information */ + IPC4_FW_SOF_INFO = 35, /* Total number of FW config parameters */ IPC4_FW_CFG_PARAMS_COUNT, /* Max config parameter id */ IPC4_MAX_FW_CFG_PARAM = IPC4_FW_CFG_PARAMS_COUNT - 1, }; +/* + * tuple based array for SOF specific information under IPC4_FW_SOF_INFO + * tuple of fw_config + */ +enum ipc4_fw_sof_info_params { + /* decoder/encoder codec information */ + IPC4_SOF_CODEC_INFO = 0, + + /* Total number of SOF config parameters */ + IPC4_SOF_CFG_PARAMS_COUNT, + /* Max config parameter id */ + IPC4_MAX_SOF_CFG_PARAM = IPC4_SOF_CFG_PARAMS_COUNT - 1, +}; + enum ipc4_hw_config_params { /* Version of cAVS implemented by FW (from ROMInfo) */ IPC4_CAVS_VER_HW_CFG = 0, diff --git a/src/include/ipc4/gateway.h b/src/include/ipc4/gateway.h index f78c21caf979..9398bb44be0e 100644 --- a/src/include/ipc4/gateway.h +++ b/src/include/ipc4/gateway.h @@ -162,8 +162,8 @@ struct ipc4_ipc_gateway_config_blob { uint32_t buffer_size; /**< Flags */ - union flags { - struct bits { + union { + struct { /**< Activates high threshold notification */ /*! * Indicates whether notification should be sent to the host diff --git a/src/include/ipc4/header.h b/src/include/ipc4/header.h index 643ded46050a..6a6eb59d02e5 100644 --- a/src/include/ipc4/header.h +++ b/src/include/ipc4/header.h @@ -177,6 +177,7 @@ struct ipc4_message_reply { #define SOF_IPC4_ENUM_CONTROL_PARAM_ID 201 #define SOF_IPC4_BYTES_CONTROL_PARAM_ID 202 #define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL ((uint32_t)(0xA15A << 16)) +#define SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL ((uint32_t)(0xC0C0 << 16)) /** * struct sof_ipc4_ctrl_value_chan: generic channel mapped value data diff --git a/src/include/ipc4/module.h b/src/include/ipc4/module.h index a73ede0b0bd5..dfe0f02e628e 100644 --- a/src/include/ipc4/module.h +++ b/src/include/ipc4/module.h @@ -77,7 +77,8 @@ struct ipc4_vendor_error { enum ipc4_mod_init_data_glb_id { IPC4_MOD_INIT_DATA_ID_INVALID = 0, IPC4_MOD_INIT_DATA_ID_DP_DATA = 1, - IPC4_MOD_INIT_DATA_ID_MAX = IPC4_MOD_INIT_DATA_ID_DP_DATA, + IPC4_MOD_INIT_DATA_ID_MODULE_DATA = 2, + IPC4_MOD_INIT_DATA_ID_MAX = IPC4_MOD_INIT_DATA_ID_MODULE_DATA, }; /* data object for vendor bespoke data with ABI growth and backwards compat */ @@ -90,9 +91,11 @@ struct ipc4_module_init_ext_object { /* Ext init array data object for Data Processing module memory requirements */ struct ipc4_module_init_ext_obj_dp_data { - uint32_t domain_id; /* userspace domain ID */ - uint32_t stack_bytes; /* required stack size in bytes, 0 means default size */ - uint32_t heap_bytes; /* required heap size in bytes, 0 means default size */ + uint32_t domain_id; /* userspace domain ID */ + uint32_t stack_bytes; /* required stack size in bytes */ + uint32_t interim_heap_bytes; /* required interim heap size in bytes */ + uint32_t lifetime_heap_bytes; /* required lifetime heap size in bytes */ + uint32_t shared_bytes; /* required shared memory size in bytes */ } __attribute__((packed, aligned(4))); /* diff --git a/src/include/ipc4/pipeline.h b/src/include/ipc4/pipeline.h index 219c36a89a3d..198918cf8577 100644 --- a/src/include/ipc4/pipeline.h +++ b/src/include/ipc4/pipeline.h @@ -69,6 +69,41 @@ enum ipc4_pipeline_state { SOF_IPC4_PIPELINE_STATE_SAVED }; +/* IDs for all pipeline ext data types in struct ipc4_pipeline_init_ext_object */ +enum ipc4_pipeline_ext_obj_id { + IPC4_GLB_PIPE_EXT_OBJ_ID_INVALID = 0, + IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA = 1, + IPC4_GLB_PIPE_EXT_OBJ_ID_MAX = IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA, +}; + +/* data object for vendor bespoke data with ABI growth and backwards compat */ +struct ipc4_pipeline_ext_object { + uint32_t last_object : 1; /* object is last in array if 1 else object follows. */ + uint32_t object_id : 15; /* unique ID for this object or globally */ + uint32_t object_words : 16; /* size in dwords (excluding this structure) */ +} __packed __aligned(4); +/* the object data will be placed in memory here and will have size "object_words" */ + +/* Ext array data object for pipeline instance's memory requirements */ +struct ipc4_pipeline_ext_obj_mem_data { + uint32_t domain_id; /* userspace domain ID */ + uint32_t stack_bytes; /* required stack size in bytes */ + uint32_t interim_heap_bytes; /* required interim heap size in bytes */ + uint32_t lifetime_heap_bytes; /* required lifetime heap size in bytes */ + uint32_t shared_bytes; /* required shared memory in bytes */ +} __packed __aligned(4); + +/* + * Host Driver sends this message to create a new pipeline instance. + */ +struct ipc4_pipeline_ext_payload { + uint32_t payload_words : 24; /* size in dwords (excluding this structure) */ + uint32_t data_obj_array : 1; /* struct ipc4_pipeline_ext_object data */ + uint32_t rsvd0 : 7; + uint32_t rsvd1; + uint32_t rsvd2; +} __packed __aligned(4); + /*! * lp - indicates whether the pipeline should be kept on running in low power * mode. On BXT the driver should set this flag to 1 for WoV pipeline. @@ -106,7 +141,8 @@ struct ipc4_pipeline_create { uint32_t rsvd1 : 3; uint32_t attributes : 16; uint32_t core_id : 4; - uint32_t rsvd2 : 6; + uint32_t rsvd2 : 5; + uint32_t payload : 1; uint32_t _reserved_2 : 2; } r; } extension; diff --git a/src/include/module/audio/sink_api.h b/src/include/module/audio/sink_api.h index 527fd1dc11c6..920087d6f8b3 100644 --- a/src/include/module/audio/sink_api.h +++ b/src/include/module/audio/sink_api.h @@ -77,6 +77,12 @@ struct sink_ops { */ int (*commit_buffer)(struct sof_sink *sink, size_t commit_size); + /** + * get latest feeding time for this sink, result is a number of microseconds since "NOW" + * where "now" means a start of last LL cycle, as described in zephyr_dp_schedule.c + */ + uint32_t (*get_lft)(struct sof_sink *sink); + /** * OPTIONAL: Notification to the sink implementation about changes in audio format * @@ -348,4 +354,9 @@ static inline struct processing_module *sink_get_bound_module(struct sof_sink *s return sink->bound_module; } +static inline uint32_t sink_get_last_feeding_time(struct sof_sink *sink) +{ + return sink->ops->get_lft(sink); +} + #endif /* __MODULE_AUDIO_SINK_API_H__ */ diff --git a/src/include/module/crossover/crossover_common.h b/src/include/module/crossover/crossover_common.h index 28c6e8aa7775..d238ff7c1008 100644 --- a/src/include/module/crossover/crossover_common.h +++ b/src/include/module/crossover/crossover_common.h @@ -8,6 +8,7 @@ #ifndef __SOF_CROSSOVER_COMMON_H__ #define __SOF_CROSSOVER_COMMON_H__ +#include #include #include @@ -39,17 +40,19 @@ typedef void (*crossover_split)(int32_t in, int32_t out[], extern const crossover_split crossover_split_fnmap[]; /* crossover init function */ -int crossover_init_coef_ch(struct sof_eq_iir_biquad *coef, +int crossover_init_coef_ch(struct processing_module *mod, + struct sof_eq_iir_biquad *coef, struct crossover_state *ch_state, int32_t num_sinks); /** * \brief Reset the state of an LR4 filter. */ -static inline void crossover_reset_state_lr4(struct iir_state_df1 *lr4) +static inline void crossover_reset_state_lr4(struct processing_module *mod, + struct iir_state_df1 *lr4) { - rfree(lr4->coef); - rfree(lr4->delay); + mod_free(mod, lr4->coef); + mod_free(mod, lr4->delay); lr4->coef = NULL; lr4->delay = NULL; @@ -59,13 +62,14 @@ static inline void crossover_reset_state_lr4(struct iir_state_df1 *lr4) * \brief Reset the state (coefficients and delay) of the crossover filter * of a single channel. */ -static inline void crossover_reset_state_ch(struct crossover_state *ch_state) +static inline void crossover_reset_state_ch(struct processing_module *mod, + struct crossover_state *ch_state) { int i; for (i = 0; i < CROSSOVER_MAX_LR4; i++) { - crossover_reset_state_lr4(&ch_state->lowpass[i]); - crossover_reset_state_lr4(&ch_state->highpass[i]); + crossover_reset_state_lr4(mod, &ch_state->lowpass[i]); + crossover_reset_state_lr4(mod, &ch_state->highpass[i]); } } diff --git a/src/include/module/module/base.h b/src/include/module/module/base.h index ed116681afd2..49007775562b 100644 --- a/src/include/module/module/base.h +++ b/src/include/module/module/base.h @@ -16,9 +16,27 @@ #include "interface.h" #include "../ipc4/base-config.h" +#ifdef SOF_MODULE_API_PRIVATE +#include +#endif + #define module_get_private_data(mod) ((mod)->priv.private) #define module_set_private_data(mod, data) ((mod)->priv.private = data) +/** + * \struct module_ext_init_data + * \brief Container for found ext init object pointers + * This struct contains pointers that point to IPC payload directly. The + * module should store what it needs in its init() callback as the data + * is not valid after that. + */ +struct ipc4_module_init_ext_obj_dp_data; +struct module_ext_init_data { + const struct ipc4_module_init_ext_obj_dp_data *dp_data; + const void *module_data; + size_t module_data_size; +}; + /** * \struct module_config * \brief Module config container, used for both config types. @@ -34,9 +52,7 @@ struct module_config { uint8_t nb_output_pins; struct ipc4_input_pin_format *input_pins; struct ipc4_output_pin_format *output_pins; - uint32_t domain_id; /* userspace domain ID */ - uint32_t stack_bytes; /* stack size in bytes, 0 means default value */ - uint32_t heap_bytes; /* max heap size in bytes, 0 means default value */ + struct module_ext_init_data *ext_data; /**< IPC payload pointers, NULL after init() */ #endif }; @@ -71,6 +87,7 @@ enum module_processing_type { }; struct userspace_context; +struct k_mem_domain; /* * A pointer to this structure is passed to module API functions (from struct module_interface). @@ -185,6 +202,9 @@ struct processing_module { #if CONFIG_USERSPACE struct userspace_context *user_ctx; #endif /* CONFIG_USERSPACE */ +#if CONFIG_SOF_USERSPACE_APPLICATION + struct k_mem_domain *mdom; +#endif #endif /* SOF_MODULE_PRIVATE */ }; diff --git a/src/include/sof/audio/audio_buffer.h b/src/include/sof/audio/audio_buffer.h index 5156971d515f..e627fc0494fa 100644 --- a/src/include/sof/audio/audio_buffer.h +++ b/src/include/sof/audio/audio_buffer.h @@ -110,6 +110,8 @@ struct sof_audio_buffer { * should not be in struct sof_audio_buffer at all, kept for pipeline2.0 transition */ bool walking; /**< indicates if the buffer is being walked */ + + struct k_heap *heap; }; #if CONFIG_PIPELINE_2_0 @@ -322,6 +324,14 @@ void audio_buffer_reset(struct sof_audio_buffer *buffer) { if (buffer->ops->reset) buffer->ops->reset(buffer); + +#if CONFIG_PIPELINE_2_0 + if (buffer->secondary_buffer_sink && buffer->secondary_buffer_sink->ops->reset) + buffer->secondary_buffer_sink->ops->reset(buffer->secondary_buffer_sink); + + if (buffer->secondary_buffer_source && buffer->secondary_buffer_source->ops->reset) + buffer->secondary_buffer_source->ops->reset(buffer->secondary_buffer_source); +#endif } /* Audio-buffer wrappers for the source-sink API */ @@ -337,5 +347,6 @@ int audio_buffer_sink_on_audio_format_set(struct sof_sink *sink); int audio_buffer_sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req); +uint32_t audio_buffer_sink_get_lft(struct sof_sink *sink); #endif /* __SOF_AUDIO_BUFFER__ */ diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index 768db978bb02..91c09ef2e510 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -211,12 +211,16 @@ struct buffer_cb_free { buffer->cb_type = type; \ } while (0) +struct k_heap; + /* pipeline buffer creation and destruction */ -struct comp_buffer *buffer_alloc(size_t size, uint32_t flags, uint32_t align, +struct comp_buffer *buffer_alloc(struct k_heap *heap, size_t size, uint32_t flags, uint32_t align, bool is_shared); -struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_size, +struct comp_buffer *buffer_alloc_range(struct k_heap *heap, size_t preferred_size, + size_t minimum_size, uint32_t flags, uint32_t align, bool is_shared); -struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared); +struct comp_buffer *buffer_new(struct k_heap *heap, const struct sof_ipc_buffer *desc, + bool is_shared); int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment); int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, size_t minimum_size, diff --git a/src/include/sof/audio/cadence/mp3_enc/xa_mp3_enc_api.h b/src/include/sof/audio/cadence/mp3_enc/xa_mp3_enc_api.h new file mode 100644 index 000000000000..aac961e63cf9 --- /dev/null +++ b/src/include/sof/audio/cadence/mp3_enc/xa_mp3_enc_api.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022-2025 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +#ifndef __XA_MP3ENC_CONFIG_PARAMS_H__ +#define __XA_MP3ENC_CONFIG_PARAMS_H__ + +/* mp3_enc-specific configuration parameters */ +enum xa_config_param_mp3_enc { + XA_MP3ENC_CONFIG_PARAM_PCM_WDSZ = 0, + XA_MP3ENC_CONFIG_PARAM_SAMP_FREQ = 1, + XA_MP3ENC_CONFIG_PARAM_NUM_CHANNELS = 2, + XA_MP3ENC_CONFIG_PARAM_BITRATE = 3 +#ifdef ENABLE_CUT_OFF_FREQ_CONFIG + , XA_MP3ENC_CONFIG_FATAL_FRAC_BANDWIDTH = 4 +#endif // ENABLE_CUT_OFF_FREQ_CONFIG +}; + +/* commands */ +#include "xa_apicmd_standards.h" + +/* mp3_enc-specific commands */ +/* (none) */ + +/* mp3_enc-specific command types */ +/* (none) */ + +/* error codes */ +#include "xa_error_standards.h" + +#define XA_CODEC_MP3_ENC 2 + +/* mp3_enc-specific error_codes */ +/*****************************************************************************/ +/* Class 0: API Errors */ +/*****************************************************************************/ +/* Nonfatal Errors */ +/* (none) */ +/* Fatal Errors */ +/* (none) */ + +/*****************************************************************************/ +/* Class 1: Configuration Errors */ +/*****************************************************************************/ +/* Nonfatal Errors */ +enum xa_error_nonfatal_config_mp3_enc { + XA_MP3ENC_CONFIG_NONFATAL_INVALID_BITRATE = XA_ERROR_CODE(xa_severity_nonfatal, xa_class_config, XA_CODEC_MP3_ENC, 0) +}; + +/* Fatal Errors */ +enum xa_error_fatal_config_mp3_enc { + XA_MP3ENC_CONFIG_FATAL_SAMP_FREQ = XA_ERROR_CODE(xa_severity_fatal, xa_class_config, XA_CODEC_MP3_ENC, 0), + XA_MP3ENC_CONFIG_FATAL_NUM_CHANNELS = XA_ERROR_CODE(xa_severity_fatal, xa_class_config, XA_CODEC_MP3_ENC, 1), + XA_MP3ENC_CONFIG_FATAL_PCM_WDSZ = XA_ERROR_CODE(xa_severity_fatal, xa_class_config, XA_CODEC_MP3_ENC, 2) +#ifdef ENABLE_CUT_OFF_FREQ_CONFIG + , XA_MP3ENC_CONFIG_PARAM_FRAC_BANDWIDTH = XA_ERROR_CODE(xa_severity_fatal, xa_class_config, XA_CODEC_MP3_ENC, 3) +#endif // ENABLE_CUT_OFF_FREQ_CONFIG +}; +/* (none) */ + +#include "xa_type_def.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ +xa_codec_func_t xa_mp3_enc; +#if defined(__cplusplus) +} +#endif /* __cplusplus */ +#endif /* __XA_MP3ENC_CONFIG_PARAMS_H__ */ diff --git a/src/include/sof/audio/coefficients/fft/twiddle_3072_32.h b/src/include/sof/audio/coefficients/fft/twiddle_3072_32.h new file mode 100644 index 000000000000..3024c7b49cff --- /dev/null +++ b/src/include/sof/audio/coefficients/fft/twiddle_3072_32.h @@ -0,0 +1,4120 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. All rights reserved. + * + */ + +/* Twiddle factors in Q1.31 format */ + +#ifndef __INCLUDE_TWIDDLE_3072_32_H__ +#define __INCLUDE_TWIDDLE_3072_32_H__ + +#include + +#define FFT_MULTI_TWIDDLE_SIZE 2048 + +/* in Q1.31, generated from cos(i * 2 * pi / FFT_SIZE_MAX) */ +const int32_t multi_twiddle_real_32[FFT_MULTI_TWIDDLE_SIZE] = { + 2147483647, + 2147479156, + 2147465681, + 2147443222, + 2147411780, + 2147371355, + 2147321946, + 2147263555, + 2147196181, + 2147119825, + 2147034487, + 2146940167, + 2146836866, + 2146724584, + 2146603322, + 2146473080, + 2146333858, + 2146185658, + 2146028480, + 2145862324, + 2145687192, + 2145503083, + 2145310000, + 2145107942, + 2144896910, + 2144676905, + 2144447929, + 2144209982, + 2143963065, + 2143707180, + 2143442326, + 2143168506, + 2142885721, + 2142593971, + 2142293258, + 2141983583, + 2141664948, + 2141337354, + 2141000801, + 2140655293, + 2140300829, + 2139937412, + 2139565043, + 2139183723, + 2138793455, + 2138394240, + 2137986079, + 2137568974, + 2137142927, + 2136707940, + 2136264015, + 2135811153, + 2135349356, + 2134878626, + 2134398966, + 2133910377, + 2133412861, + 2132906420, + 2132391057, + 2131866773, + 2131333572, + 2130791454, + 2130240422, + 2129680480, + 2129111628, + 2128533869, + 2127947206, + 2127351642, + 2126747178, + 2126133817, + 2125511562, + 2124880416, + 2124240380, + 2123591458, + 2122933653, + 2122266967, + 2121591402, + 2120906963, + 2120213651, + 2119511470, + 2118800422, + 2118080511, + 2117351739, + 2116614110, + 2115867626, + 2115112291, + 2114348108, + 2113575080, + 2112793210, + 2112002502, + 2111202959, + 2110394584, + 2109577380, + 2108751352, + 2107916502, + 2107072834, + 2106220352, + 2105359059, + 2104488958, + 2103610054, + 2102722350, + 2101825849, + 2100920556, + 2100006474, + 2099083608, + 2098151960, + 2097211535, + 2096262337, + 2095304370, + 2094337637, + 2093362143, + 2092377892, + 2091384888, + 2090383135, + 2089372638, + 2088353400, + 2087325426, + 2086288720, + 2085243286, + 2084189130, + 2083126254, + 2082054665, + 2080974365, + 2079885360, + 2078787655, + 2077681253, + 2076566160, + 2075442379, + 2074309917, + 2073168777, + 2072018965, + 2070860485, + 2069693342, + 2068517540, + 2067333086, + 2066139983, + 2064938237, + 2063727853, + 2062508835, + 2061281190, + 2060044922, + 2058800036, + 2057546537, + 2056284431, + 2055013723, + 2053734418, + 2052446522, + 2051150040, + 2049844978, + 2048531340, + 2047209133, + 2045878362, + 2044539032, + 2043191150, + 2041834720, + 2040469748, + 2039096241, + 2037714204, + 2036323642, + 2034924562, + 2033516969, + 2032100869, + 2030676269, + 2029243173, + 2027801589, + 2026351522, + 2024892978, + 2023425963, + 2021950484, + 2020466546, + 2018974156, + 2017473321, + 2015964045, + 2014446336, + 2012920201, + 2011385644, + 2009842674, + 2008291295, + 2006731516, + 2005163342, + 2003586779, + 2002001835, + 2000408516, + 1998806829, + 1997196780, + 1995578377, + 1993951625, + 1992316532, + 1990673105, + 1989021350, + 1987361274, + 1985692885, + 1984016189, + 1982331193, + 1980637905, + 1978936331, + 1977226479, + 1975508355, + 1973781967, + 1972047323, + 1970304428, + 1968553292, + 1966793920, + 1965026321, + 1963250501, + 1961466469, + 1959674231, + 1957873796, + 1956065170, + 1954248361, + 1952423377, + 1950590226, + 1948748914, + 1946899451, + 1945041843, + 1943176098, + 1941302225, + 1939420231, + 1937530123, + 1935631910, + 1933725600, + 1931811201, + 1929888720, + 1927958166, + 1926019547, + 1924072871, + 1922118145, + 1920155379, + 1918184581, + 1916205758, + 1914218919, + 1912224073, + 1910221227, + 1908210390, + 1906191570, + 1904164776, + 1902130017, + 1900087301, + 1898036636, + 1895978031, + 1893911494, + 1891837035, + 1889754661, + 1887664383, + 1885566207, + 1883460144, + 1881346202, + 1879224389, + 1877094716, + 1874957189, + 1872811820, + 1870658615, + 1868497586, + 1866328740, + 1864152086, + 1861967634, + 1859775393, + 1857575372, + 1855367581, + 1853152028, + 1850928722, + 1848697674, + 1846458892, + 1844212386, + 1841958164, + 1839696238, + 1837426615, + 1835149306, + 1832864320, + 1830571667, + 1828271356, + 1825963397, + 1823647799, + 1821324572, + 1818993726, + 1816655271, + 1814309216, + 1811955572, + 1809594347, + 1807225553, + 1804849198, + 1802465294, + 1800073849, + 1797674873, + 1795268378, + 1792854372, + 1790432867, + 1788003871, + 1785567396, + 1783123452, + 1780672048, + 1778213194, + 1775746903, + 1773273182, + 1770792044, + 1768303498, + 1765807555, + 1763304224, + 1760793518, + 1758275445, + 1755750017, + 1753217244, + 1750677137, + 1748129707, + 1745574963, + 1743012918, + 1740443581, + 1737866963, + 1735283075, + 1732691928, + 1730093532, + 1727487899, + 1724875040, + 1722254965, + 1719627685, + 1716993211, + 1714351555, + 1711702727, + 1709046739, + 1706383601, + 1703713325, + 1701035922, + 1698351403, + 1695659779, + 1692961062, + 1690255263, + 1687542393, + 1684822463, + 1682095486, + 1679361471, + 1676620432, + 1673872378, + 1671117323, + 1668355276, + 1665586251, + 1662810258, + 1660027308, + 1657237415, + 1654440588, + 1651636841, + 1648826185, + 1646008631, + 1643184191, + 1640352877, + 1637514702, + 1634669676, + 1631817811, + 1628959121, + 1626093616, + 1623221309, + 1620342211, + 1617456335, + 1614563692, + 1611664296, + 1608758157, + 1605845289, + 1602925703, + 1599999411, + 1597066426, + 1594126760, + 1591180426, + 1588227435, + 1585267800, + 1582301533, + 1579328647, + 1576349155, + 1573363068, + 1570370399, + 1567371161, + 1564365367, + 1561353028, + 1558334157, + 1555308768, + 1552276872, + 1549238483, + 1546193612, + 1543142274, + 1540084480, + 1537020244, + 1533949577, + 1530872494, + 1527789007, + 1524699129, + 1521602872, + 1518500250, + 1515391276, + 1512275962, + 1509154322, + 1506026369, + 1502892116, + 1499751576, + 1496604762, + 1493451687, + 1490292364, + 1487126808, + 1483955030, + 1480777044, + 1477592864, + 1474402503, + 1471205974, + 1468003290, + 1464794466, + 1461579514, + 1458358447, + 1455131280, + 1451898025, + 1448658697, + 1445413309, + 1442161874, + 1438904406, + 1435640919, + 1432371426, + 1429095941, + 1425814478, + 1422527051, + 1419233672, + 1415934356, + 1412629117, + 1409317969, + 1406000925, + 1402678000, + 1399349206, + 1396014559, + 1392674072, + 1389327759, + 1385975633, + 1382617710, + 1379254004, + 1375884527, + 1372509294, + 1369128320, + 1365741619, + 1362349204, + 1358951090, + 1355547292, + 1352137822, + 1348722696, + 1345301929, + 1341875533, + 1338443524, + 1335005916, + 1331562723, + 1328113960, + 1324659641, + 1321199781, + 1317734393, + 1314263493, + 1310787095, + 1307305214, + 1303817864, + 1300325060, + 1296826816, + 1293323147, + 1289814068, + 1286299593, + 1282779738, + 1279254516, + 1275723942, + 1272188032, + 1268646800, + 1265100260, + 1261548429, + 1257991320, + 1254428948, + 1250861329, + 1247288478, + 1243710408, + 1240127136, + 1236538675, + 1232945043, + 1229346252, + 1225742318, + 1222133257, + 1218519084, + 1214899813, + 1211275460, + 1207646039, + 1204011567, + 1200372058, + 1196727527, + 1193077991, + 1189423463, + 1185763960, + 1182099496, + 1178430087, + 1174755748, + 1171076495, + 1167392344, + 1163703308, + 1160009405, + 1156310649, + 1152607055, + 1148898640, + 1145185419, + 1141467408, + 1137744621, + 1134017074, + 1130284784, + 1126547765, + 1122806034, + 1119059606, + 1115308496, + 1111552721, + 1107792296, + 1104027237, + 1100257559, + 1096483278, + 1092704411, + 1088920972, + 1085132978, + 1081340445, + 1077543388, + 1073741824, + 1069935768, + 1066125236, + 1062310244, + 1058490808, + 1054666944, + 1050838668, + 1047005996, + 1043168945, + 1039327529, + 1035481766, + 1031631671, + 1027777260, + 1023918550, + 1020055556, + 1016188296, + 1012316784, + 1008441038, + 1004561072, + 1000676905, + 996788551, + 992896028, + 988999351, + 985098537, + 981193602, + 977284562, + 973371434, + 969454234, + 965532978, + 961607684, + 957678367, + 953745043, + 949807730, + 945866443, + 941921200, + 937972016, + 934018909, + 930061894, + 926100989, + 922136209, + 918167572, + 914195094, + 910218791, + 906238681, + 902254780, + 898267104, + 894275671, + 890280497, + 886281598, + 882278992, + 878272695, + 874262724, + 870249095, + 866231826, + 862210934, + 858186435, + 854158345, + 850126682, + 846091463, + 842052705, + 838010424, + 833964638, + 829915362, + 825862615, + 821806413, + 817746774, + 813683713, + 809617249, + 805547397, + 801474176, + 797397602, + 793317693, + 789234464, + 785147934, + 781058120, + 776965038, + 772868706, + 768769141, + 764666360, + 760560380, + 756451218, + 752338892, + 748223418, + 744104815, + 739983099, + 735858287, + 731730397, + 727599446, + 723465451, + 719328430, + 715188400, + 711045377, + 706899381, + 702750427, + 698598533, + 694443717, + 690285996, + 686125387, + 681961908, + 677795576, + 673626408, + 669454423, + 665279637, + 661102068, + 656921734, + 652738651, + 648552838, + 644364312, + 640173090, + 635979190, + 631782630, + 627583426, + 623381598, + 619177161, + 614970135, + 610760536, + 606548381, + 602333690, + 598116479, + 593896765, + 589674567, + 585449903, + 581222789, + 576993244, + 572761285, + 568526931, + 564290197, + 560051104, + 555809667, + 551565905, + 547319836, + 543071478, + 538820847, + 534567963, + 530312842, + 526055503, + 521795963, + 517534240, + 513270353, + 509004318, + 504736154, + 500465878, + 496193509, + 491919064, + 487642562, + 483364019, + 479083454, + 474800886, + 470516330, + 466229807, + 461941333, + 457650927, + 453358607, + 449064389, + 444768294, + 440470337, + 436170538, + 431868915, + 427565485, + 423260266, + 418953276, + 414644534, + 410334058, + 406021865, + 401707973, + 397392401, + 393075166, + 388756287, + 384435782, + 380113669, + 375789965, + 371464690, + 367137861, + 362809495, + 358479612, + 354148230, + 349815365, + 345481038, + 341145265, + 336808065, + 332469456, + 328129457, + 323788084, + 319445358, + 315101295, + 310755913, + 306409232, + 302061269, + 297712042, + 293361570, + 289009871, + 284656963, + 280302863, + 275947592, + 271591166, + 267233603, + 262874923, + 258515144, + 254154282, + 249792358, + 245429388, + 241065392, + 236700388, + 232334393, + 227967426, + 223599506, + 219230650, + 214860878, + 210490206, + 206118654, + 201746240, + 197372981, + 192998897, + 188624006, + 184248325, + 179871874, + 175494670, + 171116733, + 166738079, + 162358728, + 157978697, + 153598006, + 149216672, + 144834714, + 140452151, + 136068999, + 131685278, + 127301007, + 122916203, + 118530885, + 114145071, + 109758779, + 105372028, + 100984837, + 96597223, + 92209205, + 87820801, + 83432030, + 79042909, + 74653459, + 70263695, + 65873638, + 61483306, + 57092716, + 52701887, + 48310838, + 43919586, + 39528151, + 35136551, + 30744804, + 26352928, + 21960942, + 17568864, + 13176712, + 8784505, + 4392262, + 0, + -4392262, + -8784505, + -13176712, + -17568864, + -21960942, + -26352928, + -30744804, + -35136551, + -39528151, + -43919586, + -48310838, + -52701887, + -57092716, + -61483306, + -65873638, + -70263695, + -74653459, + -79042909, + -83432030, + -87820801, + -92209205, + -96597223, + -100984837, + -105372028, + -109758779, + -114145071, + -118530885, + -122916203, + -127301007, + -131685278, + -136068999, + -140452151, + -144834714, + -149216672, + -153598006, + -157978697, + -162358728, + -166738079, + -171116733, + -175494670, + -179871874, + -184248325, + -188624006, + -192998897, + -197372981, + -201746240, + -206118654, + -210490206, + -214860878, + -219230650, + -223599506, + -227967426, + -232334393, + -236700388, + -241065392, + -245429388, + -249792358, + -254154282, + -258515144, + -262874923, + -267233603, + -271591166, + -275947592, + -280302863, + -284656963, + -289009871, + -293361570, + -297712042, + -302061269, + -306409232, + -310755913, + -315101295, + -319445358, + -323788084, + -328129457, + -332469456, + -336808065, + -341145265, + -345481038, + -349815365, + -354148230, + -358479612, + -362809495, + -367137861, + -371464690, + -375789965, + -380113669, + -384435782, + -388756287, + -393075166, + -397392401, + -401707973, + -406021865, + -410334058, + -414644534, + -418953276, + -423260266, + -427565485, + -431868915, + -436170538, + -440470337, + -444768294, + -449064389, + -453358607, + -457650927, + -461941333, + -466229807, + -470516330, + -474800886, + -479083454, + -483364019, + -487642562, + -491919064, + -496193509, + -500465878, + -504736154, + -509004318, + -513270353, + -517534240, + -521795963, + -526055503, + -530312842, + -534567963, + -538820847, + -543071478, + -547319836, + -551565905, + -555809667, + -560051104, + -564290197, + -568526931, + -572761285, + -576993244, + -581222789, + -585449903, + -589674567, + -593896765, + -598116479, + -602333690, + -606548381, + -610760536, + -614970135, + -619177161, + -623381598, + -627583426, + -631782630, + -635979190, + -640173090, + -644364312, + -648552838, + -652738651, + -656921734, + -661102068, + -665279637, + -669454423, + -673626408, + -677795576, + -681961908, + -686125387, + -690285996, + -694443717, + -698598533, + -702750427, + -706899381, + -711045377, + -715188400, + -719328430, + -723465451, + -727599446, + -731730397, + -735858287, + -739983099, + -744104815, + -748223418, + -752338892, + -756451218, + -760560380, + -764666360, + -768769141, + -772868706, + -776965038, + -781058120, + -785147934, + -789234464, + -793317693, + -797397602, + -801474176, + -805547397, + -809617249, + -813683713, + -817746774, + -821806413, + -825862615, + -829915362, + -833964638, + -838010424, + -842052705, + -846091463, + -850126682, + -854158345, + -858186435, + -862210934, + -866231826, + -870249095, + -874262724, + -878272695, + -882278992, + -886281598, + -890280497, + -894275671, + -898267104, + -902254780, + -906238681, + -910218791, + -914195094, + -918167572, + -922136209, + -926100989, + -930061894, + -934018909, + -937972016, + -941921200, + -945866443, + -949807730, + -953745043, + -957678367, + -961607684, + -965532978, + -969454234, + -973371434, + -977284562, + -981193602, + -985098537, + -988999351, + -992896028, + -996788551, + -1000676905, + -1004561072, + -1008441038, + -1012316784, + -1016188296, + -1020055556, + -1023918550, + -1027777260, + -1031631671, + -1035481766, + -1039327529, + -1043168945, + -1047005996, + -1050838668, + -1054666944, + -1058490808, + -1062310244, + -1066125236, + -1069935768, + -1073741824, + -1077543388, + -1081340445, + -1085132978, + -1088920972, + -1092704411, + -1096483278, + -1100257559, + -1104027237, + -1107792296, + -1111552721, + -1115308496, + -1119059606, + -1122806034, + -1126547765, + -1130284784, + -1134017074, + -1137744621, + -1141467408, + -1145185419, + -1148898640, + -1152607055, + -1156310649, + -1160009405, + -1163703308, + -1167392344, + -1171076495, + -1174755748, + -1178430087, + -1182099496, + -1185763960, + -1189423463, + -1193077991, + -1196727527, + -1200372058, + -1204011567, + -1207646039, + -1211275460, + -1214899813, + -1218519084, + -1222133257, + -1225742318, + -1229346252, + -1232945043, + -1236538675, + -1240127136, + -1243710408, + -1247288478, + -1250861329, + -1254428948, + -1257991320, + -1261548429, + -1265100260, + -1268646800, + -1272188032, + -1275723942, + -1279254516, + -1282779738, + -1286299593, + -1289814068, + -1293323147, + -1296826816, + -1300325060, + -1303817864, + -1307305214, + -1310787095, + -1314263493, + -1317734393, + -1321199781, + -1324659641, + -1328113960, + -1331562723, + -1335005916, + -1338443524, + -1341875533, + -1345301929, + -1348722696, + -1352137822, + -1355547292, + -1358951090, + -1362349204, + -1365741619, + -1369128320, + -1372509294, + -1375884527, + -1379254004, + -1382617710, + -1385975633, + -1389327759, + -1392674072, + -1396014559, + -1399349206, + -1402678000, + -1406000925, + -1409317969, + -1412629117, + -1415934356, + -1419233672, + -1422527051, + -1425814478, + -1429095941, + -1432371426, + -1435640919, + -1438904406, + -1442161874, + -1445413309, + -1448658697, + -1451898025, + -1455131280, + -1458358447, + -1461579514, + -1464794466, + -1468003290, + -1471205974, + -1474402503, + -1477592864, + -1480777044, + -1483955030, + -1487126808, + -1490292364, + -1493451687, + -1496604762, + -1499751576, + -1502892116, + -1506026369, + -1509154322, + -1512275962, + -1515391276, + -1518500250, + -1521602872, + -1524699129, + -1527789007, + -1530872494, + -1533949577, + -1537020244, + -1540084480, + -1543142274, + -1546193612, + -1549238483, + -1552276872, + -1555308768, + -1558334157, + -1561353028, + -1564365367, + -1567371161, + -1570370399, + -1573363068, + -1576349155, + -1579328647, + -1582301533, + -1585267800, + -1588227435, + -1591180426, + -1594126760, + -1597066426, + -1599999411, + -1602925703, + -1605845289, + -1608758157, + -1611664296, + -1614563692, + -1617456335, + -1620342211, + -1623221309, + -1626093616, + -1628959121, + -1631817811, + -1634669676, + -1637514702, + -1640352877, + -1643184191, + -1646008631, + -1648826185, + -1651636841, + -1654440588, + -1657237415, + -1660027308, + -1662810258, + -1665586251, + -1668355276, + -1671117323, + -1673872378, + -1676620432, + -1679361471, + -1682095486, + -1684822463, + -1687542393, + -1690255263, + -1692961062, + -1695659779, + -1698351403, + -1701035922, + -1703713325, + -1706383601, + -1709046739, + -1711702727, + -1714351555, + -1716993211, + -1719627685, + -1722254965, + -1724875040, + -1727487899, + -1730093532, + -1732691928, + -1735283075, + -1737866963, + -1740443581, + -1743012918, + -1745574963, + -1748129707, + -1750677137, + -1753217244, + -1755750017, + -1758275445, + -1760793518, + -1763304224, + -1765807555, + -1768303498, + -1770792044, + -1773273182, + -1775746903, + -1778213194, + -1780672048, + -1783123452, + -1785567396, + -1788003871, + -1790432867, + -1792854372, + -1795268378, + -1797674873, + -1800073849, + -1802465294, + -1804849198, + -1807225553, + -1809594347, + -1811955572, + -1814309216, + -1816655271, + -1818993726, + -1821324572, + -1823647799, + -1825963397, + -1828271356, + -1830571667, + -1832864320, + -1835149306, + -1837426615, + -1839696238, + -1841958164, + -1844212386, + -1846458892, + -1848697674, + -1850928722, + -1853152028, + -1855367581, + -1857575372, + -1859775393, + -1861967634, + -1864152086, + -1866328740, + -1868497586, + -1870658615, + -1872811820, + -1874957189, + -1877094716, + -1879224389, + -1881346202, + -1883460144, + -1885566207, + -1887664383, + -1889754661, + -1891837035, + -1893911494, + -1895978031, + -1898036636, + -1900087301, + -1902130017, + -1904164776, + -1906191570, + -1908210390, + -1910221227, + -1912224073, + -1914218919, + -1916205758, + -1918184581, + -1920155379, + -1922118145, + -1924072871, + -1926019547, + -1927958166, + -1929888720, + -1931811201, + -1933725600, + -1935631910, + -1937530123, + -1939420231, + -1941302225, + -1943176098, + -1945041843, + -1946899451, + -1948748914, + -1950590226, + -1952423377, + -1954248361, + -1956065170, + -1957873796, + -1959674231, + -1961466469, + -1963250501, + -1965026321, + -1966793920, + -1968553292, + -1970304428, + -1972047323, + -1973781967, + -1975508355, + -1977226479, + -1978936331, + -1980637905, + -1982331193, + -1984016189, + -1985692885, + -1987361274, + -1989021350, + -1990673105, + -1992316532, + -1993951625, + -1995578377, + -1997196780, + -1998806829, + -2000408516, + -2002001835, + -2003586779, + -2005163342, + -2006731516, + -2008291295, + -2009842674, + -2011385644, + -2012920201, + -2014446336, + -2015964045, + -2017473321, + -2018974156, + -2020466546, + -2021950484, + -2023425963, + -2024892978, + -2026351522, + -2027801589, + -2029243173, + -2030676269, + -2032100869, + -2033516969, + -2034924562, + -2036323642, + -2037714204, + -2039096241, + -2040469748, + -2041834720, + -2043191150, + -2044539032, + -2045878362, + -2047209133, + -2048531340, + -2049844978, + -2051150040, + -2052446522, + -2053734418, + -2055013723, + -2056284431, + -2057546537, + -2058800036, + -2060044922, + -2061281190, + -2062508835, + -2063727853, + -2064938237, + -2066139983, + -2067333086, + -2068517540, + -2069693342, + -2070860485, + -2072018965, + -2073168777, + -2074309917, + -2075442379, + -2076566160, + -2077681253, + -2078787655, + -2079885360, + -2080974365, + -2082054665, + -2083126254, + -2084189130, + -2085243286, + -2086288720, + -2087325426, + -2088353400, + -2089372638, + -2090383135, + -2091384888, + -2092377892, + -2093362143, + -2094337637, + -2095304370, + -2096262337, + -2097211535, + -2098151960, + -2099083608, + -2100006474, + -2100920556, + -2101825849, + -2102722350, + -2103610054, + -2104488958, + -2105359059, + -2106220352, + -2107072834, + -2107916502, + -2108751352, + -2109577380, + -2110394584, + -2111202959, + -2112002502, + -2112793210, + -2113575080, + -2114348108, + -2115112291, + -2115867626, + -2116614110, + -2117351739, + -2118080511, + -2118800422, + -2119511470, + -2120213651, + -2120906963, + -2121591402, + -2122266967, + -2122933653, + -2123591458, + -2124240380, + -2124880416, + -2125511562, + -2126133817, + -2126747178, + -2127351642, + -2127947206, + -2128533869, + -2129111628, + -2129680480, + -2130240422, + -2130791454, + -2131333572, + -2131866773, + -2132391057, + -2132906420, + -2133412861, + -2133910377, + -2134398966, + -2134878626, + -2135349356, + -2135811153, + -2136264015, + -2136707940, + -2137142927, + -2137568974, + -2137986079, + -2138394240, + -2138793455, + -2139183723, + -2139565043, + -2139937412, + -2140300829, + -2140655293, + -2141000801, + -2141337354, + -2141664948, + -2141983583, + -2142293258, + -2142593971, + -2142885721, + -2143168506, + -2143442326, + -2143707180, + -2143963065, + -2144209982, + -2144447929, + -2144676905, + -2144896910, + -2145107942, + -2145310000, + -2145503083, + -2145687192, + -2145862324, + -2146028480, + -2146185658, + -2146333858, + -2146473080, + -2146603322, + -2146724584, + -2146836866, + -2146940167, + -2147034487, + -2147119825, + -2147196181, + -2147263555, + -2147321946, + -2147371355, + -2147411780, + -2147443222, + -2147465681, + -2147479156, + -2147483647, + -2147479156, + -2147465681, + -2147443222, + -2147411780, + -2147371355, + -2147321946, + -2147263555, + -2147196181, + -2147119825, + -2147034487, + -2146940167, + -2146836866, + -2146724584, + -2146603322, + -2146473080, + -2146333858, + -2146185658, + -2146028480, + -2145862324, + -2145687192, + -2145503083, + -2145310000, + -2145107942, + -2144896910, + -2144676905, + -2144447929, + -2144209982, + -2143963065, + -2143707180, + -2143442326, + -2143168506, + -2142885721, + -2142593971, + -2142293258, + -2141983583, + -2141664948, + -2141337354, + -2141000801, + -2140655293, + -2140300829, + -2139937412, + -2139565043, + -2139183723, + -2138793455, + -2138394240, + -2137986079, + -2137568974, + -2137142927, + -2136707940, + -2136264015, + -2135811153, + -2135349356, + -2134878626, + -2134398966, + -2133910377, + -2133412861, + -2132906420, + -2132391057, + -2131866773, + -2131333572, + -2130791454, + -2130240422, + -2129680480, + -2129111628, + -2128533869, + -2127947206, + -2127351642, + -2126747178, + -2126133817, + -2125511562, + -2124880416, + -2124240380, + -2123591458, + -2122933653, + -2122266967, + -2121591402, + -2120906963, + -2120213651, + -2119511470, + -2118800422, + -2118080511, + -2117351739, + -2116614110, + -2115867626, + -2115112291, + -2114348108, + -2113575080, + -2112793210, + -2112002502, + -2111202959, + -2110394584, + -2109577380, + -2108751352, + -2107916502, + -2107072834, + -2106220352, + -2105359059, + -2104488958, + -2103610054, + -2102722350, + -2101825849, + -2100920556, + -2100006474, + -2099083608, + -2098151960, + -2097211535, + -2096262337, + -2095304370, + -2094337637, + -2093362143, + -2092377892, + -2091384888, + -2090383135, + -2089372638, + -2088353400, + -2087325426, + -2086288720, + -2085243286, + -2084189130, + -2083126254, + -2082054665, + -2080974365, + -2079885360, + -2078787655, + -2077681253, + -2076566160, + -2075442379, + -2074309917, + -2073168777, + -2072018965, + -2070860485, + -2069693342, + -2068517540, + -2067333086, + -2066139983, + -2064938237, + -2063727853, + -2062508835, + -2061281190, + -2060044922, + -2058800036, + -2057546537, + -2056284431, + -2055013723, + -2053734418, + -2052446522, + -2051150040, + -2049844978, + -2048531340, + -2047209133, + -2045878362, + -2044539032, + -2043191150, + -2041834720, + -2040469748, + -2039096241, + -2037714204, + -2036323642, + -2034924562, + -2033516969, + -2032100869, + -2030676269, + -2029243173, + -2027801589, + -2026351522, + -2024892978, + -2023425963, + -2021950484, + -2020466546, + -2018974156, + -2017473321, + -2015964045, + -2014446336, + -2012920201, + -2011385644, + -2009842674, + -2008291295, + -2006731516, + -2005163342, + -2003586779, + -2002001835, + -2000408516, + -1998806829, + -1997196780, + -1995578377, + -1993951625, + -1992316532, + -1990673105, + -1989021350, + -1987361274, + -1985692885, + -1984016189, + -1982331193, + -1980637905, + -1978936331, + -1977226479, + -1975508355, + -1973781967, + -1972047323, + -1970304428, + -1968553292, + -1966793920, + -1965026321, + -1963250501, + -1961466469, + -1959674231, + -1957873796, + -1956065170, + -1954248361, + -1952423377, + -1950590226, + -1948748914, + -1946899451, + -1945041843, + -1943176098, + -1941302225, + -1939420231, + -1937530123, + -1935631910, + -1933725600, + -1931811201, + -1929888720, + -1927958166, + -1926019547, + -1924072871, + -1922118145, + -1920155379, + -1918184581, + -1916205758, + -1914218919, + -1912224073, + -1910221227, + -1908210390, + -1906191570, + -1904164776, + -1902130017, + -1900087301, + -1898036636, + -1895978031, + -1893911494, + -1891837035, + -1889754661, + -1887664383, + -1885566207, + -1883460144, + -1881346202, + -1879224389, + -1877094716, + -1874957189, + -1872811820, + -1870658615, + -1868497586, + -1866328740, + -1864152086, + -1861967634, + -1859775393, + -1857575372, + -1855367581, + -1853152028, + -1850928722, + -1848697674, + -1846458892, + -1844212386, + -1841958164, + -1839696238, + -1837426615, + -1835149306, + -1832864320, + -1830571667, + -1828271356, + -1825963397, + -1823647799, + -1821324572, + -1818993726, + -1816655271, + -1814309216, + -1811955572, + -1809594347, + -1807225553, + -1804849198, + -1802465294, + -1800073849, + -1797674873, + -1795268378, + -1792854372, + -1790432867, + -1788003871, + -1785567396, + -1783123452, + -1780672048, + -1778213194, + -1775746903, + -1773273182, + -1770792044, + -1768303498, + -1765807555, + -1763304224, + -1760793518, + -1758275445, + -1755750017, + -1753217244, + -1750677137, + -1748129707, + -1745574963, + -1743012918, + -1740443581, + -1737866963, + -1735283075, + -1732691928, + -1730093532, + -1727487899, + -1724875040, + -1722254965, + -1719627685, + -1716993211, + -1714351555, + -1711702727, + -1709046739, + -1706383601, + -1703713325, + -1701035922, + -1698351403, + -1695659779, + -1692961062, + -1690255263, + -1687542393, + -1684822463, + -1682095486, + -1679361471, + -1676620432, + -1673872378, + -1671117323, + -1668355276, + -1665586251, + -1662810258, + -1660027308, + -1657237415, + -1654440588, + -1651636841, + -1648826185, + -1646008631, + -1643184191, + -1640352877, + -1637514702, + -1634669676, + -1631817811, + -1628959121, + -1626093616, + -1623221309, + -1620342211, + -1617456335, + -1614563692, + -1611664296, + -1608758157, + -1605845289, + -1602925703, + -1599999411, + -1597066426, + -1594126760, + -1591180426, + -1588227435, + -1585267800, + -1582301533, + -1579328647, + -1576349155, + -1573363068, + -1570370399, + -1567371161, + -1564365367, + -1561353028, + -1558334157, + -1555308768, + -1552276872, + -1549238483, + -1546193612, + -1543142274, + -1540084480, + -1537020244, + -1533949577, + -1530872494, + -1527789007, + -1524699129, + -1521602872, + -1518500250, + -1515391276, + -1512275962, + -1509154322, + -1506026369, + -1502892116, + -1499751576, + -1496604762, + -1493451687, + -1490292364, + -1487126808, + -1483955030, + -1480777044, + -1477592864, + -1474402503, + -1471205974, + -1468003290, + -1464794466, + -1461579514, + -1458358447, + -1455131280, + -1451898025, + -1448658697, + -1445413309, + -1442161874, + -1438904406, + -1435640919, + -1432371426, + -1429095941, + -1425814478, + -1422527051, + -1419233672, + -1415934356, + -1412629117, + -1409317969, + -1406000925, + -1402678000, + -1399349206, + -1396014559, + -1392674072, + -1389327759, + -1385975633, + -1382617710, + -1379254004, + -1375884527, + -1372509294, + -1369128320, + -1365741619, + -1362349204, + -1358951090, + -1355547292, + -1352137822, + -1348722696, + -1345301929, + -1341875533, + -1338443524, + -1335005916, + -1331562723, + -1328113960, + -1324659641, + -1321199781, + -1317734393, + -1314263493, + -1310787095, + -1307305214, + -1303817864, + -1300325060, + -1296826816, + -1293323147, + -1289814068, + -1286299593, + -1282779738, + -1279254516, + -1275723942, + -1272188032, + -1268646800, + -1265100260, + -1261548429, + -1257991320, + -1254428948, + -1250861329, + -1247288478, + -1243710408, + -1240127136, + -1236538675, + -1232945043, + -1229346252, + -1225742318, + -1222133257, + -1218519084, + -1214899813, + -1211275460, + -1207646039, + -1204011567, + -1200372058, + -1196727527, + -1193077991, + -1189423463, + -1185763960, + -1182099496, + -1178430087, + -1174755748, + -1171076495, + -1167392344, + -1163703308, + -1160009405, + -1156310649, + -1152607055, + -1148898640, + -1145185419, + -1141467408, + -1137744621, + -1134017074, + -1130284784, + -1126547765, + -1122806034, + -1119059606, + -1115308496, + -1111552721, + -1107792296, + -1104027237, + -1100257559, + -1096483278, + -1092704411, + -1088920972, + -1085132978, + -1081340445, + -1077543388, +}; + +/* in Q1.31, generated from sin(i * 2 * pi / FFT_SIZE_MAX) */ +const int32_t multi_twiddle_imag_32[FFT_MULTI_TWIDDLE_SIZE] = { + 0, + -4392262, + -8784505, + -13176712, + -17568864, + -21960942, + -26352928, + -30744804, + -35136551, + -39528151, + -43919586, + -48310838, + -52701887, + -57092716, + -61483306, + -65873638, + -70263695, + -74653459, + -79042909, + -83432030, + -87820801, + -92209205, + -96597223, + -100984837, + -105372028, + -109758779, + -114145071, + -118530885, + -122916203, + -127301007, + -131685278, + -136068999, + -140452151, + -144834714, + -149216672, + -153598006, + -157978697, + -162358728, + -166738079, + -171116733, + -175494670, + -179871874, + -184248325, + -188624006, + -192998897, + -197372981, + -201746240, + -206118654, + -210490206, + -214860878, + -219230650, + -223599506, + -227967426, + -232334393, + -236700388, + -241065392, + -245429388, + -249792358, + -254154282, + -258515144, + -262874923, + -267233603, + -271591166, + -275947592, + -280302863, + -284656963, + -289009871, + -293361570, + -297712042, + -302061269, + -306409232, + -310755913, + -315101295, + -319445358, + -323788084, + -328129457, + -332469456, + -336808065, + -341145265, + -345481038, + -349815365, + -354148230, + -358479612, + -362809495, + -367137861, + -371464690, + -375789965, + -380113669, + -384435782, + -388756287, + -393075166, + -397392401, + -401707973, + -406021865, + -410334058, + -414644534, + -418953276, + -423260266, + -427565485, + -431868915, + -436170538, + -440470337, + -444768294, + -449064389, + -453358607, + -457650927, + -461941333, + -466229807, + -470516330, + -474800886, + -479083454, + -483364019, + -487642562, + -491919064, + -496193509, + -500465878, + -504736154, + -509004318, + -513270353, + -517534240, + -521795963, + -526055503, + -530312842, + -534567963, + -538820847, + -543071478, + -547319836, + -551565905, + -555809667, + -560051104, + -564290197, + -568526931, + -572761285, + -576993244, + -581222789, + -585449903, + -589674567, + -593896765, + -598116479, + -602333690, + -606548381, + -610760536, + -614970135, + -619177161, + -623381598, + -627583426, + -631782630, + -635979190, + -640173090, + -644364312, + -648552838, + -652738651, + -656921734, + -661102068, + -665279637, + -669454423, + -673626408, + -677795576, + -681961908, + -686125387, + -690285996, + -694443717, + -698598533, + -702750427, + -706899381, + -711045377, + -715188400, + -719328430, + -723465451, + -727599446, + -731730397, + -735858287, + -739983099, + -744104815, + -748223418, + -752338892, + -756451218, + -760560380, + -764666360, + -768769141, + -772868706, + -776965038, + -781058120, + -785147934, + -789234464, + -793317693, + -797397602, + -801474176, + -805547397, + -809617249, + -813683713, + -817746774, + -821806413, + -825862615, + -829915362, + -833964638, + -838010424, + -842052705, + -846091463, + -850126682, + -854158345, + -858186435, + -862210934, + -866231826, + -870249095, + -874262724, + -878272695, + -882278992, + -886281598, + -890280497, + -894275671, + -898267104, + -902254780, + -906238681, + -910218791, + -914195094, + -918167572, + -922136209, + -926100989, + -930061894, + -934018909, + -937972016, + -941921200, + -945866443, + -949807730, + -953745043, + -957678367, + -961607684, + -965532978, + -969454234, + -973371434, + -977284562, + -981193602, + -985098537, + -988999351, + -992896028, + -996788551, + -1000676905, + -1004561072, + -1008441038, + -1012316784, + -1016188296, + -1020055556, + -1023918550, + -1027777260, + -1031631671, + -1035481766, + -1039327529, + -1043168945, + -1047005996, + -1050838668, + -1054666944, + -1058490808, + -1062310244, + -1066125236, + -1069935768, + -1073741824, + -1077543388, + -1081340445, + -1085132978, + -1088920972, + -1092704411, + -1096483278, + -1100257559, + -1104027237, + -1107792296, + -1111552721, + -1115308496, + -1119059606, + -1122806034, + -1126547765, + -1130284784, + -1134017074, + -1137744621, + -1141467408, + -1145185419, + -1148898640, + -1152607055, + -1156310649, + -1160009405, + -1163703308, + -1167392344, + -1171076495, + -1174755748, + -1178430087, + -1182099496, + -1185763960, + -1189423463, + -1193077991, + -1196727527, + -1200372058, + -1204011567, + -1207646039, + -1211275460, + -1214899813, + -1218519084, + -1222133257, + -1225742318, + -1229346252, + -1232945043, + -1236538675, + -1240127136, + -1243710408, + -1247288478, + -1250861329, + -1254428948, + -1257991320, + -1261548429, + -1265100260, + -1268646800, + -1272188032, + -1275723942, + -1279254516, + -1282779738, + -1286299593, + -1289814068, + -1293323147, + -1296826816, + -1300325060, + -1303817864, + -1307305214, + -1310787095, + -1314263493, + -1317734393, + -1321199781, + -1324659641, + -1328113960, + -1331562723, + -1335005916, + -1338443524, + -1341875533, + -1345301929, + -1348722696, + -1352137822, + -1355547292, + -1358951090, + -1362349204, + -1365741619, + -1369128320, + -1372509294, + -1375884527, + -1379254004, + -1382617710, + -1385975633, + -1389327759, + -1392674072, + -1396014559, + -1399349206, + -1402678000, + -1406000925, + -1409317969, + -1412629117, + -1415934356, + -1419233672, + -1422527051, + -1425814478, + -1429095941, + -1432371426, + -1435640919, + -1438904406, + -1442161874, + -1445413309, + -1448658697, + -1451898025, + -1455131280, + -1458358447, + -1461579514, + -1464794466, + -1468003290, + -1471205974, + -1474402503, + -1477592864, + -1480777044, + -1483955030, + -1487126808, + -1490292364, + -1493451687, + -1496604762, + -1499751576, + -1502892116, + -1506026369, + -1509154322, + -1512275962, + -1515391276, + -1518500250, + -1521602872, + -1524699129, + -1527789007, + -1530872494, + -1533949577, + -1537020244, + -1540084480, + -1543142274, + -1546193612, + -1549238483, + -1552276872, + -1555308768, + -1558334157, + -1561353028, + -1564365367, + -1567371161, + -1570370399, + -1573363068, + -1576349155, + -1579328647, + -1582301533, + -1585267800, + -1588227435, + -1591180426, + -1594126760, + -1597066426, + -1599999411, + -1602925703, + -1605845289, + -1608758157, + -1611664296, + -1614563692, + -1617456335, + -1620342211, + -1623221309, + -1626093616, + -1628959121, + -1631817811, + -1634669676, + -1637514702, + -1640352877, + -1643184191, + -1646008631, + -1648826185, + -1651636841, + -1654440588, + -1657237415, + -1660027308, + -1662810258, + -1665586251, + -1668355276, + -1671117323, + -1673872378, + -1676620432, + -1679361471, + -1682095486, + -1684822463, + -1687542393, + -1690255263, + -1692961062, + -1695659779, + -1698351403, + -1701035922, + -1703713325, + -1706383601, + -1709046739, + -1711702727, + -1714351555, + -1716993211, + -1719627685, + -1722254965, + -1724875040, + -1727487899, + -1730093532, + -1732691928, + -1735283075, + -1737866963, + -1740443581, + -1743012918, + -1745574963, + -1748129707, + -1750677137, + -1753217244, + -1755750017, + -1758275445, + -1760793518, + -1763304224, + -1765807555, + -1768303498, + -1770792044, + -1773273182, + -1775746903, + -1778213194, + -1780672048, + -1783123452, + -1785567396, + -1788003871, + -1790432867, + -1792854372, + -1795268378, + -1797674873, + -1800073849, + -1802465294, + -1804849198, + -1807225553, + -1809594347, + -1811955572, + -1814309216, + -1816655271, + -1818993726, + -1821324572, + -1823647799, + -1825963397, + -1828271356, + -1830571667, + -1832864320, + -1835149306, + -1837426615, + -1839696238, + -1841958164, + -1844212386, + -1846458892, + -1848697674, + -1850928722, + -1853152028, + -1855367581, + -1857575372, + -1859775393, + -1861967634, + -1864152086, + -1866328740, + -1868497586, + -1870658615, + -1872811820, + -1874957189, + -1877094716, + -1879224389, + -1881346202, + -1883460144, + -1885566207, + -1887664383, + -1889754661, + -1891837035, + -1893911494, + -1895978031, + -1898036636, + -1900087301, + -1902130017, + -1904164776, + -1906191570, + -1908210390, + -1910221227, + -1912224073, + -1914218919, + -1916205758, + -1918184581, + -1920155379, + -1922118145, + -1924072871, + -1926019547, + -1927958166, + -1929888720, + -1931811201, + -1933725600, + -1935631910, + -1937530123, + -1939420231, + -1941302225, + -1943176098, + -1945041843, + -1946899451, + -1948748914, + -1950590226, + -1952423377, + -1954248361, + -1956065170, + -1957873796, + -1959674231, + -1961466469, + -1963250501, + -1965026321, + -1966793920, + -1968553292, + -1970304428, + -1972047323, + -1973781967, + -1975508355, + -1977226479, + -1978936331, + -1980637905, + -1982331193, + -1984016189, + -1985692885, + -1987361274, + -1989021350, + -1990673105, + -1992316532, + -1993951625, + -1995578377, + -1997196780, + -1998806829, + -2000408516, + -2002001835, + -2003586779, + -2005163342, + -2006731516, + -2008291295, + -2009842674, + -2011385644, + -2012920201, + -2014446336, + -2015964045, + -2017473321, + -2018974156, + -2020466546, + -2021950484, + -2023425963, + -2024892978, + -2026351522, + -2027801589, + -2029243173, + -2030676269, + -2032100869, + -2033516969, + -2034924562, + -2036323642, + -2037714204, + -2039096241, + -2040469748, + -2041834720, + -2043191150, + -2044539032, + -2045878362, + -2047209133, + -2048531340, + -2049844978, + -2051150040, + -2052446522, + -2053734418, + -2055013723, + -2056284431, + -2057546537, + -2058800036, + -2060044922, + -2061281190, + -2062508835, + -2063727853, + -2064938237, + -2066139983, + -2067333086, + -2068517540, + -2069693342, + -2070860485, + -2072018965, + -2073168777, + -2074309917, + -2075442379, + -2076566160, + -2077681253, + -2078787655, + -2079885360, + -2080974365, + -2082054665, + -2083126254, + -2084189130, + -2085243286, + -2086288720, + -2087325426, + -2088353400, + -2089372638, + -2090383135, + -2091384888, + -2092377892, + -2093362143, + -2094337637, + -2095304370, + -2096262337, + -2097211535, + -2098151960, + -2099083608, + -2100006474, + -2100920556, + -2101825849, + -2102722350, + -2103610054, + -2104488958, + -2105359059, + -2106220352, + -2107072834, + -2107916502, + -2108751352, + -2109577380, + -2110394584, + -2111202959, + -2112002502, + -2112793210, + -2113575080, + -2114348108, + -2115112291, + -2115867626, + -2116614110, + -2117351739, + -2118080511, + -2118800422, + -2119511470, + -2120213651, + -2120906963, + -2121591402, + -2122266967, + -2122933653, + -2123591458, + -2124240380, + -2124880416, + -2125511562, + -2126133817, + -2126747178, + -2127351642, + -2127947206, + -2128533869, + -2129111628, + -2129680480, + -2130240422, + -2130791454, + -2131333572, + -2131866773, + -2132391057, + -2132906420, + -2133412861, + -2133910377, + -2134398966, + -2134878626, + -2135349356, + -2135811153, + -2136264015, + -2136707940, + -2137142927, + -2137568974, + -2137986079, + -2138394240, + -2138793455, + -2139183723, + -2139565043, + -2139937412, + -2140300829, + -2140655293, + -2141000801, + -2141337354, + -2141664948, + -2141983583, + -2142293258, + -2142593971, + -2142885721, + -2143168506, + -2143442326, + -2143707180, + -2143963065, + -2144209982, + -2144447929, + -2144676905, + -2144896910, + -2145107942, + -2145310000, + -2145503083, + -2145687192, + -2145862324, + -2146028480, + -2146185658, + -2146333858, + -2146473080, + -2146603322, + -2146724584, + -2146836866, + -2146940167, + -2147034487, + -2147119825, + -2147196181, + -2147263555, + -2147321946, + -2147371355, + -2147411780, + -2147443222, + -2147465681, + -2147479156, + -2147483647, + -2147479156, + -2147465681, + -2147443222, + -2147411780, + -2147371355, + -2147321946, + -2147263555, + -2147196181, + -2147119825, + -2147034487, + -2146940167, + -2146836866, + -2146724584, + -2146603322, + -2146473080, + -2146333858, + -2146185658, + -2146028480, + -2145862324, + -2145687192, + -2145503083, + -2145310000, + -2145107942, + -2144896910, + -2144676905, + -2144447929, + -2144209982, + -2143963065, + -2143707180, + -2143442326, + -2143168506, + -2142885721, + -2142593971, + -2142293258, + -2141983583, + -2141664948, + -2141337354, + -2141000801, + -2140655293, + -2140300829, + -2139937412, + -2139565043, + -2139183723, + -2138793455, + -2138394240, + -2137986079, + -2137568974, + -2137142927, + -2136707940, + -2136264015, + -2135811153, + -2135349356, + -2134878626, + -2134398966, + -2133910377, + -2133412861, + -2132906420, + -2132391057, + -2131866773, + -2131333572, + -2130791454, + -2130240422, + -2129680480, + -2129111628, + -2128533869, + -2127947206, + -2127351642, + -2126747178, + -2126133817, + -2125511562, + -2124880416, + -2124240380, + -2123591458, + -2122933653, + -2122266967, + -2121591402, + -2120906963, + -2120213651, + -2119511470, + -2118800422, + -2118080511, + -2117351739, + -2116614110, + -2115867626, + -2115112291, + -2114348108, + -2113575080, + -2112793210, + -2112002502, + -2111202959, + -2110394584, + -2109577380, + -2108751352, + -2107916502, + -2107072834, + -2106220352, + -2105359059, + -2104488958, + -2103610054, + -2102722350, + -2101825849, + -2100920556, + -2100006474, + -2099083608, + -2098151960, + -2097211535, + -2096262337, + -2095304370, + -2094337637, + -2093362143, + -2092377892, + -2091384888, + -2090383135, + -2089372638, + -2088353400, + -2087325426, + -2086288720, + -2085243286, + -2084189130, + -2083126254, + -2082054665, + -2080974365, + -2079885360, + -2078787655, + -2077681253, + -2076566160, + -2075442379, + -2074309917, + -2073168777, + -2072018965, + -2070860485, + -2069693342, + -2068517540, + -2067333086, + -2066139983, + -2064938237, + -2063727853, + -2062508835, + -2061281190, + -2060044922, + -2058800036, + -2057546537, + -2056284431, + -2055013723, + -2053734418, + -2052446522, + -2051150040, + -2049844978, + -2048531340, + -2047209133, + -2045878362, + -2044539032, + -2043191150, + -2041834720, + -2040469748, + -2039096241, + -2037714204, + -2036323642, + -2034924562, + -2033516969, + -2032100869, + -2030676269, + -2029243173, + -2027801589, + -2026351522, + -2024892978, + -2023425963, + -2021950484, + -2020466546, + -2018974156, + -2017473321, + -2015964045, + -2014446336, + -2012920201, + -2011385644, + -2009842674, + -2008291295, + -2006731516, + -2005163342, + -2003586779, + -2002001835, + -2000408516, + -1998806829, + -1997196780, + -1995578377, + -1993951625, + -1992316532, + -1990673105, + -1989021350, + -1987361274, + -1985692885, + -1984016189, + -1982331193, + -1980637905, + -1978936331, + -1977226479, + -1975508355, + -1973781967, + -1972047323, + -1970304428, + -1968553292, + -1966793920, + -1965026321, + -1963250501, + -1961466469, + -1959674231, + -1957873796, + -1956065170, + -1954248361, + -1952423377, + -1950590226, + -1948748914, + -1946899451, + -1945041843, + -1943176098, + -1941302225, + -1939420231, + -1937530123, + -1935631910, + -1933725600, + -1931811201, + -1929888720, + -1927958166, + -1926019547, + -1924072871, + -1922118145, + -1920155379, + -1918184581, + -1916205758, + -1914218919, + -1912224073, + -1910221227, + -1908210390, + -1906191570, + -1904164776, + -1902130017, + -1900087301, + -1898036636, + -1895978031, + -1893911494, + -1891837035, + -1889754661, + -1887664383, + -1885566207, + -1883460144, + -1881346202, + -1879224389, + -1877094716, + -1874957189, + -1872811820, + -1870658615, + -1868497586, + -1866328740, + -1864152086, + -1861967634, + -1859775393, + -1857575372, + -1855367581, + -1853152028, + -1850928722, + -1848697674, + -1846458892, + -1844212386, + -1841958164, + -1839696238, + -1837426615, + -1835149306, + -1832864320, + -1830571667, + -1828271356, + -1825963397, + -1823647799, + -1821324572, + -1818993726, + -1816655271, + -1814309216, + -1811955572, + -1809594347, + -1807225553, + -1804849198, + -1802465294, + -1800073849, + -1797674873, + -1795268378, + -1792854372, + -1790432867, + -1788003871, + -1785567396, + -1783123452, + -1780672048, + -1778213194, + -1775746903, + -1773273182, + -1770792044, + -1768303498, + -1765807555, + -1763304224, + -1760793518, + -1758275445, + -1755750017, + -1753217244, + -1750677137, + -1748129707, + -1745574963, + -1743012918, + -1740443581, + -1737866963, + -1735283075, + -1732691928, + -1730093532, + -1727487899, + -1724875040, + -1722254965, + -1719627685, + -1716993211, + -1714351555, + -1711702727, + -1709046739, + -1706383601, + -1703713325, + -1701035922, + -1698351403, + -1695659779, + -1692961062, + -1690255263, + -1687542393, + -1684822463, + -1682095486, + -1679361471, + -1676620432, + -1673872378, + -1671117323, + -1668355276, + -1665586251, + -1662810258, + -1660027308, + -1657237415, + -1654440588, + -1651636841, + -1648826185, + -1646008631, + -1643184191, + -1640352877, + -1637514702, + -1634669676, + -1631817811, + -1628959121, + -1626093616, + -1623221309, + -1620342211, + -1617456335, + -1614563692, + -1611664296, + -1608758157, + -1605845289, + -1602925703, + -1599999411, + -1597066426, + -1594126760, + -1591180426, + -1588227435, + -1585267800, + -1582301533, + -1579328647, + -1576349155, + -1573363068, + -1570370399, + -1567371161, + -1564365367, + -1561353028, + -1558334157, + -1555308768, + -1552276872, + -1549238483, + -1546193612, + -1543142274, + -1540084480, + -1537020244, + -1533949577, + -1530872494, + -1527789007, + -1524699129, + -1521602872, + -1518500250, + -1515391276, + -1512275962, + -1509154322, + -1506026369, + -1502892116, + -1499751576, + -1496604762, + -1493451687, + -1490292364, + -1487126808, + -1483955030, + -1480777044, + -1477592864, + -1474402503, + -1471205974, + -1468003290, + -1464794466, + -1461579514, + -1458358447, + -1455131280, + -1451898025, + -1448658697, + -1445413309, + -1442161874, + -1438904406, + -1435640919, + -1432371426, + -1429095941, + -1425814478, + -1422527051, + -1419233672, + -1415934356, + -1412629117, + -1409317969, + -1406000925, + -1402678000, + -1399349206, + -1396014559, + -1392674072, + -1389327759, + -1385975633, + -1382617710, + -1379254004, + -1375884527, + -1372509294, + -1369128320, + -1365741619, + -1362349204, + -1358951090, + -1355547292, + -1352137822, + -1348722696, + -1345301929, + -1341875533, + -1338443524, + -1335005916, + -1331562723, + -1328113960, + -1324659641, + -1321199781, + -1317734393, + -1314263493, + -1310787095, + -1307305214, + -1303817864, + -1300325060, + -1296826816, + -1293323147, + -1289814068, + -1286299593, + -1282779738, + -1279254516, + -1275723942, + -1272188032, + -1268646800, + -1265100260, + -1261548429, + -1257991320, + -1254428948, + -1250861329, + -1247288478, + -1243710408, + -1240127136, + -1236538675, + -1232945043, + -1229346252, + -1225742318, + -1222133257, + -1218519084, + -1214899813, + -1211275460, + -1207646039, + -1204011567, + -1200372058, + -1196727527, + -1193077991, + -1189423463, + -1185763960, + -1182099496, + -1178430087, + -1174755748, + -1171076495, + -1167392344, + -1163703308, + -1160009405, + -1156310649, + -1152607055, + -1148898640, + -1145185419, + -1141467408, + -1137744621, + -1134017074, + -1130284784, + -1126547765, + -1122806034, + -1119059606, + -1115308496, + -1111552721, + -1107792296, + -1104027237, + -1100257559, + -1096483278, + -1092704411, + -1088920972, + -1085132978, + -1081340445, + -1077543388, + -1073741824, + -1069935768, + -1066125236, + -1062310244, + -1058490808, + -1054666944, + -1050838668, + -1047005996, + -1043168945, + -1039327529, + -1035481766, + -1031631671, + -1027777260, + -1023918550, + -1020055556, + -1016188296, + -1012316784, + -1008441038, + -1004561072, + -1000676905, + -996788551, + -992896028, + -988999351, + -985098537, + -981193602, + -977284562, + -973371434, + -969454234, + -965532978, + -961607684, + -957678367, + -953745043, + -949807730, + -945866443, + -941921200, + -937972016, + -934018909, + -930061894, + -926100989, + -922136209, + -918167572, + -914195094, + -910218791, + -906238681, + -902254780, + -898267104, + -894275671, + -890280497, + -886281598, + -882278992, + -878272695, + -874262724, + -870249095, + -866231826, + -862210934, + -858186435, + -854158345, + -850126682, + -846091463, + -842052705, + -838010424, + -833964638, + -829915362, + -825862615, + -821806413, + -817746774, + -813683713, + -809617249, + -805547397, + -801474176, + -797397602, + -793317693, + -789234464, + -785147934, + -781058120, + -776965038, + -772868706, + -768769141, + -764666360, + -760560380, + -756451218, + -752338892, + -748223418, + -744104815, + -739983099, + -735858287, + -731730397, + -727599446, + -723465451, + -719328430, + -715188400, + -711045377, + -706899381, + -702750427, + -698598533, + -694443717, + -690285996, + -686125387, + -681961908, + -677795576, + -673626408, + -669454423, + -665279637, + -661102068, + -656921734, + -652738651, + -648552838, + -644364312, + -640173090, + -635979190, + -631782630, + -627583426, + -623381598, + -619177161, + -614970135, + -610760536, + -606548381, + -602333690, + -598116479, + -593896765, + -589674567, + -585449903, + -581222789, + -576993244, + -572761285, + -568526931, + -564290197, + -560051104, + -555809667, + -551565905, + -547319836, + -543071478, + -538820847, + -534567963, + -530312842, + -526055503, + -521795963, + -517534240, + -513270353, + -509004318, + -504736154, + -500465878, + -496193509, + -491919064, + -487642562, + -483364019, + -479083454, + -474800886, + -470516330, + -466229807, + -461941333, + -457650927, + -453358607, + -449064389, + -444768294, + -440470337, + -436170538, + -431868915, + -427565485, + -423260266, + -418953276, + -414644534, + -410334058, + -406021865, + -401707973, + -397392401, + -393075166, + -388756287, + -384435782, + -380113669, + -375789965, + -371464690, + -367137861, + -362809495, + -358479612, + -354148230, + -349815365, + -345481038, + -341145265, + -336808065, + -332469456, + -328129457, + -323788084, + -319445358, + -315101295, + -310755913, + -306409232, + -302061269, + -297712042, + -293361570, + -289009871, + -284656963, + -280302863, + -275947592, + -271591166, + -267233603, + -262874923, + -258515144, + -254154282, + -249792358, + -245429388, + -241065392, + -236700388, + -232334393, + -227967426, + -223599506, + -219230650, + -214860878, + -210490206, + -206118654, + -201746240, + -197372981, + -192998897, + -188624006, + -184248325, + -179871874, + -175494670, + -171116733, + -166738079, + -162358728, + -157978697, + -153598006, + -149216672, + -144834714, + -140452151, + -136068999, + -131685278, + -127301007, + -122916203, + -118530885, + -114145071, + -109758779, + -105372028, + -100984837, + -96597223, + -92209205, + -87820801, + -83432030, + -79042909, + -74653459, + -70263695, + -65873638, + -61483306, + -57092716, + -52701887, + -48310838, + -43919586, + -39528151, + -35136551, + -30744804, + -26352928, + -21960942, + -17568864, + -13176712, + -8784505, + -4392262, + 0, + 4392262, + 8784505, + 13176712, + 17568864, + 21960942, + 26352928, + 30744804, + 35136551, + 39528151, + 43919586, + 48310838, + 52701887, + 57092716, + 61483306, + 65873638, + 70263695, + 74653459, + 79042909, + 83432030, + 87820801, + 92209205, + 96597223, + 100984837, + 105372028, + 109758779, + 114145071, + 118530885, + 122916203, + 127301007, + 131685278, + 136068999, + 140452151, + 144834714, + 149216672, + 153598006, + 157978697, + 162358728, + 166738079, + 171116733, + 175494670, + 179871874, + 184248325, + 188624006, + 192998897, + 197372981, + 201746240, + 206118654, + 210490206, + 214860878, + 219230650, + 223599506, + 227967426, + 232334393, + 236700388, + 241065392, + 245429388, + 249792358, + 254154282, + 258515144, + 262874923, + 267233603, + 271591166, + 275947592, + 280302863, + 284656963, + 289009871, + 293361570, + 297712042, + 302061269, + 306409232, + 310755913, + 315101295, + 319445358, + 323788084, + 328129457, + 332469456, + 336808065, + 341145265, + 345481038, + 349815365, + 354148230, + 358479612, + 362809495, + 367137861, + 371464690, + 375789965, + 380113669, + 384435782, + 388756287, + 393075166, + 397392401, + 401707973, + 406021865, + 410334058, + 414644534, + 418953276, + 423260266, + 427565485, + 431868915, + 436170538, + 440470337, + 444768294, + 449064389, + 453358607, + 457650927, + 461941333, + 466229807, + 470516330, + 474800886, + 479083454, + 483364019, + 487642562, + 491919064, + 496193509, + 500465878, + 504736154, + 509004318, + 513270353, + 517534240, + 521795963, + 526055503, + 530312842, + 534567963, + 538820847, + 543071478, + 547319836, + 551565905, + 555809667, + 560051104, + 564290197, + 568526931, + 572761285, + 576993244, + 581222789, + 585449903, + 589674567, + 593896765, + 598116479, + 602333690, + 606548381, + 610760536, + 614970135, + 619177161, + 623381598, + 627583426, + 631782630, + 635979190, + 640173090, + 644364312, + 648552838, + 652738651, + 656921734, + 661102068, + 665279637, + 669454423, + 673626408, + 677795576, + 681961908, + 686125387, + 690285996, + 694443717, + 698598533, + 702750427, + 706899381, + 711045377, + 715188400, + 719328430, + 723465451, + 727599446, + 731730397, + 735858287, + 739983099, + 744104815, + 748223418, + 752338892, + 756451218, + 760560380, + 764666360, + 768769141, + 772868706, + 776965038, + 781058120, + 785147934, + 789234464, + 793317693, + 797397602, + 801474176, + 805547397, + 809617249, + 813683713, + 817746774, + 821806413, + 825862615, + 829915362, + 833964638, + 838010424, + 842052705, + 846091463, + 850126682, + 854158345, + 858186435, + 862210934, + 866231826, + 870249095, + 874262724, + 878272695, + 882278992, + 886281598, + 890280497, + 894275671, + 898267104, + 902254780, + 906238681, + 910218791, + 914195094, + 918167572, + 922136209, + 926100989, + 930061894, + 934018909, + 937972016, + 941921200, + 945866443, + 949807730, + 953745043, + 957678367, + 961607684, + 965532978, + 969454234, + 973371434, + 977284562, + 981193602, + 985098537, + 988999351, + 992896028, + 996788551, + 1000676905, + 1004561072, + 1008441038, + 1012316784, + 1016188296, + 1020055556, + 1023918550, + 1027777260, + 1031631671, + 1035481766, + 1039327529, + 1043168945, + 1047005996, + 1050838668, + 1054666944, + 1058490808, + 1062310244, + 1066125236, + 1069935768, + 1073741824, + 1077543388, + 1081340445, + 1085132978, + 1088920972, + 1092704411, + 1096483278, + 1100257559, + 1104027237, + 1107792296, + 1111552721, + 1115308496, + 1119059606, + 1122806034, + 1126547765, + 1130284784, + 1134017074, + 1137744621, + 1141467408, + 1145185419, + 1148898640, + 1152607055, + 1156310649, + 1160009405, + 1163703308, + 1167392344, + 1171076495, + 1174755748, + 1178430087, + 1182099496, + 1185763960, + 1189423463, + 1193077991, + 1196727527, + 1200372058, + 1204011567, + 1207646039, + 1211275460, + 1214899813, + 1218519084, + 1222133257, + 1225742318, + 1229346252, + 1232945043, + 1236538675, + 1240127136, + 1243710408, + 1247288478, + 1250861329, + 1254428948, + 1257991320, + 1261548429, + 1265100260, + 1268646800, + 1272188032, + 1275723942, + 1279254516, + 1282779738, + 1286299593, + 1289814068, + 1293323147, + 1296826816, + 1300325060, + 1303817864, + 1307305214, + 1310787095, + 1314263493, + 1317734393, + 1321199781, + 1324659641, + 1328113960, + 1331562723, + 1335005916, + 1338443524, + 1341875533, + 1345301929, + 1348722696, + 1352137822, + 1355547292, + 1358951090, + 1362349204, + 1365741619, + 1369128320, + 1372509294, + 1375884527, + 1379254004, + 1382617710, + 1385975633, + 1389327759, + 1392674072, + 1396014559, + 1399349206, + 1402678000, + 1406000925, + 1409317969, + 1412629117, + 1415934356, + 1419233672, + 1422527051, + 1425814478, + 1429095941, + 1432371426, + 1435640919, + 1438904406, + 1442161874, + 1445413309, + 1448658697, + 1451898025, + 1455131280, + 1458358447, + 1461579514, + 1464794466, + 1468003290, + 1471205974, + 1474402503, + 1477592864, + 1480777044, + 1483955030, + 1487126808, + 1490292364, + 1493451687, + 1496604762, + 1499751576, + 1502892116, + 1506026369, + 1509154322, + 1512275962, + 1515391276, + 1518500250, + 1521602872, + 1524699129, + 1527789007, + 1530872494, + 1533949577, + 1537020244, + 1540084480, + 1543142274, + 1546193612, + 1549238483, + 1552276872, + 1555308768, + 1558334157, + 1561353028, + 1564365367, + 1567371161, + 1570370399, + 1573363068, + 1576349155, + 1579328647, + 1582301533, + 1585267800, + 1588227435, + 1591180426, + 1594126760, + 1597066426, + 1599999411, + 1602925703, + 1605845289, + 1608758157, + 1611664296, + 1614563692, + 1617456335, + 1620342211, + 1623221309, + 1626093616, + 1628959121, + 1631817811, + 1634669676, + 1637514702, + 1640352877, + 1643184191, + 1646008631, + 1648826185, + 1651636841, + 1654440588, + 1657237415, + 1660027308, + 1662810258, + 1665586251, + 1668355276, + 1671117323, + 1673872378, + 1676620432, + 1679361471, + 1682095486, + 1684822463, + 1687542393, + 1690255263, + 1692961062, + 1695659779, + 1698351403, + 1701035922, + 1703713325, + 1706383601, + 1709046739, + 1711702727, + 1714351555, + 1716993211, + 1719627685, + 1722254965, + 1724875040, + 1727487899, + 1730093532, + 1732691928, + 1735283075, + 1737866963, + 1740443581, + 1743012918, + 1745574963, + 1748129707, + 1750677137, + 1753217244, + 1755750017, + 1758275445, + 1760793518, + 1763304224, + 1765807555, + 1768303498, + 1770792044, + 1773273182, + 1775746903, + 1778213194, + 1780672048, + 1783123452, + 1785567396, + 1788003871, + 1790432867, + 1792854372, + 1795268378, + 1797674873, + 1800073849, + 1802465294, + 1804849198, + 1807225553, + 1809594347, + 1811955572, + 1814309216, + 1816655271, + 1818993726, + 1821324572, + 1823647799, + 1825963397, + 1828271356, + 1830571667, + 1832864320, + 1835149306, + 1837426615, + 1839696238, + 1841958164, + 1844212386, + 1846458892, + 1848697674, + 1850928722, + 1853152028, + 1855367581, + 1857575372, +}; + +#endif diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 61486e0e2a36..b6695b9cd312 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -591,7 +591,7 @@ struct comp_driver { * Intended to replace the ops field. * Currently used by module_adapter. */ - struct sys_heap *user_heap; /**< Userspace heap */ + struct k_heap *user_heap; /**< Userspace heap */ }; /** \brief Holds constant pointer to component driver */ @@ -849,6 +849,24 @@ static inline enum sof_comp_type dev_comp_type(const struct comp_dev *dev) return dev->ipc_config.type; } +/** + * Initialize common part of a component device + * @param drv Parent component driver. + * @param dev Device. + * @param bytes Size of the component device in bytes. + */ +static inline void comp_init(const struct comp_driver *drv, + struct comp_dev *dev, size_t bytes) +{ + dev->size = bytes; + dev->drv = drv; + dev->state = COMP_STATE_INIT; + list_init(&dev->bsink_list); + list_init(&dev->bsource_list); + memcpy_s(&dev->tctx, sizeof(dev->tctx), + trace_comp_drv_get_tr_ctx(dev->drv), sizeof(struct tr_ctx)); +} + /** * Allocates memory for the component device and initializes common part. * @param drv Parent component driver. @@ -857,27 +875,36 @@ static inline enum sof_comp_type dev_comp_type(const struct comp_dev *dev) */ static inline struct comp_dev *comp_alloc(const struct comp_driver *drv, size_t bytes) { - struct comp_dev *dev = NULL; - /* * Use uncached address everywhere to access components to rule out * multi-core failures. TODO: verify if cached alias may be used in some cases */ - dev = module_driver_heap_rzalloc(drv->user_heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, - bytes); + struct comp_dev *dev = sof_heap_alloc(drv->user_heap, + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + bytes, 0); + if (!dev) return NULL; - dev->size = bytes; - dev->drv = drv; - dev->state = COMP_STATE_INIT; - list_init(&dev->bsink_list); - list_init(&dev->bsource_list); - memcpy_s(&dev->tctx, sizeof(struct tr_ctx), - trace_comp_drv_get_tr_ctx(dev->drv), sizeof(struct tr_ctx)); + + memset(dev, 0, sizeof(*dev)); + comp_init(drv, dev, bytes); return dev; } +/** + * Frees memory allocated for component device. + * + * This is a counterpart to comp_alloc() and not to be confused with + * comp_free(). + * + * @param dev Pointer to the component device. + */ +static inline void comp_free_device(struct comp_dev *dev) +{ + sof_heap_free(dev->drv->user_heap, dev); +} + /** * \brief Module adapter associated with a component * @param dev Component device @@ -919,6 +946,7 @@ void sys_comp_module_copier_interface_init(void); void sys_comp_module_crossover_interface_init(void); void sys_comp_module_dcblock_interface_init(void); void sys_comp_module_demux_interface_init(void); +void sys_comp_module_dolby_dax_audio_processing_interface_init(void); void sys_comp_module_drc_interface_init(void); void sys_comp_module_dts_interface_init(void); void sys_comp_module_eq_fir_interface_init(void); @@ -940,7 +968,9 @@ void sys_comp_module_selector_interface_init(void); void sys_comp_module_sound_dose_interface_init(void); void sys_comp_module_src_interface_init(void); void sys_comp_module_src_lite_interface_init(void); +void sys_comp_module_stft_process_interface_init(void); void sys_comp_module_tdfb_interface_init(void); +void sys_comp_module_tone_interface_init(void); void sys_comp_module_template_interface_init(void); void sys_comp_module_tester_interface_init(void); void sys_comp_module_volume_interface_init(void); @@ -1200,7 +1230,7 @@ bool comp_update_performance_data(struct comp_dev *dev, uint32_t cycles_used); static inline int user_get_buffer_memory_region(const struct comp_driver *drv) { -#if CONFIG_USERSPACE +#if CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP return drv->user_heap ? SOF_MEM_FLAG_USER_SHARED_BUFFER : SOF_MEM_FLAG_USER; #else return SOF_MEM_FLAG_USER; diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 3762fcde7791..d2bbf87a7764 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -44,17 +44,15 @@ struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init); /** See comp_ops::free */ static inline void comp_free(struct comp_dev *dev) { - assert(dev->drv->ops.free); - - /* free task if shared component or DP task*/ - if ((dev->is_shared || dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) && - dev->task) { - schedule_task_free(dev->task); - module_driver_heap_free(dev->drv->user_heap, dev->task); - dev->task = NULL; - } + const struct comp_driver *drv = dev->drv; + + assert(drv->ops.free); - dev->drv->ops.free(dev); + /* + * In DP case this will run in DP thread context, so the task can only + * be freed after this. + */ + drv->ops.free(dev); } /** @@ -152,19 +150,20 @@ static inline int comp_trigger_local(struct comp_dev *dev, int cmd) int ret; ret = dev->drv->ops.trigger(dev, cmd); + if (ret) + return ret; /* start a thread in case of shared component or DP scheduling */ if (dev->task) { /* schedule or cancel task */ switch (cmd) { case COMP_TRIGGER_START: - case COMP_TRIGGER_RELEASE: - schedule_task(dev->task, 0, dev->period); + ret = schedule_task(dev->task, 0, dev->period); break; + case COMP_TRIGGER_RELEASE: case COMP_TRIGGER_XRUN: case COMP_TRIGGER_PAUSE: case COMP_TRIGGER_STOP: - schedule_task_cancel(dev->task); break; } } diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index fce40f1638a1..14c7b33a38e9 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -42,7 +42,7 @@ struct comp_buffer; #define KPB_MAX_BUFFER_SIZE(sw, channels_number) ((KPB_SAMPLNG_FREQUENCY / 1000) * \ (KPB_SAMPLE_CONTAINER_SIZE(sw) / 8) * KPB_MAX_BUFF_TIME * \ (channels_number)) -#define KPB_MAX_NO_OF_CLIENTS 2 +#define KPB_MAX_NO_OF_CLIENTS 4 #define KPB_MAX_SINK_CNT (1 + KPB_MAX_NO_OF_CLIENTS) #define KPB_NO_OF_HISTORY_BUFFERS 2 /**< no of internal buffers */ #define KPB_ALLOCATION_STEP 0x100 diff --git a/src/include/sof/audio/mfcc/mfcc_comp.h b/src/include/sof/audio/mfcc/mfcc_comp.h index bbc01030e157..ec5cc90eb40c 100644 --- a/src/include/sof/audio/mfcc/mfcc_comp.h +++ b/src/include/sof/audio/mfcc/mfcc_comp.h @@ -154,7 +154,7 @@ static inline int16_t *mfcc_buffer_wrap(struct mfcc_buffer *buffer, int16_t *ptr int mfcc_setup(struct processing_module *mod, int max_frames, int rate, int channels); -void mfcc_free_buffers(struct mfcc_comp_data *cd); +void mfcc_free_buffers(struct processing_module *mod); void mfcc_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames); diff --git a/src/include/sof/audio/module_adapter/iadk/system_agent.h b/src/include/sof/audio/module_adapter/iadk/system_agent.h index a0470167c796..e7aab98c748c 100644 --- a/src/include/sof/audio/module_adapter/iadk/system_agent.h +++ b/src/include/sof/audio/module_adapter/iadk/system_agent.h @@ -107,8 +107,9 @@ extern "C" { * method (the variant with 7 parameters) via a parameter that initially contained the address to * the agent system. The system_agent_start function returns it in the variable adapter. */ -int system_agent_start(uintptr_t entry_point, uint32_t module_id, uint32_t instance_id, - uint32_t core_id, uint32_t log_handle, void *mod_cfg, const void **adapter); +struct system_agent_params; + +int system_agent_start(const struct system_agent_params *params, const void **adapter); #ifdef __cplusplus } #endif diff --git a/src/include/sof/audio/module_adapter/library/native_system_agent.h b/src/include/sof/audio/module_adapter/library/native_system_agent.h index 657bc6ac643d..70c0f6b1aad1 100644 --- a/src/include/sof/audio/module_adapter/library/native_system_agent.h +++ b/src/include/sof/audio/module_adapter/library/native_system_agent.h @@ -11,9 +11,17 @@ #include #include -typedef int (*system_agent_start_fn)(uintptr_t entry_point, uint32_t module_id, - uint32_t instance_id, uint32_t core_id, uint32_t log_handle, - void *mod_cfg, const void **adapter); +struct system_agent_params { + uintptr_t entry_point; /* The module entry point function address. */ + uint32_t module_id; /* The identifier for the module. */ + uint32_t instance_id; /* The instance identifier of the module. */ + uint32_t core_id; /* Core on which the module will run. */ + uint32_t log_handle; /* The handle for logging purposes. */ + void *mod_cfg; /* Pointer to the module configuration data. */ +}; + +typedef int (*system_agent_start_fn)(const struct system_agent_params *params, + const void **adapter); struct native_system_agent { struct system_service system_service; @@ -29,18 +37,12 @@ struct native_system_agent { * * This function initializes and starts the native system agent with the provided parameters. * - * @param[in] entry_point - The module entry point function address. - * @param[in] module_id - The identifier for the module. - * @param[in] instance_id - The instance identifier of the module. - * @param[in] core_id - Core on which the module will run. - * @param[in] log_handle - The handle for logging purposes. - * @param[in] mod_cfg - Pointer to the module configuration data. + * @param[in] params - Pointer to the system agent parameter structure * @param[out] iface - Pointer to the module interface. * * @return Returns 0 on success or an error code on failure. */ -int native_system_agent_start(uintptr_t entry_point, uint32_t module_id, uint32_t instance_id, - uint32_t core_id, uint32_t log_handle, void *mod_cfg, +int native_system_agent_start(const struct system_agent_params *params, const void **iface); #endif /* __NATIVE_SYSTEM_AGENT_H__ */ diff --git a/src/include/sof/audio/module_adapter/library/userspace_proxy.h b/src/include/sof/audio/module_adapter/library/userspace_proxy.h index 52381ac7c175..872646d1eec9 100644 --- a/src/include/sof/audio/module_adapter/library/userspace_proxy.h +++ b/src/include/sof/audio/module_adapter/library/userspace_proxy.h @@ -14,12 +14,55 @@ #include #include +#include +#include + +#include +#include +#include + +struct module_interface; +struct comp_driver; +struct sof_man_module; +struct system_agent_params; /* Processing module structure fields needed for user mode */ struct userspace_context { struct k_mem_domain *comp_dom; /* Module specific memory domain */ + const struct module_interface *interface; /* Userspace module interface */ + struct user_work_item *work_item; /* work item for user worker thread */ }; - #endif /* CONFIG_USERSPACE */ +#if CONFIG_SOF_USERSPACE_PROXY +/** + * Creates userspace module proxy + * + * @param user_ctx - pointer to pointer of userspace module context + * @param drv - pointer to component driver + * @param manifest - pointer to module manifest + * @param start_fn - pointer to system agent start function + * @param agent_params - pointer to system_agent_params + * @param agent_interface - pointer to variable to store module interface created by agent + * @param ops - Pointer to a variable that will hold the address of the module interface + * structure. The function stores a pointer to its own userspace proxy + * interface structure in this variable. + * + * @return 0 for success, error otherwise. + */ +int userspace_proxy_create(struct userspace_context **user_ctx, const struct comp_driver *drv, + const struct sof_man_module *manifest, system_agent_start_fn start_fn, + const struct system_agent_params *agent_params, + const void **agent_interface, const struct module_interface **ops); + +/** + * Destroy userspace module proxy + * + * @param drv - pointer to component driver + * @param user_ctx - pointer to userspace module context + */ +void userspace_proxy_destroy(const struct comp_driver *drv, struct userspace_context *user_ctx); + +#endif /* CONFIG_SOF_USERSPACE_PROXY */ + #endif /* __SOF_AUDIO_USERSPACE_PROXY_H__ */ diff --git a/src/include/sof/audio/module_adapter/library/userspace_proxy_user.h b/src/include/sof/audio/module_adapter/library/userspace_proxy_user.h new file mode 100644 index 000000000000..e571705cec17 --- /dev/null +++ b/src/include/sof/audio/module_adapter/library/userspace_proxy_user.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki + */ + +#ifndef __SOF_AUDIO_USERSPACE_PROXY_USER_H__ +#define __SOF_AUDIO_USERSPACE_PROXY_USER_H__ + +#if CONFIG_SOF_USERSPACE_PROXY +struct module_agent_params { + system_agent_start_fn start_fn; + struct system_agent_params params; + byte_array_t mod_cfg; + const void *out_interface; +}; + +struct module_large_cfg_set_params { + uint32_t config_id; + enum module_cfg_fragment_position pos; + uint32_t data_off_size; + const uint8_t *fragment; + size_t fragment_size; + uint8_t *response; + size_t response_size; +}; + +struct module_large_cfg_get_params { + uint32_t config_id; + uint32_t *data_off_size; + uint8_t *fragment; + size_t fragment_size; +}; + +struct module_processing_mode_params { + enum module_processing_mode mode; +}; + +struct module_process_params { + struct sof_source **sources; + int num_of_sources; + struct sof_sink **sinks; + int num_of_sinks; +}; + +enum userspace_proxy_cmd { + USER_PROXY_MOD_CMD_AGENT_START, + USER_PROXY_MOD_CMD_INIT, + USER_PROXY_MOD_CMD_PREPARE, + USER_PROXY_MOD_CMD_PROC_READY, + USER_PROXY_MOD_CMD_SET_PROCMOD, + USER_PROXY_MOD_CMD_GET_PROCMOD, + USER_PROXY_MOD_CMD_SET_CONF, + USER_PROXY_MOD_CMD_GET_CONF, + USER_PROXY_MOD_CMD_BIND, + USER_PROXY_MOD_CMD_UNBIND, + USER_PROXY_MOD_CMD_RESET, + USER_PROXY_MOD_CMD_FREE, + USER_PROXY_MOD_CMD_TRIGGER +}; + +struct module_params { + enum userspace_proxy_cmd cmd; + int status; + struct processing_module *mod; + struct userspace_context *context; + /* The field used in the union depends on the value of cmd */ + union { + struct module_agent_params agent; + struct module_large_cfg_set_params set_conf; + struct module_large_cfg_get_params get_conf; + struct module_processing_mode_params proc_mode; + struct module_process_params proc; + struct bind_info *bind_data; + int trigger_data; + } ext; +}; + +struct user_work_item { + struct k_work_user work_item; /* ipc worker workitem */ + struct k_event *event; /* ipc worker done event */ + struct module_params params; +}; + +void userspace_proxy_handle_request(struct processing_module *mod, struct module_params *params); + +void userspace_proxy_worker_handler(struct k_work_user *work_item); + +#endif /* CONFIG_SOF_USERSPACE_PROXY */ + +#endif /* __SOF_AUDIO_USERSPACE_PROXY_USER_H__ */ diff --git a/src/include/sof/audio/module_adapter/module/cadence.h b/src/include/sof/audio/module_adapter/module/cadence.h index a4ad3d9482f8..baefbaeea08f 100644 --- a/src/include/sof/audio/module_adapter/module/cadence.h +++ b/src/include/sof/audio/module_adapter/module/cadence.h @@ -17,6 +17,7 @@ #define LIB_NO_ERROR XA_NO_ERROR #define LIB_IS_FATAL_ERROR(e) ((e) & XA_FATAL_ERROR) #define CODEC_GET_API_ID(id) ((id) & 0xFF) +#define CADENCE_MP3_ENCODER_DEFAULT_BITRATE 320 /*****************************************************************************/ /* Cadence API functions */ @@ -32,6 +33,8 @@ extern xa_codec_func_t xa_sbc_dec; extern xa_codec_func_t xa_vorbis_dec; extern xa_codec_func_t xa_src_pp; +#define DEFAULT_CODEC_ID CADENCE_CODEC_WRAPPER_ID + #define API_CALL(cd, cmd, sub_cmd, value, ret) \ do { \ ret = (cd)->api((cd)->self, \ @@ -49,14 +52,33 @@ struct cadence_api { }; struct cadence_codec_data { +#if CONFIG_IPC_MAJOR_4 + struct ipc4_base_module_cfg base_cfg; + uint32_t direction; +#endif char name[LIB_NAME_MAX_LEN]; void *self; xa_codec_func_t *api; void *mem_tabs; + size_t mem_to_be_freed_len; + void **mem_to_be_freed; uint32_t api_id; struct module_config setup_cfg; }; +enum cadence_api_id { + CADENCE_CODEC_WRAPPER_ID = 0x01, + CADENCE_CODEC_AAC_DEC_ID = 0x02, + CADENCE_CODEC_BSAC_DEC_ID = 0x03, + CADENCE_CODEC_DAB_DEC_ID = 0x04, + CADENCE_CODEC_DRM_DEC_ID = 0x05, + CADENCE_CODEC_MP3_DEC_ID = 0x06, + CADENCE_CODEC_SBC_DEC_ID = 0x07, + CADENCE_CODEC_VORBIS_DEC_ID = 0x08, + CADENCE_CODEC_SRC_PP_ID = 0x09, + CADENCE_CODEC_MP3_ENC_ID = 0x0A, +}; + #if CONFIG_IPC_MAJOR_4 struct ipc4_cadence_module_cfg { struct ipc4_base_module_cfg base_cfg; @@ -65,4 +87,24 @@ struct ipc4_cadence_module_cfg { } __packed __aligned(4); #endif +extern struct cadence_api cadence_api_table[]; + +int cadence_codec_set_configuration(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, const uint8_t *fragment, + size_t fragment_size, uint8_t *response, size_t response_size); +int cadence_codec_resolve_api_with_id(struct processing_module *mod, uint32_t codec_id, + uint32_t direction); +int cadence_codec_apply_params(struct processing_module *mod, int size, void *data); +int cadence_codec_process_data(struct processing_module *mod); +int cadence_codec_apply_config(struct processing_module *mod); +void cadence_codec_free_memory_tables(struct processing_module *mod); +int cadence_codec_init_memory_tables(struct processing_module *mod); +int cadence_codec_get_samples(struct processing_module *mod); +int cadence_codec_init_process(struct processing_module *mod); +int cadence_init_codec_object(struct processing_module *mod); +int cadence_codec_resolve_api(struct processing_module *mod); +int cadence_codec_free(struct processing_module *mod); +size_t cadence_api_table_size(void); + #endif /* __SOF_AUDIO_CADENCE_CODEC__ */ diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 97e5d9b35520..59f5f398bad5 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -13,8 +13,9 @@ #ifndef __SOF_AUDIO_MODULE_GENERIC__ #define __SOF_AUDIO_MODULE_GENERIC__ -#include +#include #include +#include #include #include #include "module_interface.h" @@ -23,6 +24,7 @@ #if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__) #include #endif +#include /* * helpers to determine processing type @@ -127,11 +129,10 @@ struct module_param { * when the module unloads. */ struct module_resources { - struct list_item res_list; /**< Allocad resource containers */ - struct list_item free_cont_list; /**< Unused memory containers */ - struct list_item cont_chunk_list; /**< Memory container chunks */ + struct objpool_head objpool; size_t heap_usage; size_t heap_high_water_mark; + struct k_heap *heap; #if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__) k_tid_t rsrc_mngr; #endif @@ -170,6 +171,8 @@ struct module_processing_data { uint32_t produced; /**< Specifies how much data the module produced in its last task.*/ uint32_t consumed; /**< Specified how much data the module consumed in its last task */ uint32_t init_done; /**< Specifies if the module initialization is finished */ + bool eos_reached; /**< End of stream processing is reached */ + bool eos_notification_sent; /**< EOS notification is sent to host */ void *in_buff; /**< A pointer to module input buffer. */ void *out_buff; /**< A pointer to module output buffer. */ }; @@ -188,16 +191,68 @@ struct module_processing_data { /*****************************************************************************/ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); int module_init(struct processing_module *mod); -void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment); -void *mod_alloc(struct processing_module *mod, uint32_t size); -void *mod_zalloc(struct processing_module *mod, uint32_t size); -int mod_free(struct processing_module *mod, const void *ptr); +void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment); +void mod_resource_init(struct processing_module *mod); +void mod_heap_info(struct processing_module *mod, size_t *size, uintptr_t *start); +#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION) +__syscall void *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, + size_t alignment); +__syscall int mod_free(struct processing_module *mod, const void *ptr); +#else +void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, + size_t alignment); +int z_impl_mod_free(struct processing_module *mod, const void *ptr); +#define mod_alloc_ext z_impl_mod_alloc_ext +#define mod_free z_impl_mod_free +#endif + +/** + * Allocates aligned memory block for module. + * @param mod Pointer to the module this memory block is allocated for. + * @param size Size in bytes. + * @param alignment Alignment in bytes. + * @return Pointer to the allocated memory or NULL if failed. + * + * The allocated memory is automatically freed when the module is unloaded. + */ +static inline void *mod_alloc_align(struct processing_module *mod, size_t size, size_t alignment) +{ + return mod_alloc_ext(mod, SOF_MEM_FLAG_USER, size, alignment); +} + +static inline void *mod_balloc(struct processing_module *mod, size_t size) +{ + return mod_balloc_align(mod, size, 0); +} + +static inline void *mod_alloc(struct processing_module *mod, size_t size) +{ + return mod_alloc_align(mod, size, 0); +} + +static inline void *mod_zalloc(struct processing_module *mod, size_t size) +{ + void *ret = mod_alloc(mod, size); + + if (ret) + memset(ret, 0, size); + + return ret; +} + #if CONFIG_COMP_BLOB struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_module *mod); void mod_data_blob_handler_free(struct processing_module *mod, struct comp_data_blob_handler *dbh); #endif #if CONFIG_FAST_GET -const void *mod_fast_get(struct processing_module *mod, const void * const dram_ptr, size_t size); +#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION) +__syscall const void *mod_fast_get(struct processing_module *mod, const void * const dram_ptr, + size_t size); +#else +const void *z_impl_mod_fast_get(struct processing_module *mod, const void * const dram_ptr, + size_t size); +#define mod_fast_get z_impl_mod_fast_get +#endif void mod_fast_put(struct processing_module *mod, const void *sram_ptr); #endif void mod_free_all(struct processing_module *mod); @@ -266,9 +321,10 @@ int module_unbind(struct processing_module *mod, struct bind_info *unbind_data); struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec); +struct userspace_context; struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec, - void *mod_priv); + void *mod_priv, struct userspace_context *user_ctx); int module_adapter_prepare(struct comp_dev *dev); int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *params); int module_adapter_copy(struct comp_dev *dev); @@ -376,7 +432,18 @@ int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd); void module_update_buffer_position(struct input_stream_buffer *input_buffers, struct output_stream_buffer *output_buffers, uint32_t frames); - +struct module_ext_init_data; +#if CONFIG_IPC_MAJOR_4 +int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init_data *ext_data, + struct ipc_config_process *spec); +#else +static inline +int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init_data *ext_data, + struct ipc_config_process *spec) +{ + return 0; +} +#endif int module_adapter_init_data(struct comp_dev *dev, struct module_config *dst, const struct comp_ipc_config *config, @@ -388,4 +455,33 @@ void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_str int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, int cmd); int module_adapter_sink_src_prepare(struct comp_dev *dev); + +/** + * Get a deadline based on current LFT reported by all sinks + * it returns a value >= UINT32_MAX / 2 in case the deadline cannot be calculated: + * - if a module is in a dealayed start + * - if there's no sink - i.e. DP module is a pure data consumer (like key phrare detector) + * + * @return a deadline the module must finish processing since NOW [in us] + */ +uint32_t module_get_deadline(struct processing_module *mod); + +/** + * Get a Longest Processing Time estimation for the module, in us + * It is either + * - a value taken from the manifest or estimated from module period (TODO) + * - or a value taken from IPC call (TODO) + * - a worst case - module period + * note that module period may be calculated reasonably late, i.e. in prepare() method + */ +static inline uint32_t module_get_lpt(struct processing_module *mod) +{ + /* return worst case of LPT - a module period. See zephyr_dp_schedule.c for description */ + return mod->dev->period; +} + +#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION) +#include +#endif + #endif /* __SOF_AUDIO_MODULE_GENERIC__ */ diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index 5221d330e0f1..913a569c208c 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -25,6 +25,7 @@ struct comp_buffer; struct comp_dev; struct ipc; struct ipc_msg; +struct k_heap; /* * Pipeline status to stop execution of current path, but to keep the @@ -52,6 +53,7 @@ struct ipc_msg; * Audio pipeline. */ struct pipeline { + struct k_heap *heap; /**< heap used for allocating this pipeline */ uint32_t comp_id; /**< component id for pipeline */ uint32_t pipeline_id; /**< pipeline id */ uint32_t sched_id; /**< Scheduling component id */ @@ -134,6 +136,13 @@ struct pipeline_task { struct comp_dev *sched_comp; /**< pipeline scheduling component */ }; +struct ipc4_pipeline_ext_obj_mem_data; + +/** \brief For storing IPC payload data. */ +struct create_pipeline_params { + const struct ipc4_pipeline_ext_obj_mem_data *mem_data; +}; + #define pipeline_task_get(t) container_of(t, struct pipeline_task, task) /* @@ -145,12 +154,15 @@ struct pipeline_task { /** * \brief Creates a new pipeline. + * \param[in] heap Heap to allocate the pipeline on, or NULL for default. * \param[in] pipeline_id Pipeline ID number. * \param[in] priority Pipeline scheduling priority. * \param[in] comp_id Pipeline component ID number. + * \param[in] pparams Pipeline parameters from IPC payload, maybe NULL. * \return New pipeline pointer or NULL. */ -struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t comp_id); +struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority, + uint32_t comp_id, struct create_pipeline_params *pparams); /** * \brief Free's a pipeline. @@ -257,7 +269,7 @@ int pipeline_params(struct pipeline *p, struct comp_dev *cd, struct sof_ipc_pcm_params *params); /** - * \brief Creates a new pipeline. + * \brief Prepares pipeline for processing. * \param[in] p pipeline. * \param[in,out] cd Pipeline component device. * \return 0 on success. @@ -357,9 +369,9 @@ int pipeline_comp_ll_task_init(struct pipeline *p); int pipeline_comp_dp_task_init(struct comp_dev *comp); /** - * \brief Free's a pipeline. + * \brief Schedule a pipeline copy to run after a delay * \param[in] p pipeline. - * \param[in] start Pipelien start time in microseconds. + * \param[in] start Pipeline start time in microseconds. */ void pipeline_schedule_copy(struct pipeline *p, uint64_t start); diff --git a/src/include/sof/boot_test.h b/src/include/sof/boot_test.h index 965eec06a6a9..1af6e7f2d8e0 100644 --- a/src/include/sof/boot_test.h +++ b/src/include/sof/boot_test.h @@ -6,8 +6,14 @@ #ifndef __SOF_BOOT_TEST_H__ #define __SOF_BOOT_TEST_H__ +#if !CONFIG_LIBRARY +#include +#else +#define LOG_ERR(...) do {} while (0) +#endif #include +#if CONFIG_SOF_BOOT_TEST #define TEST_RUN_ONCE(fn, ...) do { \ static bool once; \ if (!once) { \ @@ -15,6 +21,9 @@ fn(__VA_ARGS__); \ } \ } while (0) +#else +#define TEST_RUN_ONCE(fn, ...) do {} while (0) +#endif #define TEST_CHECK_RET(ret, testname) do { \ if ((ret) < 0) { \ @@ -25,4 +34,6 @@ } \ } while (0) +void sof_run_boot_tests(void); + #endif diff --git a/src/include/sof/debug/telemetry/telemetry.h b/src/include/sof/debug/telemetry/telemetry.h index 4f8a869a9dd6..6c2d5fdf8cb7 100644 --- a/src/include/sof/debug/telemetry/telemetry.h +++ b/src/include/sof/debug/telemetry/telemetry.h @@ -11,8 +11,11 @@ #include #endif +#ifndef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER /* Slot in memory window 2 (Debug Window) to be used as telemetry slot */ #define SOF_DW_TELEMETRY_SLOT 1 +#endif + /* Memory of average algorithm of performance queue */ #define SOF_AVG_PERF_MEAS_DEPTH 64 /* Number of runs taken to calculate average (algorithm resolution) */ @@ -87,6 +90,9 @@ struct telemetry_perf_queue { }; void telemetry_update(uint32_t begin_ccount, uint32_t current_ccount); +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +struct system_tick_info *telemetry_get_systick_info_ptr(void); +#endif #ifdef CONFIG_TIMING_FUNCTIONS #define telemetry_timestamp timing_counter_get diff --git a/src/include/sof/lib/dai-legacy.h b/src/include/sof/lib/dai-legacy.h index 44142412334b..c1b7c0a28653 100644 --- a/src/include/sof/lib/dai-legacy.h +++ b/src/include/sof/lib/dai-legacy.h @@ -419,7 +419,7 @@ void dai_put(struct dai *dai); * \brief Digital Audio interface formatting */ static inline int dai_set_config(struct dai *dai, struct ipc_config_dai *config, - const void *spec_config) + const void *spec_config, size_t size) { return dai->drv->ops.set_config(dai, config, spec_config); } diff --git a/src/include/sof/lib/dai-zephyr.h b/src/include/sof/lib/dai-zephyr.h index cff5fffb4228..8ff739fa42d5 100644 --- a/src/include/sof/lib/dai-zephyr.h +++ b/src/include/sof/lib/dai-zephyr.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -237,7 +238,8 @@ void dai_put(struct dai *dai); /** * \brief Digital Audio interface formatting */ -int dai_set_config(struct dai *dai, struct ipc_config_dai *config, const void *spec_config); +int dai_set_config(struct dai *dai, struct ipc_config_dai *config, + const void *spec_config, size_t size); /** * \brief Get Digital Audio interface DMA Handshake @@ -304,7 +306,14 @@ void dai_release_llp_slot(struct dai_data *dd); /** * \brief Retrieve a pointer to the Zephyr device structure for a DAI of a given type and index. */ -const struct device *dai_get_device(uint32_t type, uint32_t index); +const struct device *dai_get_device(enum sof_ipc_dai_type type, uint32_t index); + +/** + * \brief Retrieve the list of all DAI devices. + * \param count Pointer to store the number of devices in the list. + * \return Pointer to the array of device pointers. + */ +const struct device **dai_get_device_list(size_t *count); /** @}*/ #endif /* __SOF_LIB_DAI_ZEPHYR_H__ */ diff --git a/src/include/sof/lib/fast-get.h b/src/include/sof/lib/fast-get.h index ffbac19cf1b8..fa34ecea128d 100644 --- a/src/include/sof/lib/fast-get.h +++ b/src/include/sof/lib/fast-get.h @@ -10,7 +10,9 @@ #include -const void *fast_get(const void * const dram_ptr, size_t size); -void fast_put(const void *sram_ptr); +struct k_heap; + +const void *fast_get(struct k_heap *heap, const void * const dram_ptr, size_t size); +void fast_put(struct k_heap *heap, const void *sram_ptr); #endif /* __SOF_LIB_FAST_GET_H__ */ diff --git a/src/include/sof/lib/mailbox.h b/src/include/sof/lib/mailbox.h index 06e2659a5847..ae667f0d0c4c 100644 --- a/src/include/sof/lib/mailbox.h +++ b/src/include/sof/lib/mailbox.h @@ -100,6 +100,14 @@ void mailbox_hostbox_read(void *dest, size_t dest_size, assert(!host_read_err); } +#if CONFIG_IPC_MAJOR_4 +static inline +void mailbox_stream_write(size_t offset, const void *src, size_t bytes) +{ + /* in IPC4, the stream mailbox must not be used */ + assert(false); +} +#else static inline void mailbox_stream_write(size_t offset, const void *src, size_t bytes) { @@ -110,5 +118,6 @@ void mailbox_stream_write(size_t offset, const void *src, size_t bytes) dcache_writeback_region((__sparse_force void __sparse_cache *)(MAILBOX_STREAM_BASE + offset), bytes); } +#endif #endif /* __SOF_LIB_MAILBOX_H__ */ diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index ef32b5d75e87..f1ead3028984 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -91,6 +91,8 @@ enum { LIB_MANAGER_DATA, LIB_MANAGER_RODATA, LIB_MANAGER_BSS, + LIB_MANAGER_COLD, + LIB_MANAGER_COLDRODATA, LIB_MANAGER_N_SEGMENTS, }; @@ -198,15 +200,6 @@ void lib_manager_get_instance_bss_address(uint32_t instance_id, const struct sof_man_module *mod, void __sparse_cache **va_addr, size_t *size); -/* - * \brief Free module - * - * param[in] component_id - component id coming from ipc config. This function reguires valid - * lib_id and module_id fields of component id. - * - * Function is responsible to free module resources in HP memory. - */ -int lib_manager_free_module(const uint32_t component_id); /* * \brief Load library * diff --git a/src/include/sof/llext_manager.h b/src/include/sof/llext_manager.h index 44928c5a124f..525fa50b1506 100644 --- a/src/include/sof/llext_manager.h +++ b/src/include/sof/llext_manager.h @@ -15,6 +15,7 @@ struct comp_dev; struct comp_driver; struct comp_ipc_config; +struct k_mem_domain; static inline bool module_is_llext(const struct sof_man_module *mod) { @@ -29,12 +30,16 @@ int llext_manager_free_module(const uint32_t component_id); int llext_manager_add_library(uint32_t module_id); +int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *domain); +int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *domain); + bool comp_is_llext(struct comp_dev *comp); #else #define module_is_llext(mod) false #define llext_manager_allocate_module(ipc_config, ipc_specific_config) 0 #define llext_manager_free_module(component_id) 0 #define llext_manager_add_library(module_id) 0 +#define llext_manager_add_domain(component_id, domain) 0 #define comp_is_llext(comp) false #endif diff --git a/src/include/sof/math/auditory.h b/src/include/sof/math/auditory.h index eef073092e22..b09017786e36 100644 --- a/src/include/sof/math/auditory.h +++ b/src/include/sof/math/auditory.h @@ -76,7 +76,9 @@ int16_t psy_mel_to_hz(int16_t mel); * filter coefficients. * \return Zero when success, otherwise error code. */ -int psy_get_mel_filterbank(struct psy_mel_filterbank *mel_fb); +struct processing_module; +int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); +int mod_psy_free_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); /** * \brief Convert linear complex spectra from FFT into Mel band energies in desired diff --git a/src/include/sof/math/dct.h b/src/include/sof/math/dct.h index bb3aca81b202..7c754f448c21 100644 --- a/src/include/sof/math/dct.h +++ b/src/include/sof/math/dct.h @@ -29,6 +29,8 @@ struct dct_plan_16 { bool ortho; }; -int dct_initialize_16(struct dct_plan_16 *dct); +int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct); + +int mod_dct_free_16(struct processing_module *mod, struct dct_plan_16 *dct); #endif /* __SOF_MATH_DCT_H__ */ diff --git a/src/include/sof/math/fft.h b/src/include/sof/math/fft.h index 504465401cad..033ea4527eb3 100644 --- a/src/include/sof/math/fft.h +++ b/src/include/sof/math/fft.h @@ -9,6 +9,7 @@ #ifndef __SOF_FFT_H__ #define __SOF_FFT_H__ +#include #include #include #include @@ -25,7 +26,9 @@ #endif -#define FFT_SIZE_MAX 1024 +#define FFT_SIZE_MIN 1 +#define FFT_SIZE_MAX 1024 +#define FFT_MULTI_COUNT_MAX 3 struct icomplex32 { int32_t real; @@ -51,10 +54,69 @@ struct fft_plan { struct icomplex16 *outb16; /* pointer to output integer complex buffer */ }; +struct fft_multi_plan { + struct fft_plan *fft_plan[FFT_MULTI_COUNT_MAX]; + struct icomplex32 *tmp_i32[FFT_MULTI_COUNT_MAX]; /* pointer to input buffer */ + struct icomplex32 *tmp_o32[FFT_MULTI_COUNT_MAX]; /* pointer to output buffer */ + struct icomplex32 *inb32; /* pointer to input integer complex buffer */ + struct icomplex32 *outb32; /* pointer to output integer complex buffer */ + uint16_t *bit_reverse_idx; + uint32_t total_size; + uint32_t fft_size; + int num_ffts; +}; + /* interfaces of the library */ -struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits); +struct fft_plan *mod_fft_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits); void fft_execute_16(struct fft_plan *plan, bool ifft); void fft_execute_32(struct fft_plan *plan, bool ifft); -void fft_plan_free(struct fft_plan *plan16); +void mod_fft_plan_free(struct processing_module *mod, struct fft_plan *plan); + +/** + * mod_fft_multi_plan_new() - Prepare FFT for 2^N size and some other FFT sizes + * @param mod: Pointer to module + * @param inb: Buffer to use for complex input data + * @param outb: Buffer to use for complex output data + * @param size: Size of FFT as number of bins + * @param bits: World length of FFT. Currently only 32 is supported. + * @return Pointer to allocated FFT plan + * + * This function does the preparations to calculate FFT. If the size is power of two + * the operation is similar to mod_fft_plan_new(). Some other FFT sizes like 1536 is + * supported by allocated multiple FFT plans and by wrapping all needed for similar + * usage as power of two size FFT. + */ + +struct fft_multi_plan *mod_fft_multi_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits); +/** + * fft_multi_execute_32() - Calculate Fast Fourier Transform (FFT) for 2^size and other + * @param plan: Pointer to FFT plan created with mod_fft_multi_plan_new() + * @param ifft: Value 0 calculates FFT, value 1 calculates IFFT + * + * This function calculates the FFT with the buffers defined with mod_fft_multi_plan_new(). + */ +void fft_multi_execute_32(struct fft_multi_plan *plan, bool ifft); + +/** + * mod_fft_multi_plan_free() - Free the FFT plan + * @param mod: Pointer to module + * @param plan: Pointe to FFT plan + * + * This function frees the allocations done internally by the function mod_fft_multi_plan_new(). + * The input and output buffers need to be freed separately. + */ +void mod_fft_multi_plan_free(struct processing_module *mod, struct fft_multi_plan *plan); + +/** + * dft3_32() - Discrete Fourier Transform (DFT) for size 3. + * @param input: Pointer to complex values input array, Q1.31 + * @param output: Pointer to complex values output array, Q3.29 + * + * This function is useful for calculating some non power of two FFTs. E.g. the + * FFT for size 1536 is done with three 512 size FFTs and one 3 size DFT. + */ +void dft3_32(struct icomplex32 *input, struct icomplex32 *output); #endif /* __SOF_FFT_H__ */ diff --git a/src/include/sof/math/matrix.h b/src/include/sof/math/matrix.h index 74899371038a..f48f1ca4960d 100644 --- a/src/include/sof/math/matrix.h +++ b/src/include/sof/math/matrix.h @@ -10,6 +10,7 @@ #ifndef __SOF_MATH_MATRIX_H__ #define __SOF_MATH_MATRIX_H__ +#include #include #include #include @@ -44,6 +45,20 @@ static inline struct mat_matrix_16b *mat_matrix_alloc_16b(int16_t rows, int16_t return mat; } +static inline struct mat_matrix_16b *mod_mat_matrix_alloc_16b(struct processing_module *mod, + int16_t rows, int16_t columns, + int16_t fractions) +{ + struct mat_matrix_16b *mat; + const int mat_size = sizeof(int16_t) * rows * columns + sizeof(struct mat_matrix_16b); + + mat = mod_zalloc(mod, mat_size); + if (mat) + mat_init_16b(mat, rows, columns, fractions); + + return mat; +} + static inline void mat_copy_from_linear_16b(struct mat_matrix_16b *mat, const int16_t *lin_data) { size_t bytes = sizeof(int16_t) * mat->rows * mat->columns; diff --git a/src/include/sof/math/numbers.h b/src/include/sof/math/numbers.h index 0cd9314f4859..80d4eba1a639 100644 --- a/src/include/sof/math/numbers.h +++ b/src/include/sof/math/numbers.h @@ -36,7 +36,11 @@ __a > 0 ? 1 : 0; \ }) +/* Zephyr added gcd() in 2025/Nov to sys/util.h */ +#ifndef gcd +#define USE_SOF_GCD 1 int gcd(int a, int b); /* Calculate greatest common divisor for a and b */ +#endif /* This is a divide function that returns ceil of the quotient. * E.g. ceil_divide(9, 3) returns 3, ceil_divide(10, 3) returns 4. diff --git a/src/include/sof/math/trig.h b/src/include/sof/math/trig.h index 0c0b2d23a388..9f04c137a265 100644 --- a/src/include/sof/math/trig.h +++ b/src/include/sof/math/trig.h @@ -13,14 +13,17 @@ #include -#define PI_DIV2_Q4_28 421657428 -#define PI_DIV2_Q3_29 843314856 -#define PI_Q4_28 843314857 -#define PI_MUL2_Q4_28 1686629713 -#define CORDIC_31B_TABLE_SIZE 31 -#define CORDIC_15B_TABLE_SIZE 15 -#define CORDIC_30B_ITABLE_SIZE 30 -#define CORDIC_16B_ITABLE_SIZE 16 +#define PI_Q4_28 843314857 /* int32(pi * 2^28) */ +#define PI_MUL2_Q4_28 1686629713 /* int32(2 * pi * 2^28) */ +#define PI_DIV2_Q3_29 843314857 /* int32(pi / 2 * 2^29) */ +#define PI_Q3_29 1686629713 /* int32(pi * 2^29) */ + +#define CORDIC_31B_TABLE_SIZE 31 +#define CORDIC_15B_TABLE_SIZE 15 +#define CORDIC_30B_ITABLE_SIZE 30 +#define CORDIC_16B_ITABLE_SIZE 16 +#define CORDIC_31B_ITERATIONS (CORDIC_31B_TABLE_SIZE - 1) +#define CORDIC_16B_ITERATIONS (CORDIC_16B_ITABLE_SIZE - 1) typedef enum { EN_32B_CORDIC_SINE, @@ -36,13 +39,49 @@ struct cordic_cmpx { int32_t im; }; +/** + * cordic_approx() - CORDIC-based approximation of sine and cosine + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @param a_idx Used LUT size. + * @param sign Output pointer to sine/cosine sign. + * @param b_yn Output pointer to sine value in Q2.30 format. + * @param xn Output pointer to cosine value in Q2.30 format. + * @param th_cdc_fxp Output pointer to the residual angle in Q2.30 format. + */ void cordic_approx(int32_t th_rad_fxp, int32_t a_idx, int32_t *sign, int32_t *b_yn, int32_t *xn, int32_t *th_cdc_fxp); -int32_t is_scalar_cordic_acos(int32_t realvalue, int16_t numiters); -int32_t is_scalar_cordic_asin(int32_t realvalue, int16_t numiters); + +/** + * is_scalar_cordic_acos() - CORDIC-based approximation for inverse cosine + * @param realvalue Input cosine value in Q2.30 format. + * @param numiters_minus_one Number of iterations minus one. + * @return Inverse cosine angle in Q3.29 format. + */ +int32_t is_scalar_cordic_acos(int32_t realvalue, int numiters_minus_one); + +/** + * is_scalar_cordic_asin() - CORDIC-based approximation for inverse sine + * @param realvalue Input sine value in Q2.30 format. + * @param numiters_minus_one Number of iterations minus one. + * @return Inverse sine angle in Q2.30 format. + */ +int32_t is_scalar_cordic_asin(int32_t realvalue, int numiters_minus_one); + +/** + * cmpx_cexp() - CORDIC-based approximation of complex exponential e^(j*THETA) + * @param sign Sine sign + * @param b_yn Sine value in Q2.30 format + * @param xn Cosine value in Q2.30 format + * @param type CORDIC type + * @param cexp Output pointer to complex result in struct cordic_cmpx + */ void cmpx_cexp(int32_t sign, int32_t b_yn, int32_t xn, cordic_cfg type, struct cordic_cmpx *cexp); -/* Input is Q4.28, output is Q1.31 */ + /** + * sin_fixed_32b() - Sine function using CORDIC algorithm + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @return Sine value in Q1.31 format. + * * Compute fixed point cordicsine with table lookup and interpolation * The cordic sine algorithm converges, when the angle is in the range * [-pi/2, pi/2).If an angle is outside of this range, then a multiple of @@ -71,6 +110,10 @@ static inline int32_t sin_fixed_32b(int32_t th_rad_fxp) } /** + * cos_fixed_32b() - Cosine function using CORDIC algorithm + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @return Cosine value in Q1.31 format. + * * Compute fixed point cordicsine with table lookup and interpolation * The cordic cosine algorithm converges, when the angle is in the range * [-pi/2, pi/2).If an angle is outside of this range, then a multiple of @@ -98,8 +141,11 @@ static inline int32_t cos_fixed_32b(int32_t th_rad_fxp) return sat_int32(Q_SHIFT_LEFT((int64_t)th_cdc_fxp, 30, 31)); } -/* Input is Q4.28, output is Q1.15 */ /** + * sin_fixed_16b() - Sine function using CORDIC algorithm + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @return Sine value in Q1.15 format + * * Compute fixed point cordic sine with table lookup and interpolation * The cordic sine algorithm converges, when the angle is in the range * [-pi/2, pi/2).If an angle is outside of this range, then a multiple of @@ -129,6 +175,10 @@ static inline int16_t sin_fixed_16b(int32_t th_rad_fxp) } /** + * cos_fixed_16b() - Cosine function using CORDIC algorithm + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @return Cosine value in Q1.15 format. + * * Compute fixed point cordic cosine with table lookup and interpolation * The cordic cos algorithm converges, when the angle is in the range * [-pi/2, pi/2).If an angle is outside of this range, then a multiple of @@ -158,7 +208,10 @@ static inline int16_t cos_fixed_16b(int32_t th_rad_fxp) } /** - * CORDIC-based approximation of complex exponential e^(j*THETA). + * cmpx_exp_32b() - CORDIC-based approximation of complex exponential e^(j*THETA). + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @param cexp Output pointer to complex result in struct cordic_cmpx in Q2.30 format. + * * computes COS(THETA) + j*SIN(THETA) using CORDIC algorithm * approximation and returns the complex result. * THETA values must be in the range [-2*pi, 2*pi). The cordic @@ -190,7 +243,10 @@ static inline void cmpx_exp_32b(int32_t th_rad_fxp, struct cordic_cmpx *cexp) } /** - * CORDIC-based approximation of complex exponential e^(j*THETA). + * cmpx_exp_16b() - CORDIC-based approximation of complex exponential e^(j*THETA). + * @param th_rad_fxp Input angle in radian Q4.28 format. + * @param cexp Output pointer to complex result in struct cordic_cmpx in Q1.15 format. + * * computes COS(THETA) + j*SIN(THETA) using CORDIC algorithm * approximation and returns the complex result. * THETA values must be in the range [-2*pi, 2*pi). The cordic @@ -223,7 +279,10 @@ static inline void cmpx_exp_16b(int32_t th_rad_fxp, struct cordic_cmpx *cexp) } /** - * CORDIC-based approximation of inverse sine + * asin_fixed_32b() - CORDIC-based approximation of inverse sine + * @param cdc_asin_th Input value in Q2.30 format. + * @return Inverse sine angle in Q2.30 format. + * * inverse sine of cdc_asin_theta based on a CORDIC approximation. * asin(cdc_asin_th) inverse sine angle values in radian produces using the DCORDIC * (Double CORDIC) algorithm. @@ -238,17 +297,18 @@ static inline int32_t asin_fixed_32b(int32_t cdc_asin_th) int32_t th_asin_fxp; if (cdc_asin_th >= 0) - th_asin_fxp = is_scalar_cordic_asin(cdc_asin_th, - CORDIC_31B_TABLE_SIZE); + th_asin_fxp = is_scalar_cordic_asin(cdc_asin_th, CORDIC_31B_ITERATIONS); else - th_asin_fxp = -is_scalar_cordic_asin(-cdc_asin_th, - CORDIC_31B_TABLE_SIZE); + th_asin_fxp = -is_scalar_cordic_asin(-cdc_asin_th, CORDIC_31B_ITERATIONS); return th_asin_fxp; /* Q2.30 */ } /** - * CORDIC-based approximation of inverse cosine + * acos_fixed_32b() - CORDIC-based approximation of inverse cosine + * @param cdc_acos_th Input value in Q2.30 format. + * @return Inverse cosine angle in Q3.29 format. + * * inverse cosine of cdc_acos_theta based on a CORDIC approximation * acos(cdc_acos_th) inverse cosine angle values in radian produces using the DCORDIC * (Double CORDIC) algorithm. @@ -262,18 +322,18 @@ static inline int32_t acos_fixed_32b(int32_t cdc_acos_th) int32_t th_acos_fxp; if (cdc_acos_th >= 0) - th_acos_fxp = is_scalar_cordic_acos(cdc_acos_th, - CORDIC_31B_TABLE_SIZE); + th_acos_fxp = is_scalar_cordic_acos(cdc_acos_th, CORDIC_31B_ITERATIONS); else - th_acos_fxp = - PI_MUL2_Q4_28 - is_scalar_cordic_acos(-cdc_acos_th, - CORDIC_31B_TABLE_SIZE); + th_acos_fxp = PI_Q3_29 - is_scalar_cordic_acos(-cdc_acos_th, CORDIC_31B_ITERATIONS); return th_acos_fxp; /* Q3.29 */ } /** - * CORDIC-based approximation of inverse sine + * asin_fixed_16b() - CORDIC-based approximation of inverse sine + * @param cdc_asin_th Input value in Q2.30 format. + * @return Inverse sine angle in Q2.14 format. + * * inverse sine of cdc_asin_theta based on a CORDIC approximation. * asin(cdc_asin_th) inverse sine angle values in radian produces using the DCORDIC * (Double CORDIC) algorithm. @@ -289,17 +349,18 @@ static inline int16_t asin_fixed_16b(int32_t cdc_asin_th) int32_t th_asin_fxp; if (cdc_asin_th >= 0) - th_asin_fxp = is_scalar_cordic_asin(cdc_asin_th, - CORDIC_16B_ITABLE_SIZE); + th_asin_fxp = is_scalar_cordic_asin(cdc_asin_th, CORDIC_16B_ITERATIONS); else - th_asin_fxp = -is_scalar_cordic_asin(-cdc_asin_th, - CORDIC_16B_ITABLE_SIZE); + th_asin_fxp = -is_scalar_cordic_asin(-cdc_asin_th, CORDIC_16B_ITERATIONS); /*convert Q2.30 to Q2.14 format*/ return sat_int16(Q_SHIFT_RND(th_asin_fxp, 30, 14)); } /** - * CORDIC-based approximation of inverse cosine + * acos_fixed_16b() - CORDIC-based approximation of inverse cosine + * @param cdc_acos_th Input value in Q2.30 format. + * @return Inverse cosine angle in Q3.13 format. + * * inverse cosine of cdc_acos_theta based on a CORDIC approximation * acos(cdc_acos_th) inverse cosine angle values in radian produces using the DCORDIC * (Double CORDIC) algorithm. @@ -314,12 +375,9 @@ static inline int16_t acos_fixed_16b(int32_t cdc_acos_th) int32_t th_acos_fxp; if (cdc_acos_th >= 0) - th_acos_fxp = is_scalar_cordic_acos(cdc_acos_th, - CORDIC_16B_ITABLE_SIZE); + th_acos_fxp = is_scalar_cordic_acos(cdc_acos_th, CORDIC_16B_ITERATIONS); else - th_acos_fxp = - PI_MUL2_Q4_28 - is_scalar_cordic_acos(-cdc_acos_th, - CORDIC_16B_ITABLE_SIZE); + th_acos_fxp = PI_Q3_29 - is_scalar_cordic_acos(-cdc_acos_th, CORDIC_16B_ITERATIONS); /*convert Q3.29 to Q3.13 format*/ return sat_int16(Q_SHIFT_RND(th_acos_fxp, 29, 13)); diff --git a/src/include/sof/math/window.h b/src/include/sof/math/window.h index bd04317b96ee..d72d00b3bd87 100644 --- a/src/include/sof/math/window.h +++ b/src/include/sof/math/window.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 Intel Corporation. All rights reserved. + * Copyright(c) 2022-2025 Intel Corporation. * * Author: Seppo Ingalsuo */ @@ -13,40 +13,85 @@ #include #include -#define WIN_BLACKMAN_A0 Q_CONVERT_FLOAT(7938.0 / 18608.0, 15) /* For "exact" blackman */ +#define WIN_BLACKMAN_A0_Q15 Q_CONVERT_FLOAT(7938.0 / 18608.0, 15) /* For "exact" blackman 16bit */ +#define WIN_BLACKMAN_A0_Q31 Q_CONVERT_FLOAT(7938.0 / 18608.0, 31) /* For "exact" blackman 32bit */ /** - * \brief Return rectangular window, simply values of one - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector + * Returns a rectangular window with 16 bits, simply a values of ones vector + * @param win Pointer to output vector with Q1.15 coefficients + * @param length Length of coefficients vector */ void win_rectangular_16b(int16_t win[], int length); /** - * \brief Calculate Blackman window function, reference + * Returns a rectangular window with 32 bits, simply a values of ones vector + * @param win Pointer to output vector with Q1.31 coefficients + * @param length Length of coefficients vector + */ +void win_rectangular_32b(int32_t win[], int length); + +/** + * Calculates a Blackman window function with 16 bits, reference * https://en.wikipedia.org/wiki/Window_function#Blackman_window * - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector - * \param[in] a0 Parameter for window shape, use e.g. 0.42 as Q1.15 + * @param win Pointer to output vector with Q1.15 coefficients + * @param length Length of coefficients vector + * @param a0 Parameter for window shape, use e.g. 0.42 as Q1.15 */ void win_blackman_16b(int16_t win[], int length, int16_t a0); /** - * \brief Calculate Hamming window function, reference + * Calculates a Blackman window function with 32 bits, reference + * https://en.wikipedia.org/wiki/Window_function#Blackman_window + * + * @param win Pointer to output vector with Q1.31 coefficients + * @param length Length of coefficients vector + * @param a0 Parameter for window shape, use e.g. 0.42 as Q1.31 + */ +void win_blackman_32b(int32_t win[], int length, int32_t a0); + +/** + * Calculates a Hann window function with 16 bits, reference * https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows * - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector + * @param win Pointer to output vector with Q1.15 coefficients + * @param length Length of coefficients vector + */ +void win_hann_16b(int16_t win[], int length); + +/** + * Calculates a Hann window function with 32 bits, reference + * https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows + * + * @param win Pointer to output vector with Q1.31 coefficients + * @param length Length of coefficients vector + */ +void win_hann_32b(int32_t win[], int length); + +/** + * Calculates a Hamming window function with 16 bits, reference + * https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows + * + * @param win Pointer to output vector with Q1.15 coefficients + * @param length Length of coefficients vector */ void win_hamming_16b(int16_t win[], int length); /** - * \brief Calculate Povey window function. It's a window function - * from Pytorch. + * Calculates a Hamming window function with 32 bits, reference + * https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows + * + * @param win Pointer to output vector with Q1.31 coefficients + * @param length Length of coefficients vector + */ +void win_hamming_32b(int32_t win[], int length); + +/** + * Calculates a Povey window function with 16 bits. It's a window function + * used in Pytorch and Kaldi. * - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector + * @param win Output vector with coefficients + * @param length Length of coefficients vector */ void win_povey_16b(int16_t win[], int length); diff --git a/src/include/sof/objpool.h b/src/include/sof/objpool.h new file mode 100644 index 000000000000..697a19cd2336 --- /dev/null +++ b/src/include/sof/objpool.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +#ifndef __ZEPHYR_OBJPOOL_H__ +#define __ZEPHYR_OBJPOOL_H__ + +#include + +#include +#include +#include + +struct k_heap; +struct objpool_head { + struct list_item list; + struct k_heap *heap; + uint32_t flags; +}; + +/** + * Allocate memory tracked as part of an object pool. + * + * @param head Pointer to the object pool head. + * @param size Size in bytes of memory blocks to allocate. + * @param flags Memory allocation flags. + * + * @return a pointer to the allocated memory on success, NULL on failure. + * + * Allocate a memory block of @a size bytes. @a size is used upon the first + * invocation to allocate memory on the heap, all consequent allocations with + * the same @a head must use the same @a size value. First allocation with an + * empty @a head allocates 2 blocks. After both blocks are taken and a third one + * is requested, the next call allocates 4 blocks, then 8, 16 and 32. After that + * 32 blocks are allocated every time. Note, that by design allocated blocks are + * never freed. See more below. + * TODO: @a flags are currently only used when allocating new object sets. + * Should add a check that they're consistent with already allocated objects. + */ +void *objpool_alloc(struct objpool_head *head, size_t size, uint32_t flags); + +/** + * Return a block to the object pool + * + * @param head Pointer to the object pool head. + * @param data Pointer to the object to return (can be NULL) + * + * @return 0 on success or a negative error code. + * + * Return a block to the object pool. Memory is never freed by design, unused + * blocks are kept in the object pool for future re-use. + */ +int objpool_free(struct objpool_head *head, void *data); + +/** + * Free all of the object pool memory + * + * @param head Pointer to the object pool head. + */ +void objpool_prune(struct objpool_head *head); + +/* returns true to stop */ +typedef bool (*objpool_iterate_cb)(void *data, void *arg); + +/** + * Iterate over object pool entries until stopped + * + * @param head Pointer to the object pool head. + * @param cb Callback function + * @param arg Callback function argument + * + * @return 0 on success or a negative error code. + * + * Call the callback function for each entry in the pool, until it returns true. + * If the callback never returns true, return an error. + */ +int objpool_iterate(struct objpool_head *head, objpool_iterate_cb cb, void *arg); + +#endif diff --git a/src/include/sof/schedule/dp_schedule.h b/src/include/sof/schedule/dp_schedule.h index 360d7f47c1de..37b8f1fc3f2c 100644 --- a/src/include/sof/schedule/dp_schedule.h +++ b/src/include/sof/schedule/dp_schedule.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include struct processing_module; @@ -86,4 +88,53 @@ int scheduler_dp_task_init(struct task **task, void scheduler_get_task_info_dp(struct scheduler_props *scheduler_props, uint32_t *data_off_size); +enum { + DP_TASK_EVENT_PROCESS = BIT(0), /* Need to process data */ + DP_TASK_EVENT_CANCEL = BIT(1), /* Thread cancellation */ + DP_TASK_EVENT_IPC = BIT(2), /* IPC message */ + DP_TASK_EVENT_IPC_DONE = BIT(3), /* IPC processing has completed. */ +}; + +struct bind_info; +struct sof_source; +struct sof_sink; +/* + * Keeps the scheduler_dp_thread_ipc() flow simple - just one call that does all + * the IPC-message specific parameter packing internally. This is slightly + * suboptimal because IPC parameters first have to be collected in this + * structure and then packed in DP-accessible memory inside + * scheduler_dp_thread_ipc(). This could be split into two levels, by adding + * IPC-specific functions like ipc_flatten_pipeline_state() and similar, but + * that would add multiple functions to the API. + */ +union scheduler_dp_thread_ipc_param { + struct bind_info *bind_data; + struct { + unsigned int trigger_cmd; + enum ipc4_pipeline_state state; + int n_sources; + struct sof_source **sources; + int n_sinks; + struct sof_sink **sinks; + } pipeline_state; +}; + +struct dp_heap_user { + struct k_heap heap; + /* So far relying on linear processing of serialized IPCs, but might need protection */ + unsigned int client_count; /* devices and buffers */ +}; + +#if CONFIG_ZEPHYR_DP_SCHEDULER +int scheduler_dp_thread_ipc(struct processing_module *pmod, unsigned int cmd, + const union scheduler_dp_thread_ipc_param *param); +#else +static inline int scheduler_dp_thread_ipc(struct processing_module *pmod, + unsigned int cmd, + const union scheduler_dp_thread_ipc_param *param) +{ + return 0; +} +#endif + #endif /* __SOF_SCHEDULE_DP_SCHEDULE_H__ */ diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index 5fc7691e3b13..dc28e43c7461 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -66,7 +66,11 @@ struct ll_schedule_domain_ops { struct ll_schedule_domain { uint64_t next_tick; /**< ticks just set for next run */ uint64_t new_target_tick; /**< for the next set, used during the reschedule stage */ - struct k_spinlock lock; /**< standard lock */ +#ifdef CONFIG_SOF_USERSPACE_LL + struct k_mutex *lock; /**< standard lock */ +#else + struct k_spinlock lock; /**< standard lock */ +#endif atomic_t total_num_tasks; /**< total number of registered tasks */ atomic_t enabled_cores; /**< number of enabled cores */ uint32_t ticks_per_ms; /**< number of clock ticks per ms */ @@ -93,13 +97,26 @@ static inline struct ll_schedule_domain *dma_domain_get(void) return sof_get()->platform_dma_domain; } +#ifdef CONFIG_SOF_USERSPACE_LL +struct task *zephyr_ll_task_alloc(void); +struct k_heap *zephyr_ll_user_heap(void); +void zephyr_ll_user_resources_init(void); +#endif /* CONFIG_SOF_USERSPACE_LL */ + static inline struct ll_schedule_domain *domain_init (int type, int clk, bool synchronous, const struct ll_schedule_domain_ops *ops) { struct ll_schedule_domain *domain; +#ifdef CONFIG_SOF_USERSPACE_LL + domain = sof_heap_alloc(zephyr_ll_user_heap(), SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*domain), sizeof(void *)); + if (domain) + memset(domain, 0, sizeof(*domain)); +#else domain = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, sizeof(*domain)); +#endif if (!domain) return NULL; domain->type = type; @@ -116,7 +133,17 @@ static inline struct ll_schedule_domain *domain_init domain->next_tick = UINT64_MAX; domain->new_target_tick = UINT64_MAX; +#ifdef CONFIG_SOF_USERSPACE_LL + /* Allocate mutex dynamically for userspace access */ + domain->lock = k_object_alloc(K_OBJ_MUTEX); + if (!domain->lock) { + sof_heap_free(zephyr_ll_user_heap(), domain); + return NULL; + } + k_mutex_init(domain->lock); +#else k_spinlock_init(&domain->lock); +#endif atomic_init(&domain->total_num_tasks, 0); atomic_init(&domain->enabled_cores, 0); @@ -246,7 +273,11 @@ struct ll_schedule_domain *zephyr_dma_domain_init(struct dma *dma_array, struct ll_schedule_domain *zephyr_ll_domain(void); struct ll_schedule_domain *zephyr_domain_init(int clk); #define timer_domain_init(timer, clk) zephyr_domain_init(clk) -#endif +#ifdef CONFIG_SOF_USERSPACE_LL +struct k_thread *zephyr_domain_thread_tid(struct ll_schedule_domain *domain); +struct k_mem_domain *zephyr_ll_mem_domain(void); +#endif /* CONFIG_SOF_USERSPACE_LL */ +#endif /* __ZEPHYR__ */ struct ll_schedule_domain *dma_multi_chan_domain_init(struct dma *dma_array, uint32_t num_dma, int clk, diff --git a/src/include/user/debug_stream.h b/src/include/user/debug_stream.h index 60f731622478..b6d8c08cf43a 100644 --- a/src/include/user/debug_stream.h +++ b/src/include/user/debug_stream.h @@ -48,5 +48,6 @@ struct debug_stream_record { /* Debug Stream record identifiers */ #define DEBUG_STREAM_RECORD_ID_UNINITIALIZED 0 /* invalid record marker */ #define DEBUG_STREAM_RECORD_ID_THREAD_INFO 1 /* Thread info record */ +#define DEBUG_STREAM_RECORD_ID_TEXT_MSG 2 /* Text message */ #endif /* __SOC_DEBUG_STREAM_H__ */ diff --git a/src/include/user/debug_stream_text_msg.h b/src/include/user/debug_stream_text_msg.h new file mode 100644 index 000000000000..3d246e305fc3 --- /dev/null +++ b/src/include/user/debug_stream_text_msg.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2024 Intel Corporation. + */ + +#ifndef __SOC_DEBUG_STREAM_TEXT_MSG_H__ +#define __SOC_DEBUG_STREAM_TEXT_MSG_H__ + +#include + +/* + * Debug Stream text message. + */ +struct debug_stream_text_msg { + struct debug_stream_record hdr; + char msg[]; +} __packed; + +/* + * To send debug messages over debug stream. Enable + * CONFIG_SOF_DEBUG_STREAM_TEXT_MSG to enable this function. + */ +void ds_msg(const char *format, ...); + +#endif /* __SOC_DEBUG_STREAM_TEXT_MSG_H__ */ diff --git a/src/init/init.c b/src/init/init.c index ddb4c604b4a6..48d7c520faa5 100644 --- a/src/init/init.c +++ b/src/init/init.c @@ -218,6 +218,10 @@ __cold static int primary_core_init(int argc, char *argv[], struct sof *sof) io_perf_monitor_init(); #endif +#if CONFIG_SOF_USERSPACE_LL + zephyr_ll_user_resources_init(); +#endif + /* init the platform */ if (platform_init(sof) < 0) sof_panic(SOF_IPC_PANIC_PLATFORM); diff --git a/src/ipc/ipc-common.c b/src/ipc/ipc-common.c index 2368ea9163fd..10f241784625 100644 --- a/src/ipc/ipc-common.c +++ b/src/ipc/ipc-common.c @@ -55,9 +55,11 @@ int ipc_process_on_core(uint32_t core, bool blocking) return -EACCES; } +#if CONFIG_IPC_MAJOR_3 /* The other core will write there its response */ dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, ((struct sof_ipc_cmd_hdr *)ipc->comp_data)->size); +#endif /* * If the primary core is waiting for secondary cores to complete, it @@ -292,6 +294,11 @@ __cold int ipc_init(struct sof *sof) tr_dbg(&ipc_tr, "entry"); +#if CONFIG_SOF_BOOT_TEST_STANDALONE + LOG_INF("SOF_BOOT_TEST_STANDALONE, disabling IPC."); + return 0; +#endif + /* init ipc data */ sof->ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc)); if (!sof->ipc) { diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index 0b34915ea26f..2f685b551747 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -50,7 +50,8 @@ __cold static bool valid_ipc_buffer_desc(const struct sof_ipc_buffer *desc) } /* create a new component in the pipeline */ -__cold struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared) +__cold struct comp_buffer *buffer_new(struct k_heap *heap, const struct sof_ipc_buffer *desc, + bool is_shared) { struct comp_buffer *buffer; uint32_t flags = desc->flags; @@ -78,7 +79,7 @@ __cold struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is desc->caps, flags); /* allocate buffer */ - buffer = buffer_alloc(desc->size, flags, PLATFORM_DCACHE_ALIGN, + buffer = buffer_alloc(heap, desc->size, flags, PLATFORM_DCACHE_ALIGN, is_shared); if (buffer) { buffer->stream.runtime_stream_params.id = desc->comp.id; @@ -234,7 +235,7 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) /* check whether pipeline exists */ ipc_pipe = ipc_get_pipeline_by_id(ipc, comp_id); if (!ipc_pipe) { - tr_err(&ipc_tr, "ipc: ipc_pipeline_complete looking for pipe component id 0x%x failed", + tr_err(&ipc_tr, "ipc: looking for pipe component id 0x%x failed", comp_id); return -EINVAL; } @@ -248,14 +249,14 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) /* get pipeline source component */ ipc_ppl_source = ipc_get_ppl_src_comp(ipc, p->pipeline_id); if (!ipc_ppl_source) { - tr_err(&ipc_tr, "ipc: ipc_pipeline_complete looking for pipeline source failed"); + tr_err(&ipc_tr, "ipc: looking for pipeline source failed"); return -EINVAL; } /* get pipeline sink component */ ipc_ppl_sink = ipc_get_ppl_sink_comp(ipc, p->pipeline_id); if (!ipc_ppl_sink) { - tr_err(&ipc_tr, "ipc: ipc_pipeline_complete looking for pipeline sink failed"); + tr_err(&ipc_tr, "ipc: looking for pipeline sink failed"); return -EINVAL; } diff --git a/src/ipc/ipc-zephyr.c b/src/ipc/ipc-zephyr.c index 460089414cf7..66ada4ddaa05 100644 --- a/src/ipc/ipc-zephyr.c +++ b/src/ipc/ipc-zephyr.c @@ -12,8 +12,12 @@ #include #include - +#include +#ifdef CONFIG_INTEL_ADSP_IPC +#include #include +#endif + #include #include @@ -58,25 +62,32 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); * When IPC message is read fills ipc_cmd_hdr. */ static uint32_t g_last_data, g_last_ext_data; +static struct ipc_ept sof_ipc_ept; +static struct ipc_ept_cfg sof_ipc_ept_cfg; + +BUILD_ASSERT(sizeof(struct ipc_cmd_hdr) == sizeof(uint32_t) * 2, + "ipc_cmd_hdr must be exactly two 32-bit words"); /** - * @brief cAVS IPC Message Handler Callback function. + * @brief SOF IPC receive callback for Zephyr IPC service. * - * See @ref (*intel_adsp_ipc_handler_t) for function signature description. - * @return false so BUSY on the other side will not be cleared immediately but - * will remain set until message would have been processed by scheduled task, i.e. - * until ipc_platform_complete_cmd() call. + * This callback is invoked by the Zephyr IPC service backend when a compact 2-word IPC message + * arrives from the host. It stores the raw header words in g_last_data/g_last_ext_data and + * schedules the SOF IPC task to process the command via ipc_platform_do_cmd(). */ -static bool message_handler(const struct device *dev, void *arg, uint32_t data, uint32_t ext_data) +static void sof_ipc_receive_cb(const void *data, size_t len, void *priv) { - struct ipc *ipc = (struct ipc *)arg; - + struct ipc *ipc = (struct ipc *)priv; + const uint32_t *msg = data; k_spinlock_key_t key; + __ASSERT(len == sizeof(uint32_t) * 2, "Unexpected IPC message length: %zu", len); + __ASSERT(data, "IPC data pointer is NULL"); + key = k_spin_lock(&ipc->lock); - g_last_data = data; - g_last_ext_data = ext_data; + g_last_data = msg[0]; + g_last_ext_data = msg[1]; #if CONFIG_DEBUG_IPC_COUNTERS increment_ipc_received_counter(); @@ -84,8 +95,6 @@ static bool message_handler(const struct device *dev, void *arg, uint32_t data, ipc_schedule_process(ipc); k_spin_unlock(&ipc->lock, key); - - return false; } #ifdef CONFIG_PM_DEVICE @@ -159,9 +168,6 @@ static int ipc_device_resume_handler(const struct device *dev, void *arg) ipc->task_mask = 0; ipc->pm_prepare_D3 = false; - /* attach handlers */ - intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc); - /* schedule task */ #if CONFIG_TWB_IPC_TASK scheduler_twb_task_init(&ipc->ipc_task, SOF_UUID(zipc_task_uuid), @@ -254,7 +260,10 @@ enum task_state ipc_platform_do_cmd(struct ipc *ipc) void ipc_platform_complete_cmd(struct ipc *ipc) { ARG_UNUSED(ipc); - intel_adsp_ipc_complete(INTEL_ADSP_IPC_HOST_DEV); + int ret = ipc_service_release_rx_buffer(&sof_ipc_ept, NULL); + + if (ret < 0) + tr_warn(&ipc_tr, "ipc_service_release_rx_buffer() failed: %d", ret); #if CONFIG_DEBUG_IPC_COUNTERS increment_ipc_processed_counter(); @@ -263,30 +272,34 @@ void ipc_platform_complete_cmd(struct ipc *ipc) int ipc_platform_send_msg(const struct ipc_msg *msg) { - if (!intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV)) + if (ipc_service_get_tx_buffer_size(&sof_ipc_ept) == 0) return -EBUSY; /* prepare the message and copy to mailbox */ struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg); - return intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext); + return ipc_service_send(&sof_ipc_ept, hdr, sizeof(*hdr)); } void ipc_platform_send_msg_direct(const struct ipc_msg *msg) { /* prepare the message and copy to mailbox */ struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg); + int ret = ipc_service_send_critical(&sof_ipc_ept, hdr, sizeof(*hdr)); - intel_adsp_ipc_send_message_emergency(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext); + if (ret < 0) + tr_err(&ipc_tr, "ipc_service_send_critical() failed: %d", ret); } int ipc_platform_poll_is_host_ready(void) { - return intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV); + return ipc_service_get_tx_buffer_size(&sof_ipc_ept) > 0; } int platform_ipc_init(struct ipc *ipc) { + int ret; + ipc_set_drvdata(ipc, NULL); /* schedule task */ @@ -300,9 +313,22 @@ int platform_ipc_init(struct ipc *ipc) #endif /* configure interrupt - work is done internally by Zephyr API */ - /* attach handlers */ - intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc); -#ifdef CONFIG_PM + sof_ipc_ept_cfg.name = "sof_ipc"; + sof_ipc_ept_cfg.prio = 0; + sof_ipc_ept_cfg.cb.received = sof_ipc_receive_cb; + sof_ipc_ept_cfg.priv = ipc; + + /* + * TODO: INTEL_ADSP_IPC_HOST_DEV is currently hardcoded for Intel ADSP platform. + * This needs to be made generic/configurable when additional vendor IPC backends + * become available (e.g., via devicetree, Kconfig, or platform-specific device selection). + */ + ret = ipc_service_register_endpoint(INTEL_ADSP_IPC_HOST_DEV, + &sof_ipc_ept, &sof_ipc_ept_cfg); + if (ret < 0) + return ret; + +#if defined(CONFIG_PM) && defined(CONFIG_INTEL_ADSP_IPC) intel_adsp_ipc_set_suspend_handler(INTEL_ADSP_IPC_HOST_DEV, ipc_device_suspend_handler, ipc); intel_adsp_ipc_set_resume_handler(INTEL_ADSP_IPC_HOST_DEV, @@ -312,6 +338,7 @@ int platform_ipc_init(struct ipc *ipc) return 0; } +#ifdef CONFIG_INTEL_ADSP_IPC static bool ipc_wait_complete(const struct device *dev, void *arg) { k_sem_give(arg); @@ -331,3 +358,4 @@ void ipc_platform_wait_ack(struct ipc *ipc) intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL); } +#endif /* CONFIG_INTEL_ADSP_IPC */ diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index 870459e3a352..88f9d2a4fee7 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -215,7 +215,7 @@ int ipc_comp_dai_config(struct ipc *ipc, struct ipc_config_dai *common_config, int ret = -ENODEV; int i; - tr_info(&ipc_tr, "ipc_comp_dai_config() dai type = %d index = %d", + tr_info(&ipc_tr, "dai type = %d index = %d", config->type, config->dai_index); /* for each component */ @@ -310,7 +310,7 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai dd->ipc_config.type != config->type) return 0; - comp_info(dev, "dai_config() dai type = %d index = %d dd %p", + comp_info(dev, "dai type = %d index = %d dd %p", config->type, config->dai_index, dd); /* cannot configure DAI while active */ @@ -379,7 +379,7 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai dd->dai_spec_config = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(struct sof_ipc_dai_config)); if (!dd->dai_spec_config) { - comp_err(dev, "No memory for dai_config."); + comp_err(dev, "No memory"); return -ENOMEM; } } diff --git a/src/ipc/ipc3/handler.c b/src/ipc/ipc3/handler.c index 9f865960f1bf..80ddb2225e43 100644 --- a/src/ipc/ipc3/handler.c +++ b/src/ipc/ipc3/handler.c @@ -579,7 +579,7 @@ static int ipc_dai_config_set(struct sof_ipc_dai_config *config, } /* configure DAI */ - ret = dai_set_config(dai, config_dai, config); + ret = dai_set_config(dai, config_dai, config, sizeof(*config)); dai_put(dai); /* free ref immediately */ if (ret < 0) { ipc_cmd_err(&ipc_tr, "ipc: dai %d,%d config failed %d", config->type, @@ -829,7 +829,7 @@ static int ipc_dma_trace_config(uint32_t header) if (!dmat) { mtrace_printf(LOG_LEVEL_ERROR, - "ipc_dma_trace_config failed: dmat not initialized"); + "failed: dmat not initialized"); return -ENOMEM; } diff --git a/src/ipc/ipc3/helper.c b/src/ipc/ipc3/helper.c index 658ceaa26784..4d87f042dd1d 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -395,8 +395,8 @@ int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc) } /* create the pipeline */ - pipe = pipeline_new(pipe_desc->pipeline_id, pipe_desc->priority, - pipe_desc->comp_id); + pipe = pipeline_new(NULL, pipe_desc->pipeline_id, pipe_desc->priority, + pipe_desc->comp_id, NULL); if (!pipe) { tr_err(&ipc_tr, "pipeline_new() failed"); return -ENOMEM; @@ -485,7 +485,7 @@ int ipc_buffer_new(struct ipc *ipc, const struct sof_ipc_buffer *desc) } /* register buffer with pipeline */ - buffer = buffer_new(desc, BUFFER_USAGE_NOT_SHARED); + buffer = buffer_new(NULL, desc, BUFFER_USAGE_NOT_SHARED); if (!buffer) { tr_err(&ipc_tr, "buffer_new() failed"); return -ENOMEM; diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index 94fbd1823945..dd55236f0917 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -91,13 +91,9 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void struct processing_module *mod = comp_mod(dev); struct copier_data *cd = module_get_private_data(mod); - if (!cd->gtw_cfg) { - comp_err(dev, "No gateway config found!"); - return SOF_DMA_CHAN_INVALID; - } - channel = SOF_DMA_CHAN_INVALID; - const struct sof_alh_configuration_blob *alh_blob = cd->gtw_cfg; + const struct sof_alh_configuration_blob *alh_blob = + (void *)cd->config.gtw_cfg.config_data; for (int i = 0; i < alh_blob->alh_cfg.count; i++) { if (dai->host_dma_config[i]->stream_id == dai->dai_index) { @@ -346,7 +342,7 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev, dd->ipc_config.type != common_config->type) return 0; - comp_info(dev, "dai_config() dai type = %d index = %d dd %p", + comp_info(dev, "dai type = %d index = %d dd %p", common_config->type, common_config->dai_index, dd); /* cannot configure DAI while active */ @@ -380,7 +376,7 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev, size = sizeof(*copier_cfg); dd->dai_spec_config = rzalloc(SOF_MEM_FLAG_USER, size); if (!dd->dai_spec_config) { - comp_err(dev, "No memory for dai_config size %d", size); + comp_err(dev, "No memory for size %d", size); return -ENOMEM; } @@ -396,7 +392,11 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev, if (ret < 0) return ret; - return dai_set_config(dd->dai, common_config, copier_cfg->gtw_cfg.config_data); + /* gtw_cfg.config_length is in words */ + size = copier_cfg->gtw_cfg.config_length << 2; + + return dai_set_config(dd->dai, common_config, + copier_cfg->gtw_cfg.config_data, size); } #if CONFIG_ZEPHYR_NATIVE_DRIVERS diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index 3eea8f623081..fc64c904ef80 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -39,11 +38,6 @@ #include #include -#if CONFIG_SOF_BOOT_TEST -/* CONFIG_SOF_BOOT_TEST depends on Zephyr */ -#include -#endif - #include #include #include @@ -887,7 +881,7 @@ __cold static int ipc4_init_module_instance(struct ipc4_message_request *ipc4) return IPC4_FAILURE; tr_dbg(&ipc_tr, - "ipc4_init_module_instance %x : %x", + "%x : %x", (uint32_t)module_init.primary.r.module_id, (uint32_t)module_init.primary.r.instance_id); @@ -918,7 +912,7 @@ __cold static int ipc4_bind_module_instance(struct ipc4_message_request *ipc4) if (ret < 0) return IPC4_FAILURE; - tr_dbg(&ipc_tr, "ipc4_bind_module_instance %x : %x with %x : %x", + tr_dbg(&ipc_tr, "%x : %x with %x : %x", (uint32_t)bu.primary.r.module_id, (uint32_t)bu.primary.r.instance_id, (uint32_t)bu.extension.r.dst_module_id, (uint32_t)bu.extension.r.dst_instance_id); @@ -937,7 +931,7 @@ __cold static int ipc4_unbind_module_instance(struct ipc4_message_request *ipc4) if (ret < 0) return IPC4_FAILURE; - tr_dbg(&ipc_tr, "ipc4_unbind_module_instance %x : %x with %x : %x", + tr_dbg(&ipc_tr, "%x : %x with %x : %x", (uint32_t)bu.primary.r.module_id, (uint32_t)bu.primary.r.instance_id, (uint32_t)bu.extension.r.dst_module_id, (uint32_t)bu.extension.r.dst_instance_id); @@ -952,7 +946,7 @@ static int ipc4_set_get_config_module_instance(struct ipc4_message_request *ipc4 struct comp_dev *dev = NULL; int ret; - tr_dbg(&ipc_tr, "ipc4_set_get_config_module_instance %x : %x, set %d", + tr_dbg(&ipc_tr, "%x : %x, set %d", (uint32_t)config->primary.r.module_id, (uint32_t)config->primary.r.instance_id, !!set); @@ -983,7 +977,7 @@ static int ipc4_set_get_config_module_instance(struct ipc4_message_request *ipc4 ret = function(dev, COMP_ATTR_IPC4_CONFIG, &config->extension.dat); if (ret < 0) { - ipc_cmd_err(&ipc_tr, "ipc4_set_get_config_module_instance %x : %x failed %d, set %u, param %x", + ipc_cmd_err(&ipc_tr, "%x : %x failed %d, set %u, param %x", (uint32_t)config->primary.r.module_id, (uint32_t)config->primary.r.instance_id, ret, !!set, (uint32_t)config->extension.dat); @@ -1137,7 +1131,7 @@ __cold static int ipc4_get_large_config_module_instance(struct ipc4_message_requ if (ret < 0) return IPC4_FAILURE; - tr_dbg(&ipc_tr, "ipc4_get_large_config_module_instance %x : %x", + tr_dbg(&ipc_tr, "%x : %x", (uint32_t)config.primary.r.module_id, (uint32_t)config.primary.r.instance_id); /* get component dev for non-basefw since there is no @@ -1299,7 +1293,7 @@ __cold static int ipc4_set_large_config_module_instance(struct ipc4_message_requ dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, config.extension.r.data_off_size); - tr_dbg(&ipc_tr, "ipc4_set_large_config_module_instance %x : %x", + tr_dbg(&ipc_tr, "%x : %x", (uint32_t)config.primary.r.module_id, (uint32_t)config.primary.r.instance_id); if (config.primary.r.module_id) { @@ -1368,7 +1362,7 @@ __cold static int ipc4_delete_module_instance(struct ipc4_message_request *ipc4) if (ret < 0) return IPC4_FAILURE; - tr_dbg(&ipc_tr, "ipc4_delete_module_instance %x : %x", (uint32_t)module.primary.r.module_id, + tr_dbg(&ipc_tr, "%x : %x", (uint32_t)module.primary.r.module_id, (uint32_t)module.primary.r.instance_id); comp_id = IPC4_COMP_ID(module.primary.r.module_id, module.primary.r.instance_id); @@ -1399,7 +1393,7 @@ __cold static int ipc4_module_process_d0ix(struct ipc4_message_request *ipc4) module_id = d0ix.primary.r.module_id; instance_id = d0ix.primary.r.instance_id; - tr_dbg(&ipc_tr, "ipc4_module_process_d0ix %x : %x", module_id, instance_id); + tr_dbg(&ipc_tr, "%x : %x", module_id, instance_id); /* only module 0 can be used to set d0ix state */ if (d0ix.primary.r.module_id || d0ix.primary.r.instance_id) { @@ -1448,7 +1442,7 @@ __cold static int ipc4_module_process_dx(struct ipc4_message_request *ipc4) /* check if core enable mask is valid */ if (dx_info.core_mask > MASK(CONFIG_CORE_COUNT - 1, 0)) { - ipc_cmd_err(&ipc_tr, "ipc4_module_process_dx: CONFIG_CORE_COUNT: %d < core enable mask: %d", + ipc_cmd_err(&ipc_tr, "CONFIG_CORE_COUNT: %d < core enable mask: %d", CONFIG_CORE_COUNT, dx_info.core_mask); return IPC4_ERROR_INVALID_PARAM; } diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 511917ceb768..a06d3dc7bc59 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -138,12 +139,19 @@ __cold struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_i ipc_config.core = module_init->extension.r.core_id; ipc_config.ipc_config_size = module_init->extension.r.param_block_size * sizeof(uint32_t); ipc_config.ipc_extended_init = module_init->extension.r.extended_init; - - dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, - MAILBOX_HOSTBOX_SIZE); - + if (ipc_config.ipc_config_size > MAILBOX_HOSTBOX_SIZE) { + tr_err(&ipc_tr, "IPC payload size %u too big for the message window", + ipc_config.ipc_config_size); + return NULL; + } +#ifdef CONFIG_DCACHE_LINE_SIZE + if (!IS_ENABLED(CONFIG_LIBRARY)) + sys_cache_data_invd_range((__sparse_force void __sparse_cache *) + MAILBOX_HOSTBOX_BASE, + ALIGN_UP(ipc_config.ipc_config_size, + CONFIG_DCACHE_LINE_SIZE)); +#endif data = ipc4_get_comp_new_data(); - #if CONFIG_LIBRARY ipc_config.ipc_config_size -= sizeof(struct sof_uuid); drv = ipc4_library_get_comp_drv(data + ipc_config.ipc_config_size); @@ -229,7 +237,105 @@ struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type, return NULL; } -__cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) +/* + * This function currently only decodes the payload and prints out + * data it finds, but it does not store it anywhere. + */ +__cold static int ipc4_create_pipeline_payload_decode(char *data, + struct create_pipeline_params *pparams) +{ + const struct ipc4_pipeline_ext_payload *hdr = + (struct ipc4_pipeline_ext_payload *)data; + const struct ipc4_pipeline_ext_object *obj; +#ifdef CONFIG_DCACHE_LINE_SIZE + size_t cache_line_size = CONFIG_DCACHE_LINE_SIZE; + size_t hdr_cache_size = ALIGN_UP(sizeof(*hdr), cache_line_size); +#endif + bool last_object; + size_t size; + +#ifdef CONFIG_DCACHE_LINE_SIZE + if (!IS_ENABLED(CONFIG_LIBRARY)) + sys_cache_data_invd_range((__sparse_force void __sparse_cache *)data, + hdr_cache_size); +#endif + size = hdr->payload_words * sizeof(uint32_t); + last_object = !hdr->data_obj_array; + + if (size < sizeof(*hdr)) { + tr_err(&ipc_tr, "Payload size too small: %u : %#x", hdr->payload_words, + *((uint32_t *)hdr)); + return -EINVAL; + } + if (size > MAILBOX_HOSTBOX_SIZE) { + tr_err(&ipc_tr, "Payload size too large: %u : %#x", hdr->payload_words, + *((uint32_t *)hdr)); + } + tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array, + *((uint32_t *)hdr)); + +#ifdef CONFIG_DCACHE_LINE_SIZE + if (!IS_ENABLED(CONFIG_LIBRARY) && ALIGN_UP(size, cache_line_size) > hdr_cache_size) + sys_cache_data_invd_range((__sparse_force void __sparse_cache *) + ((char *)data + hdr_cache_size), + ALIGN_UP(size, cache_line_size) - hdr_cache_size); +#endif + + obj = (const struct ipc4_pipeline_ext_object *)(hdr + 1); + while (!last_object) { + const struct ipc4_pipeline_ext_object *next_obj; + + /* Check if there is space for the object header */ + if ((char *)(obj + 1) - data > size) { + tr_err(&ipc_tr, "obj header overflow, %u > %zu", + (char *)(obj + 1) - data, size); + return -EINVAL; + } + + /* Calculate would be next object position and check if current object fits */ + next_obj = (const struct ipc4_pipeline_ext_object *) + (((const uint32_t *)(obj + 1)) + obj->object_words); + if ((char *)next_obj - data > size) { + tr_err(&ipc_tr, "object size overflow, %u > %zu", + (char *)next_obj - data, size); + return -EINVAL; + } + + switch (obj->object_id) { + case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA: + { + /* Get mem_data struct that follows the obj struct */ + const struct ipc4_pipeline_ext_obj_mem_data *mem_data = + (const struct ipc4_pipeline_ext_obj_mem_data *)(obj + 1); + + if (obj->object_words * sizeof(uint32_t) < sizeof(*mem_data)) { + tr_err(&ipc_tr, "mem_data object does not fit %zu < %zu", + obj->object_words * sizeof(uint32_t), sizeof(*mem_data)); + break; + } + pparams->mem_data = mem_data; + tr_info(&ipc_tr, + "init_ext_obj_mem_data domain %u stack %u interim %u lifetime %u shared %u", + mem_data->domain_id, mem_data->stack_bytes, + mem_data->interim_heap_bytes, mem_data->lifetime_heap_bytes, + mem_data->shared_bytes); + break; + } + default: + tr_warn(&ipc_tr, "Unknown ext init object id %u of %u words", + obj->object_id, obj->object_words); + } + /* Read the last object flag from obj header */ + last_object = obj->last_object; + /* Move to next object */ + obj = next_obj; + } + + return 0; +} + +__cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc, + struct create_pipeline_params *pparams) { struct ipc_comp_dev *ipc_pipe; struct pipeline *pipe; @@ -246,7 +352,8 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) } /* create the pipeline */ - pipe = pipeline_new(pipe_desc->primary.r.instance_id, pipe_desc->primary.r.ppl_priority, 0); + pipe = pipeline_new(NULL, pipe_desc->primary.r.instance_id, + pipe_desc->primary.r.ppl_priority, 0, pparams); if (!pipe) { tr_err(&ipc_tr, "ipc: pipeline_new() failed"); return IPC4_OUT_OF_MEMORY; @@ -280,11 +387,29 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) return IPC4_SUCCESS; } +#if CONFIG_LIBRARY +static inline char *ipc4_get_pipe_create_data(void) +{ + struct ipc *ipc = ipc_get(); + char *data = (char *)ipc->comp_data + sizeof(struct ipc4_pipeline_create); + + return data; +} +#else +__cold static inline char *ipc4_get_pipe_create_data(void) +{ + assert_can_be_cold(); + + return (char *)MAILBOX_HOSTBOX_BASE; +} +#endif + /* Only called from ipc4_new_pipeline(), which is __cold */ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc) { struct ipc4_pipeline_create *pipe_desc = ipc_from_pipe_new(_pipe_desc); - + struct create_pipeline_params pparams = { 0 }; + bool valid_pparams = false; assert_can_be_cold(); tr_dbg(&ipc_tr, "ipc: pipeline id = %u", (uint32_t)pipe_desc->primary.r.instance_id); @@ -293,7 +418,18 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc) if (!cpu_is_me(pipe_desc->extension.r.core_id)) return ipc4_process_on_core(pipe_desc->extension.r.core_id, false); - return ipc4_create_pipeline(pipe_desc); + if (pipe_desc->extension.r.payload) { + char *data; + int ret; + + data = ipc4_get_pipe_create_data(); + + ret = ipc4_create_pipeline_payload_decode(data, &pparams); + if (ret == 0) + valid_pparams = true; + } + + return ipc4_create_pipeline(pipe_desc, valid_pparams ? &pparams : NULL); } __cold static inline int ipc_comp_free_remote(struct comp_dev *dev) @@ -321,6 +457,7 @@ __cold static int ipc_pipeline_module_free(uint32_t pipeline_id) /* free sink buffer allocated by current component in bind function */ comp_dev_for_each_consumer_safe(icd->cd, buffer, safe) { + pipeline_disconnect(icd->cd, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); struct comp_dev *sink = comp_buffer_get_sink_component(buffer); /* free the buffer only when the sink module has also been disconnected */ @@ -391,7 +528,7 @@ __cold int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id) __cold static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, bool is_shared, uint32_t buf_size, uint32_t src_queue, - uint32_t dst_queue) + uint32_t dst_queue, struct k_heap *heap) { struct sof_ipc_buffer ipc_buf; @@ -402,7 +539,7 @@ __cold static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, bool ipc_buf.comp.id = IPC4_COMP_ID(src_queue, dst_queue); ipc_buf.comp.pipeline_id = src->ipc_config.pipeline_id; ipc_buf.comp.core = cpu_get_id(); - return buffer_new(&ipc_buf, is_shared); + return buffer_new(heap, &ipc_buf, is_shared); } #if CONFIG_CROSS_CORE_STREAM @@ -503,6 +640,8 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return IPC4_INVALID_RESOURCE_ID; } + struct k_heap *dp_heap; + #if CONFIG_ZEPHYR_DP_SCHEDULER if (source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP && sink->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { @@ -510,6 +649,19 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) src_id, sink_id); return IPC4_INVALID_REQUEST; } + + struct comp_dev *dp; + + if (sink->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + dp = sink; + else if (source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + dp = source; + else + dp = NULL; + + dp_heap = dp && dp->mod ? dp->mod->priv.resources.heap : NULL; +#else + dp_heap = NULL; #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ bool cross_core_bind = source->ipc_config.core != sink->ipc_config.core; @@ -579,12 +731,20 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) buf_size = ibs * 2; buffer = ipc4_create_buffer(source, cross_core_bind, buf_size, bu->extension.r.src_queue, - bu->extension.r.dst_queue); + bu->extension.r.dst_queue, dp_heap); if (!buffer) { - tr_err(&ipc_tr, "failed to allocate buffer to bind %d to %d", src_id, sink_id); + tr_err(&ipc_tr, "failed to allocate buffer to bind %#x to %#x", src_id, sink_id); return IPC4_OUT_OF_MEMORY; } +#if CONFIG_ZEPHYR_DP_SCHEDULER + if (dp_heap) { + struct dp_heap_user *dp_user = container_of(dp_heap, struct dp_heap_user, heap); + + dp_user->client_count++; + } +#endif + /* * set min_free_space and min_available in sink/src api of created buffer. * buffer is connected like: @@ -603,20 +763,30 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) if (sink->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP || source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { - bool dp_on_source = source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP; - struct sof_source *src = audio_buffer_get_source(&buffer->audio_buffer); - struct sof_sink *snk = audio_buffer_get_sink(&buffer->audio_buffer); - - ring_buffer = ring_buffer_create(dp_on_source ? source : sink, - source_get_min_available(src), - sink_get_min_free_space(snk), + struct processing_module *srcmod = comp_mod(source); + struct module_data *src_module_data = &srcmod->priv; + struct processing_module *dstmod = comp_mod(sink); + struct module_data *dst_module_data = &dstmod->priv; + + /* + * Handle cases where the size of the ring buffer depends on the + * in_buff_size/out_buff_size advertised by the module. E.g. in the case of the + * compressed decoder module, the in/out_buff_size is determined during module + * init based on the decoder implementation. Also note that the size passed here + * is only for the ring buffer. The size of intermediate buffer created above is + * unchanged. + */ + ring_buffer = ring_buffer_create(dp, MAX(ibs, dst_module_data->mpd.in_buff_size), + MAX(obs, src_module_data->mpd.out_buff_size), audio_buffer_is_shared(&buffer->audio_buffer), buf_get_id(buffer)); - if (!ring_buffer) - goto free; + if (!ring_buffer) { + buffer_free(buffer); + return IPC4_OUT_OF_MEMORY; + } /* data destination module needs to use ring_buffer */ - audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, dp_on_source, + audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, dp == source, &ring_buffer->audio_buffer); } @@ -646,14 +816,14 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) ret = comp_buffer_connect(source, source->ipc_config.core, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); if (ret < 0) { - tr_err(&ipc_tr, "failed to connect src %d to internal buffer", src_id); + tr_err(&ipc_tr, "failed to connect src %#x to internal buffer", src_id); goto free; } ret = comp_buffer_connect(sink, sink->ipc_config.core, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); if (ret < 0) { - tr_err(&ipc_tr, "failed to connect internal buffer to sink %d", sink_id); + tr_err(&ipc_tr, "failed to connect internal buffer to sink %#x", sink_id); goto e_sink_connect; } @@ -1043,7 +1213,7 @@ __cold const struct comp_driver *ipc4_get_comp_drv(uint32_t module_id) mod = lib_manager_get_module_manifest(module_id); if (!mod) { - tr_err(&comp_tr, "Error: Couldn't find loadable module with id %d.", + tr_err(&comp_tr, "Error: Couldn't find loadable module with id %#x.", module_id); return NULL; } @@ -1103,7 +1273,7 @@ __cold static int ipc4_add_comp_dev(struct comp_dev *dev) icd->core = dev->ipc_config.core; icd->id = dev->ipc_config.id; - tr_dbg(&ipc_tr, "ipc4_add_comp_dev add comp 0x%x", icd->id); + tr_dbg(&ipc_tr, "add comp 0x%x", icd->id); /* add new component to the list */ list_item_append(&icd->list, &ipc->comp_list); @@ -1152,28 +1322,36 @@ int ipc4_find_dma_config_multiple(struct ipc_config_dai *dai, uint8_t *data_buff return IPC4_INVALID_REQUEST; } -void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, - struct sof_ipc_stream_params *params) +void ipc4_audio_format_to_stream_params(const struct ipc4_audio_format *audio_fmt, + struct sof_ipc_stream_params *params) { enum sof_ipc_frame frame_fmt, valid_fmt; int i; memset(params, 0, sizeof(struct sof_ipc_stream_params)); - params->channels = base_cfg->audio_fmt.channels_count; - params->rate = base_cfg->audio_fmt.sampling_frequency; - params->sample_container_bytes = base_cfg->audio_fmt.depth / 8; - params->sample_valid_bytes = base_cfg->audio_fmt.valid_bit_depth / 8; - params->buffer_fmt = base_cfg->audio_fmt.interleaving_style; - params->buffer.size = base_cfg->obs * 2; - - audio_stream_fmt_conversion(base_cfg->audio_fmt.depth, - base_cfg->audio_fmt.valid_bit_depth, + params->channels = audio_fmt->channels_count; + params->rate = audio_fmt->sampling_frequency; + params->sample_container_bytes = audio_fmt->depth / 8; + params->sample_valid_bytes = audio_fmt->valid_bit_depth / 8; + params->buffer_fmt = audio_fmt->interleaving_style; + + audio_stream_fmt_conversion(audio_fmt->depth, + audio_fmt->valid_bit_depth, &frame_fmt, &valid_fmt, - base_cfg->audio_fmt.s_type); + audio_fmt->s_type); params->frame_fmt = frame_fmt; for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; + params->chmap[i] = (audio_fmt->ch_map >> i * 4) & 0xf; +} + +void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, + struct sof_ipc_stream_params *params) +{ + memset(params, 0, sizeof(struct sof_ipc_stream_params)); + params->buffer.size = base_cfg->obs * 2; + + ipc4_audio_format_to_stream_params(&base_cfg->audio_fmt, params); } EXPORT_SYMBOL(ipc4_base_module_cfg_to_stream_params); diff --git a/src/ipc/ipc4/logging.c b/src/ipc/ipc4/logging.c index 2e0f6fd5088e..feb0863f64b7 100644 --- a/src/ipc/ipc4/logging.c +++ b/src/ipc/ipc4/logging.c @@ -9,6 +9,7 @@ #endif #include +#include #include #include #include @@ -60,7 +61,7 @@ static uint32_t mtrace_aging_timer = IPC4_MTRACE_NOTIFY_AGING_TIMER_MS; #define MTRACE_IPC_CORE PLATFORM_PRIMARY_CORE_ID -static struct k_mutex log_mutex; +static K_MUTEX_DEFINE(log_mutex); static struct k_work_delayable log_work; static void mtrace_log_hook_unlocked(size_t written, size_t space_left) @@ -140,11 +141,13 @@ int ipc4_logging_enable_logs(bool first_block, if (log_state->enable) { adsp_mtrace_log_init(mtrace_log_hook); + /* Initialize work queue if not already initialized */ + if (!log_work.work.handler) + k_work_init_delayable(&log_work, log_work_handler); - k_mutex_init(&log_mutex); - k_work_init_delayable(&log_work, log_work_handler); - - log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL); + /* Enable backend if not already active */ + if (!log_backend_is_active(log_backend)) + log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL); mtrace_aging_timer = log_state->aging_timer_period; if (mtrace_aging_timer < IPC4_MTRACE_AGING_TIMER_MIN_MS) { @@ -152,10 +155,20 @@ int ipc4_logging_enable_logs(bool first_block, LOG_WRN("Too small aging timer value, limiting to %u\n", mtrace_aging_timer); } + + /* Logs enabled, this is the best place to run boot-tests */ + TEST_RUN_ONCE(sof_run_boot_tests); } else { - k_work_flush_delayable(&log_work, &ipc4_log_work_sync); + /* Flush work queue if initialized */ + if (log_work.work.handler) { + k_work_flush_delayable(&log_work, &ipc4_log_work_sync); + log_work.work.handler = NULL; + } + adsp_mtrace_log_init(NULL); - log_backend_disable(log_backend); + /* Disable backend if currently active */ + if (log_backend_is_active(log_backend)) + log_backend_disable(log_backend); } return 0; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f7a37d50cd72..707753635f69 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -set(common_files notifier.c dma.c dai.c) +set(common_files notifier.c dma.c dai.c objpool.c) if(CONFIG_LIBRARY) add_local_sources(sof diff --git a/src/lib/agent.c b/src/lib/agent.c index 1d96bc54bb7e..1030e88dd7f2 100644 --- a/src/lib/agent.c +++ b/src/lib/agent.c @@ -81,9 +81,9 @@ static enum task_state validate(void *data) /* warning timeout */ if (delta > sa->warn_timeout) { if (delta > UINT_MAX) - tr_warn(&sa_tr, "validate(), ll drift detected, delta > %u", UINT_MAX); + tr_warn(&sa_tr, "ll drift detected, delta > %u", UINT_MAX); else - tr_warn(&sa_tr, "validate(), ll drift detected, delta = %u", + tr_warn(&sa_tr, "ll drift detected, delta = %u", (unsigned int)delta); } @@ -98,9 +98,9 @@ void sa_init(struct sof *sof, uint64_t timeout) uint64_t ticks; if (timeout > UINT_MAX) - tr_warn(&sa_tr, "sa_init(), timeout > %u", UINT_MAX); + tr_warn(&sa_tr, "timeout > %u", UINT_MAX); else - tr_info(&sa_tr, "sa_init(), timeout = %u", (unsigned int)timeout); + tr_info(&sa_tr, "timeout = %u", (unsigned int)timeout); sof->sa = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->sa)); @@ -117,10 +117,10 @@ void sa_init(struct sof *sof, uint64_t timeout) if (ticks > UINT_MAX || sof->sa->warn_timeout > UINT_MAX || sof->sa->panic_timeout > UINT_MAX) tr_info(&sa_tr, - "sa_init(), some of the values are > %u", UINT_MAX); + "some of the values are > %u", UINT_MAX); else tr_info(&sa_tr, - "sa_init(), ticks = %u, sof->sa->warn_timeout = %u, sof->sa->panic_timeout = %u", + "ticks = %u, sof->sa->warn_timeout = %u, sof->sa->panic_timeout = %u", (unsigned int)ticks, (unsigned int)sof->sa->warn_timeout, (unsigned int)sof->sa->panic_timeout); diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 7d07677c9a65..a6354fb0420f 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -71,3 +71,14 @@ int heap_info(int index, struct mm_info *out) return 0; } #endif + +void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, + size_t alignment) +{ + return malloc(bytes); +} + +void sof_heap_free(struct k_heap *heap, void *addr) +{ + free(addr); +} diff --git a/src/lib/ams.c b/src/lib/ams.c index 766c3bd96213..31bca13ce833 100644 --- a/src/lib/ams.c +++ b/src/lib/ams.c @@ -495,7 +495,7 @@ static int ams_process_slot(struct async_message_service *ams, uint32_t slot) instance_id = shared_c->slots[slot].instance_id; ams_release(shared_c); - tr_info(&ams_tr, "ams_process_slot slot %d msg %d from 0x%08x", + tr_info(&ams_tr, "slot %d msg %d from 0x%08x", slot, msg.message_type_id, msg.producer_module_id << 16 | msg.producer_instance_id); diff --git a/src/lib/dai.c b/src/lib/dai.c index c4daf2b06918..8e45f8a4bb97 100644 --- a/src/lib/dai.c +++ b/src/lib/dai.c @@ -187,6 +187,14 @@ const struct device *zephyr_dev[] = { #endif }; +const struct device **dai_get_device_list(size_t *count) +{ + __ASSERT_NO_MSG(count); + *count = ARRAY_SIZE(zephyr_dev); + + return zephyr_dev; +} + /* convert sof_ipc_dai_type to Zephyr dai_type */ static int sof_dai_type_to_zephyr(uint32_t type) { @@ -223,7 +231,7 @@ static int sof_dai_type_to_zephyr(uint32_t type) } } -const struct device *dai_get_device(uint32_t type, uint32_t index) +const struct device *dai_get_device(enum sof_ipc_dai_type type, uint32_t index) { struct dai_config cfg; int z_type; @@ -325,7 +333,7 @@ void dai_put(struct dai *dai) ret = dai_remove(dai->dev); if (ret < 0) { - tr_err(&dai_tr, "dai_put_zephyr: index %d failed ret = %d", + tr_err(&dai_tr, "index %d failed ret = %d", dai->index, ret); } @@ -391,11 +399,11 @@ void dai_put(struct dai *dai) if (--dai->sref == 0) { ret = dai_remove(dai); if (ret < 0) { - tr_err(&dai_tr, "dai_put: type %d index %d dai_remove() failed ret = %d", + tr_err(&dai_tr, "type %d index %d dai_remove() failed ret = %d", dai->drv->type, dai->index, ret); } } - tr_info(&dai_tr, "dai_put type %d index %d new sref %d", + tr_info(&dai_tr, "type %d index %d new sref %d", dai->drv->type, dai->index, dai->sref); k_spin_unlock(&dai->lock, key); } diff --git a/src/lib/dma.c b/src/lib/dma.c index d24f730276b1..608ee091ac25 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -36,7 +35,7 @@ DECLARE_TR_CTX(dma_tr, SOF_UUID(dma_uuid), LOG_LEVEL_INFO); #if CONFIG_ZEPHYR_NATIVE_DRIVERS static int dma_init(struct sof_dma *dma); -struct sof_dma *sof_dma_get(uint32_t dir, uint32_t cap, uint32_t dev, uint32_t flags) +struct sof_dma *z_impl_sof_dma_get(uint32_t dir, uint32_t cap, uint32_t dev, uint32_t flags) { const struct dma_info *info = dma_info_get(); int users, ret = 0; @@ -129,7 +128,7 @@ struct sof_dma *sof_dma_get(uint32_t dir, uint32_t cap, uint32_t dev, uint32_t f return !ret ? dmin : NULL; } -void sof_dma_put(struct sof_dma *dma) +void z_impl_sof_dma_put(struct sof_dma *dma) { k_spinlock_key_t key; @@ -168,8 +167,6 @@ static int dma_init(struct sof_dma *dma) return 0; } -EXPORT_SYMBOL(sof_dma_get); -EXPORT_SYMBOL(sof_dma_put); #else struct dma *dma_get(uint32_t dir, uint32_t cap, uint32_t dev, uint32_t flags) { @@ -278,16 +275,14 @@ void dma_put(struct dma *dma) if (--dma->sref == 0) { ret = dma_remove_legacy(dma); if (ret < 0) { - tr_err(&dma_tr, "dma_put(): dma_remove() failed id = %d, ret = %d", + tr_err(&dma_tr, "dma_remove() failed id = %d, ret = %d", dma->plat_data.id, ret); } } - tr_info(&dma_tr, "dma_put(), dma = %p, sref = %d", + tr_info(&dma_tr, "dma = %p, sref = %d", dma, dma->sref); k_spin_unlock(&dma->lock, key); } -EXPORT_SYMBOL(dma_get); -EXPORT_SYMBOL(dma_put); #endif int dma_sg_alloc(struct dma_sg_elem_array *elem_array, @@ -329,7 +324,6 @@ void dma_sg_free(struct dma_sg_elem_array *elem_array) rfree(elem_array->elems); dma_sg_init(elem_array); } -EXPORT_SYMBOL(dma_sg_free); int dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, diff --git a/src/lib/notifier.c b/src/lib/notifier.c index 8ec3d02f8a82..e398417a6fd1 100644 --- a/src/lib/notifier.c +++ b/src/lib/notifier.c @@ -63,7 +63,7 @@ int notifier_register(void *receiver, void *caller, enum notify_id type, sizeof(*handle)); if (!handle) { - tr_err(&nt_tr, "notifier_register(): callback handle allocation failed."); + tr_err(&nt_tr, "callback handle allocation failed."); ret = -ENOMEM; goto out; } @@ -197,7 +197,7 @@ void init_system_notify(struct sof *sof) *notify = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(**notify)); if (!*notify) { - tr_err(&nt_tr, "init_system_notify(): allocation failed"); + tr_err(&nt_tr, "allocation failed"); sof_panic(SOF_IPC_PANIC_IPC); } diff --git a/src/lib/objpool.c b/src/lib/objpool.c new file mode 100644 index 000000000000..3df78103e13c --- /dev/null +++ b/src/lib/objpool.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct objpool { + struct list_item list; + unsigned int n; + uint32_t mask; + size_t size; + uint8_t data[]; +}; + +#define OBJPOOL_BITS (sizeof(((struct objpool *)0)->mask) * 8) + +static int objpool_add(struct objpool_head *head, unsigned int n, size_t size, uint32_t flags) +{ + if (n > OBJPOOL_BITS) + return -ENOMEM; + + if (!is_power_of_2(n)) + return -EINVAL; + + size_t aligned_size = n * ALIGN_UP(size, sizeof(int)); + + if (!head->heap) + head->heap = sof_sys_heap_get(); + + struct objpool *pobjpool = sof_heap_alloc(head->heap, flags, + aligned_size + sizeof(*pobjpool), 0); + + if (!pobjpool) + return -ENOMEM; + + /* Initialize with 0 to give caller a chance to identify new allocations */ + memset(pobjpool->data, 0, aligned_size); + + pobjpool->n = n; + /* clear bit means free */ + pobjpool->mask = 0; + pobjpool->size = size; + + list_item_append(&pobjpool->list, &head->list); + + return 0; +} + +void *objpool_alloc(struct objpool_head *head, size_t size, uint32_t flags) +{ + size_t aligned_size = ALIGN_UP(size, sizeof(int)); + struct list_item *list; + struct objpool *pobjpool; + + /* Make sure size * 32 still fits in OBJPOOL_BITS bits */ + if (!size || aligned_size > (UINT_MAX >> 5) - sizeof(*pobjpool)) + return NULL; + + if (!list_is_empty(&head->list) && head->flags != flags) + /* List isn't empty, and flags don't match */ + return NULL; + + list_for_item(list, &head->list) { + pobjpool = container_of(list, struct objpool, list); + + uint32_t free_mask = MASK(pobjpool->n - 1, 0) & ~pobjpool->mask; + + /* sanity check */ + if (size != pobjpool->size) + return NULL; + + if (!free_mask) + continue; + + /* Find first free - guaranteed valid now */ + unsigned int bit = ffs(free_mask) - 1; + + pobjpool->mask |= BIT(bit); + + return pobjpool->data + aligned_size * bit; + } + + /* no free elements found */ + unsigned int new_n; + + if (list_is_empty(&head->list)) { + head->flags = flags; + new_n = 2; + } else { + /* Check the last one */ + pobjpool = container_of(head->list.prev, struct objpool, list); + + if (pobjpool->n == OBJPOOL_BITS) + new_n = OBJPOOL_BITS; + else + new_n = pobjpool->n << 1; + } + + if (objpool_add(head, new_n, size, flags) < 0) + return NULL; + + /* Return the first element of the new objpool, which is now the last one in the list */ + pobjpool = container_of(head->list.prev, struct objpool, list); + pobjpool->mask = 1; + + return pobjpool->data; +} + +int objpool_free(struct objpool_head *head, void *data) +{ + struct list_item *list; + struct objpool *pobjpool; + + if (!data) + return 0; + + list_for_item(list, &head->list) { + pobjpool = container_of(list, struct objpool, list); + + size_t aligned_size = ALIGN_UP(pobjpool->size, sizeof(int)); + + if ((uint8_t *)data >= pobjpool->data && + (uint8_t *)data < pobjpool->data + aligned_size * pobjpool->n) { + unsigned int n = ((uint8_t *)data - pobjpool->data) / aligned_size; + + if ((uint8_t *)data != pobjpool->data + n * aligned_size) + return -EINVAL; + + pobjpool->mask &= ~BIT(n); + + return 0; + } + } + + return -EINVAL; +} + +void objpool_prune(struct objpool_head *head) +{ + struct list_item *next, *tmp; + + list_for_item_safe(next, tmp, &head->list) { + list_item_del(next); + sof_heap_free(head->heap, container_of(next, struct objpool, list)); + } +} + +int objpool_iterate(struct objpool_head *head, objpool_iterate_cb cb, void *arg) +{ + struct list_item *list; + + list_for_item(list, &head->list) { + struct objpool *pobjpool = container_of(list, struct objpool, list); + size_t aligned_size = ALIGN_UP(pobjpool->size, sizeof(int)); + unsigned int bit; + + for (uint32_t mask = pobjpool->mask; mask; mask &= ~BIT(bit)) { + bit = ffs(mask) - 1; + + if (cb(pobjpool->data + bit * aligned_size, arg)) + return 0; + } + } + + return -ENOENT; +} diff --git a/src/library_manager/lib_manager.c b/src/library_manager/lib_manager.c index d45df1493f5e..b81ec6bbe738 100644 --- a/src/library_manager/lib_manager.c +++ b/src/library_manager/lib_manager.c @@ -3,7 +3,8 @@ // Copyright(c) 2022 Intel Corporation. All rights reserved. // // Author: Jaroslaw Stelter -// Pawel Dobrowolski +// Pawel Dobrowolski +// Adrian Warecki /* * Dynamic module loading functions. @@ -18,11 +19,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -373,7 +376,15 @@ static uintptr_t lib_manager_allocate_module(const struct sof_man_module *mod, return 0; } -int lib_manager_free_module(const uint32_t component_id) +/* + * \brief Free module + * + * param[in] component_id - component id coming from ipc config. This function reguires valid + * lib_id and module_id fields of component id. + * + * Function is responsible to free module resources in HP memory. + */ +static int lib_manager_free_module(const uint32_t component_id) { const struct sof_man_module *mod; const uint32_t module_id = IPC4_MOD_ID(component_id); @@ -412,14 +423,14 @@ int lib_manager_free_module(const uint32_t component_id) #define PAGE_SZ 4096 /* equals to MAN_PAGE_SIZE used by rimage */ -uintptr_t lib_manager_allocate_module(const struct comp_ipc_config *ipc_config, - const void *ipc_specific_config, const void **buildinfo) +static uintptr_t lib_manager_allocate_module(const struct comp_ipc_config *ipc_config, + const void *ipc_specific_config, const void **buildinfo) { tr_err(&lib_manager_tr, "Dynamic module allocation is not supported"); return 0; } -int lib_manager_free_module(const uint32_t component_id) +static int lib_manager_free_module(const uint32_t component_id) { /* Since we cannot allocate the freeing is not considered to be an error */ tr_warn(&lib_manager_tr, "Dynamic module freeing is not supported"); @@ -452,7 +463,7 @@ static void lib_manager_update_sof_ctx(void *base_addr, uint32_t lib_id) struct lib_manager_mod_ctx *ctx = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, sizeof(*ctx)); if (!ctx) { - tr_err(&lib_manager_tr, "lib_manager_update_sof_ctx(): allocation failed"); + tr_err(&lib_manager_tr, "allocation failed"); sof_panic(SOF_IPC_PANIC_IPC); } @@ -487,23 +498,27 @@ const struct sof_man_module *lib_manager_get_module_manifest(const uint32_t modu * \brief Starts system agent and returns module interface into agent_interface variable. * * \param[in] drv - Pointer to the component driver structure. - * \param[in] component_id - Identifier of the component. + * \param[in] config - Pointer to component ipc config structure * \param[in] args - Pointer to components' ipc configuration arguments. * \param[in] module_entry_point - Entry point address of the module. * \param[in] agent - Function pointer to the system agent start function. * \param[out] agent_interface - Pointer to store the module interface returned by the system agent. + * \param[out] userspace - Pointer to store the userspace module proxy context. + * \param[out] ops - Pointer to store pointer to the module interface structure. * * \return Error code returned by the system agent, 0 on success. */ -static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t component_id, +static int lib_manager_start_agent(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const struct sof_man_module *mod_manifest, const struct ipc_config_process *args, const uintptr_t module_entry_point, const system_agent_start_fn agent, - const void **agent_interface) + const void **agent_interface, + struct userspace_context **userspace, + const struct module_interface **ops) { - const uint32_t module_id = IPC4_MOD_ID(component_id); - const uint32_t instance_id = IPC4_INST_ID(component_id); - const uint32_t log_handle = (uint32_t)drv->tctx; + struct system_agent_params agent_params; byte_array_t mod_cfg; int ret; @@ -511,8 +526,25 @@ static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t /* Intel modules expects DW size here */ mod_cfg.size = args->size >> 2; - ret = agent(module_entry_point, module_id, instance_id, 0, log_handle, &mod_cfg, - agent_interface); + agent_params.entry_point = module_entry_point; + agent_params.module_id = IPC4_MOD_ID(config->id); + agent_params.instance_id = IPC4_INST_ID(config->id); + agent_params.core_id = config->core; + agent_params.log_handle = (uint32_t)drv->tctx; + agent_params.mod_cfg = &mod_cfg; + +#if CONFIG_SOF_USERSPACE_PROXY + /* If drv->user_heap is allocated, it means the module is userspace. */ + if (drv->user_heap) { + ret = userspace_proxy_create(userspace, drv, mod_manifest, agent, &agent_params, + agent_interface, ops); + if (ret) + tr_err(&lib_manager_tr, "userspace_proxy_create failed! %d", ret); + return ret; + } +#endif /* CONFIG_SOF_USERSPACE_PROXY */ + + ret = agent(&agent_params, agent_interface); if (ret) tr_err(&lib_manager_tr, "System agent start failed %d!", ret); @@ -578,9 +610,10 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv, const void *spec) { const struct sof_man_fw_desc *const desc = lib_manager_get_library_manifest(config->id); - const struct ipc_config_process *args = (struct ipc_config_process *)spec; + const struct ipc_config_process *args = (const struct ipc_config_process *)spec; const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(config->id); - const struct module_interface *ops = NULL; + struct userspace_context *userspace = NULL; + const struct module_interface *ops; const struct sof_man_module *mod; system_agent_start_fn agent; void *adapter_priv = NULL; @@ -588,6 +621,13 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv, struct comp_dev *dev; int ret; +#ifdef CONFIG_SOF_USERSPACE_PROXY + if (drv->user_heap && config->proc_domain != COMP_PROCESSING_DOMAIN_DP) { + tr_err(&lib_manager_tr, "Userspace supports only DP modules."); + return NULL; + } +#endif + tr_dbg(&lib_manager_tr, "start"); if (!desc) { tr_err(&lib_manager_tr, "Error: Couldn't find loadable module with id %u.", @@ -619,35 +659,39 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv, agent = &native_system_agent_start; agent_iface = (const void **)&ops; break; +#if CONFIG_INTEL_MODULES case MOD_TYPE_IADK: agent = &system_agent_start; - /* processing_module_adapter_interface is already assigned to drv->adapter_ops by - * the lib_manager_prepare_module_adapter function. - */ + ops = &processing_module_adapter_interface; agent_iface = (const void **)&adapter_priv; break; +#endif case MOD_TYPE_INVALID: goto err; } /* At this point module resources are allocated and it is moved to L2 memory. */ if (agent) { - ret = lib_manager_start_agent(drv, config->id, args, module_entry_point, agent, - agent_iface); + ret = lib_manager_start_agent(drv, config, mod, args, module_entry_point, agent, + agent_iface, &userspace, &ops); if (ret) goto err; } - if (ops && comp_set_adapter_ops(drv, ops) < 0) + if (comp_set_adapter_ops(drv, ops) < 0) goto err; - dev = module_adapter_new_ext(drv, config, spec, adapter_priv); + dev = module_adapter_new_ext(drv, config, spec, adapter_priv, userspace); if (!dev) goto err; return dev; err: +#if CONFIG_SOF_USERSPACE_PROXY + if (userspace) + userspace_proxy_destroy(drv, userspace); +#endif /* CONFIG_SOF_USERSPACE_PROXY */ lib_manager_free_module(config->id); return NULL; } @@ -694,18 +738,16 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st drv->ops.dai_ts_start = module_adapter_ts_start_op; drv->ops.dai_ts_stop = module_adapter_ts_stop_op; drv->ops.dai_ts_get = module_adapter_ts_get_op; -#if CONFIG_INTEL_MODULES - drv->adapter_ops = &processing_module_adapter_interface; -#endif } int lib_manager_register_module(const uint32_t component_id) { - struct comp_driver_info *new_drv_info; - struct comp_driver *drv = NULL; const struct sof_man_module *mod = lib_manager_get_module_manifest(component_id); const struct sof_uuid *uid = (struct sof_uuid *)&mod->uuid; - int ret; + struct comp_driver_info *new_drv_info; + struct k_heap *drv_heap = NULL; + struct comp_driver *drv = NULL; + int ret = -ENOMEM; if (!mod) { tr_err(&lib_manager_tr, "Error: Couldn't find loadable module with id %u.", @@ -722,14 +764,26 @@ int lib_manager_register_module(const uint32_t component_id) return -ENOMEM; } - drv = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, - sizeof(struct comp_driver)); +#if CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP + if (mod->type.user_mode) { + drv_heap = module_driver_heap_init(); + if (!drv_heap) { + tr_err(&lib_manager_tr, "failed to allocate driver heap!"); + goto cleanup; + } + } +#endif /* CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP */ + + drv = sof_heap_alloc(drv_heap, SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, + sizeof(struct comp_driver), 0); if (!drv) { tr_err(&lib_manager_tr, "failed to allocate comp_driver"); - ret = -ENOMEM; goto cleanup; } + memset(drv, 0, sizeof(*drv)); + drv->user_heap = drv_heap; + lib_manager_prepare_module_adapter(drv, uid); /* Fill the new_drv_info structure with already known parameters */ @@ -741,8 +795,9 @@ int lib_manager_register_module(const uint32_t component_id) cleanup: if (ret < 0) { - rfree(drv); rfree(new_drv_info); + sof_heap_free(drv_heap, drv); + module_driver_heap_remove(drv_heap); } return ret; @@ -937,6 +992,9 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, return ret; } + /* Writeback entire library to ensure it's visible to other cores */ + dcache_writeback_region((__sparse_force void *)library_base_address, preload_size); + #if CONFIG_LIBRARY_AUTH_SUPPORT /* AUTH_PHASE_LAST - do final library authentication checks */ ret = lib_manager_auth_proc((__sparse_force void *)library_base_address, diff --git a/src/library_manager/llext_manager.c b/src/library_manager/llext_manager.c index 9c032319f82d..28a79ad4c00b 100644 --- a/src/library_manager/llext_manager.c +++ b/src/library_manager/llext_manager.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -124,7 +125,7 @@ static int llext_manager_load_data_from_storage(const struct sys_mm_drv_region * int ret = llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset); if (ret < 0) { - tr_err(lib_manager_tr, "no section info: %d", ret); + tr_err(&lib_manager_tr, "no section info: %d", ret); continue; } @@ -226,9 +227,12 @@ static int llext_manager_load_module(struct lib_manager_module *mctx) (uintptr_t)bss_addr >= (uintptr_t)va_base_data + data_size)) { size_t bss_align = MIN(PAGE_SZ, BIT(__builtin_ctz((uintptr_t)bss_addr))); - if ((uintptr_t)bss_addr + bss_size == (uintptr_t)va_base_data && - !((uintptr_t)bss_addr & (PAGE_SZ - 1))) { - /* .bss directly in front of writable data and properly aligned, prepend */ + if ((!data_size || (uintptr_t)bss_addr + bss_size == (uintptr_t)va_base_data) && + bss_align >= PAGE_SZ) { + /* + * .bss is properly aligned and either there's no writable data, + * or .bss is directly in front of writable data, prepend .bss + */ va_base_data = bss_addr; data_size += bss_size; } else if ((uintptr_t)bss_addr == (uintptr_t)va_base_data + @@ -250,11 +254,15 @@ static int llext_manager_load_module(struct lib_manager_module *mctx) const struct sys_mm_drv_region *virtual_memory_regions = sys_mm_drv_query_memory_regions(); const struct sys_mm_drv_region *virtual_region; + if (!virtual_memory_regions) + return -EFAULT; + SYS_MM_DRV_MEMORY_REGION_FOREACH(virtual_memory_regions, virtual_region) { if (virtual_region->attr == VIRTUAL_REGION_LLEXT_LIBRARIES_ATTR) break; } - if (!virtual_region || !virtual_region->size) + + if (!virtual_region->size) return -EFAULT; /* Copy Code */ @@ -286,7 +294,8 @@ static int llext_manager_load_module(struct lib_manager_module *mctx) return 0; e_rodata: - llext_manager_align_unmap(va_base_rodata, rodata_size); + if (rodata_size) + llext_manager_align_unmap(va_base_rodata, rodata_size); e_text: llext_manager_align_unmap(va_base_text, text_size); @@ -716,6 +725,248 @@ uintptr_t llext_manager_allocate_module(const struct comp_ipc_config *ipc_config return mod_manifest->module.entry_point; } +#ifdef CONFIG_USERSPACE +static int llext_manager_add_partition(struct k_mem_domain *domain, + uintptr_t addr, size_t size, + k_mem_partition_attr_t attr) +{ + size_t pre_pad_size = addr & (PAGE_SZ - 1); + struct k_mem_partition part = { + .start = addr - pre_pad_size, + .size = ALIGN_UP(pre_pad_size + size, PAGE_SZ), + .attr = attr, + }; + + tr_dbg(&lib_manager_tr, "add %#zx @ %lx partition", part.size, part.start); + return k_mem_domain_add_partition(domain, &part); +} + +static int llext_manager_rm_partition(struct k_mem_domain *domain, + uintptr_t addr, size_t size, + k_mem_partition_attr_t attr) +{ + size_t pre_pad_size = addr & (PAGE_SZ - 1); + struct k_mem_partition part = { + .start = addr - pre_pad_size, + .size = ALIGN_UP(pre_pad_size + size, PAGE_SZ), + .attr = attr, + }; + + tr_dbg(&lib_manager_tr, "remove %#zx @ %lx partition", part.size, part.start); + return k_mem_domain_remove_partition(domain, &part); +} + +int llext_manager_add_domain(const uint32_t component_id, struct k_mem_domain *domain) +{ + const uint32_t module_id = IPC4_MOD_ID(component_id); + struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); + const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); + const unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index); + struct lib_manager_module *mctx = ctx->mod + mod_idx; + const struct llext *ext = mctx->llext; + const struct llext_loader *ldr = &mctx->ebl->loader; + + /* Executable code (.text) */ + uintptr_t va_base_text = mctx->segment[LIB_MANAGER_TEXT].addr; + size_t text_size = mctx->segment[LIB_MANAGER_TEXT].size; + + /* Read-only data (.rodata and others) */ + uintptr_t va_base_rodata = mctx->segment[LIB_MANAGER_RODATA].addr; + size_t rodata_size = mctx->segment[LIB_MANAGER_RODATA].size; + + /* Writable data (.data, .bss and others) */ + uintptr_t va_base_data = mctx->segment[LIB_MANAGER_DATA].addr; + size_t data_size = mctx->segment[LIB_MANAGER_DATA].size; + + int ret = llext_manager_add_partition(domain, va_base_text, text_size, + K_MEM_PARTITION_P_RX_U_RX); + + if (ret < 0) + return ret; + + if (rodata_size) { + ret = llext_manager_add_partition(domain, va_base_rodata, rodata_size, + K_MEM_PARTITION_P_RO_U_RO); + if (ret < 0) + goto e_text; + } + + if (data_size) { + ret = llext_manager_add_partition(domain, va_base_data, data_size, + K_MEM_PARTITION_P_RW_U_RW); + if (ret < 0) + goto e_rodata; + } + + elf_shdr_t shdr_cold, shdr_coldrodata; + bool rodata = false, text = false; + const void *rodata_addr = NULL, *text_addr = NULL; + size_t text_offset = 0, rodata_offset = 0; + + shdr_cold.sh_size = 0; + shdr_coldrodata.sh_size = 0; + + ret = llext_get_section_header((struct llext_loader *)ldr, (struct llext *)ext, + ".cold", &shdr_cold); + if (ret < 0) + tr_warn(&lib_manager_tr, "couldn't get .cold header"); + else + llext_get_region_info(ldr, ext, LLEXT_MEM_TEXT, NULL, &text_addr, NULL); + + ret = llext_get_section_header((struct llext_loader *)ldr, (struct llext *)ext, + ".coldrodata", &shdr_coldrodata); + if (ret < 0) + tr_warn(&lib_manager_tr, "couldn't get .coldrodata header"); + else + llext_get_region_info(ldr, ext, LLEXT_MEM_RODATA, NULL, &rodata_addr, NULL); + + for (unsigned int i = 0; i < llext_section_count(ext) && (!rodata || !text); i++) { + const elf_shdr_t *shdr; + enum llext_mem s_region = LLEXT_MEM_COUNT; + size_t s_offset = 0; + + ret = llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset); + if (ret < 0) + continue; + + switch (s_region) { + case LLEXT_MEM_TEXT: + if (shdr_cold.sh_size && + shdr->sh_name == shdr_cold.sh_name && + shdr->sh_offset == shdr_cold.sh_offset && !text) { + text = true; + text_offset = s_offset; + } + break; + case LLEXT_MEM_RODATA: + if (shdr_coldrodata.sh_size && + shdr->sh_name == shdr_coldrodata.sh_name && + shdr->sh_offset == shdr_coldrodata.sh_offset && !rodata) { + rodata = true; + rodata_offset = s_offset; + } + break; + default: + break; + } + } + + if (text) { + tr_dbg(&lib_manager_tr, ".cold %#x @ %#lx", + shdr_cold.sh_size, (uintptr_t)text_addr + text_offset); + ret = llext_manager_add_partition(domain, (uintptr_t)text_addr + text_offset, + shdr_cold.sh_size, + K_MEM_PARTITION_P_RX_U_RX); + if (ret < 0) + goto e_data; + mctx->segment[LIB_MANAGER_COLD].addr = (uintptr_t)text_addr + text_offset; + mctx->segment[LIB_MANAGER_COLD].size = shdr_cold.sh_size; + } + + if (rodata) { + tr_dbg(&lib_manager_tr, ".coldrodata %#x @ %#lx", + shdr_coldrodata.sh_size, (uintptr_t)rodata_addr + rodata_offset); + ret = llext_manager_add_partition(domain, (uintptr_t)rodata_addr + rodata_offset, + shdr_coldrodata.sh_size, + K_MEM_PARTITION_P_RO_U_RO); + if (ret < 0) + goto e_cold; + mctx->segment[LIB_MANAGER_COLDRODATA].addr = (uintptr_t)rodata_addr + rodata_offset; + mctx->segment[LIB_MANAGER_COLDRODATA].size = shdr_coldrodata.sh_size; + } + + return 0; + +e_cold: + llext_manager_rm_partition(domain, (uintptr_t)text_addr + text_offset, shdr_cold.sh_size, + K_MEM_PARTITION_P_RX_U_RX); + mctx->segment[LIB_MANAGER_COLD].addr = 0; + mctx->segment[LIB_MANAGER_COLD].size = 0; +e_data: + llext_manager_rm_partition(domain, va_base_data, data_size, K_MEM_PARTITION_P_RW_U_RW); +e_rodata: + llext_manager_rm_partition(domain, va_base_rodata, rodata_size, K_MEM_PARTITION_P_RO_U_RO); +e_text: + llext_manager_rm_partition(domain, va_base_text, text_size, K_MEM_PARTITION_P_RX_U_RX); + return ret; +} + +int llext_manager_rm_domain(const uint32_t component_id, struct k_mem_domain *domain) +{ + const uint32_t module_id = IPC4_MOD_ID(component_id); + struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); + const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); + const unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index); + struct lib_manager_module *mctx = ctx->mod + mod_idx; + + /* Executable code (.text) */ + uintptr_t va_base_text = mctx->segment[LIB_MANAGER_TEXT].addr; + size_t text_size = mctx->segment[LIB_MANAGER_TEXT].size; + + /* Read-only data (.rodata and others) */ + uintptr_t va_base_rodata = mctx->segment[LIB_MANAGER_RODATA].addr; + size_t rodata_size = mctx->segment[LIB_MANAGER_RODATA].size; + + /* Writable data (.data, .bss and others) */ + uintptr_t va_base_data = mctx->segment[LIB_MANAGER_DATA].addr; + size_t data_size = mctx->segment[LIB_MANAGER_DATA].size; + + int err, ret = llext_manager_rm_partition(domain, va_base_text, text_size, + K_MEM_PARTITION_P_RX_U_RX); + + if (ret < 0) + tr_err(&lib_manager_tr, "failed to remove .text memory partition: %d", ret); + + if (rodata_size) { + err = llext_manager_rm_partition(domain, va_base_rodata, rodata_size, + K_MEM_PARTITION_P_RO_U_RO); + if (err < 0) { + tr_err(&lib_manager_tr, "failed to remove .rodata memory partition: %d", + err); + if (!ret) + ret = err; + } + } + + if (data_size) { + err = llext_manager_rm_partition(domain, va_base_data, data_size, + K_MEM_PARTITION_P_RW_U_RW); + if (err < 0) { + tr_err(&lib_manager_tr, "failed to remove .data memory partition: %d", err); + if (!ret) + ret = err; + } + } + + if (mctx->segment[LIB_MANAGER_COLD].addr) { + err = llext_manager_rm_partition(domain, + mctx->segment[LIB_MANAGER_COLD].addr, + mctx->segment[LIB_MANAGER_COLD].size, + K_MEM_PARTITION_P_RX_U_RX); + if (err < 0) { + tr_err(&lib_manager_tr, "failed to remove .cold memory partition: %d", err); + if (!ret) + ret = err; + } + } + + if (mctx->segment[LIB_MANAGER_COLDRODATA].addr) { + err = llext_manager_rm_partition(domain, + mctx->segment[LIB_MANAGER_COLDRODATA].addr, + mctx->segment[LIB_MANAGER_COLDRODATA].size, + K_MEM_PARTITION_P_RO_U_RO); + if (err < 0) { + tr_err(&lib_manager_tr, + "failed to remove .coldrodata memory partition: %d", err); + if (!ret) + ret = err; + } + } + + return ret; +} +#endif + int llext_manager_free_module(const uint32_t component_id) { const uint32_t module_id = IPC4_MOD_ID(component_id); diff --git a/src/library_manager/llext_manager_dram.c b/src/library_manager/llext_manager_dram.c index 9c134a3fcd81..25c00f47b4e1 100644 --- a/src/library_manager/llext_manager_dram.c +++ b/src/library_manager/llext_manager_dram.c @@ -23,6 +23,7 @@ struct lib_manager_dram_storage { struct llext_elf_sect_map *sect; struct llext_symbol *sym; unsigned int n_llext; + unsigned int n_mod; }; /* @@ -147,6 +148,8 @@ int llext_manager_store_to_dram(void) } lib_manager_dram.n_llext = n_llext; + lib_manager_dram.n_mod = n_mod; + /* Make sure, that the data is actually in the DRAM, not just in data cache */ dcache_writeback_region((__sparse_force void __sparse_cache *)&lib_manager_dram, sizeof(lib_manager_dram)); @@ -162,26 +165,33 @@ int llext_manager_restore_from_dram(void) struct ext_library *_ext_lib = ext_lib_get(); unsigned int i, j, k, n_mod, n_llext, n_sect, n_sym; + struct llext_loader **ldr; + struct llext **llext; - if (!lib_manager_dram.n_llext || !lib_manager_dram.ctx) { + if (!lib_manager_dram.n_mod || !lib_manager_dram.ctx) { tr_dbg(&lib_manager_tr, "No modules saved"); dcache_writeback_region((__sparse_force void __sparse_cache *)&lib_manager_dram, sizeof(lib_manager_dram)); return 0; } - /* arrays of pointers for llext_restore() */ - void **ptr_array = rmalloc(SOF_MEM_FLAG_KERNEL, - sizeof(*ptr_array) * lib_manager_dram.n_llext * 2); - - if (!ptr_array) - return -ENOMEM; - - struct llext_loader **ldr = (struct llext_loader **)ptr_array; - struct llext **llext = (struct llext **)(ptr_array + lib_manager_dram.n_llext); - *_ext_lib = lib_manager_dram.ext_lib; + if (lib_manager_dram.n_llext) { + /* arrays of pointers for llext_restore() */ + void **ptr_array = rmalloc(SOF_MEM_FLAG_KERNEL, + sizeof(*ptr_array) * lib_manager_dram.n_llext * 2); + + if (!ptr_array) + return -ENOMEM; + + ldr = (struct llext_loader **)ptr_array; + llext = (struct llext **)(ptr_array + lib_manager_dram.n_llext); + } else { + ldr = NULL; + llext = NULL; + } + /* The external loop walks all the libraries */ for (i = 0, j = 0, n_mod = 0, n_llext = 0, n_sect = 0, n_sym = 0; i < ARRAY_SIZE(_ext_lib->desc); i++) { @@ -262,26 +272,28 @@ int llext_manager_restore_from_dram(void) _ext_lib->desc[i] = ctx; } - /* Let Zephyr restore extensions and its own internal bookkeeping */ - int ret = llext_restore(llext, ldr, lib_manager_dram.n_llext); + if (lib_manager_dram.n_llext) { + /* Let Zephyr restore extensions and its own internal bookkeeping */ + int ret = llext_restore(llext, ldr, lib_manager_dram.n_llext); - if (ret < 0) { - tr_err(&lib_manager_tr, "Zephyr failed to restore: %d", ret); - goto nomem; - } + if (ret < 0) { + tr_err(&lib_manager_tr, "Zephyr failed to restore: %d", ret); + goto nomem; + } - /* Rewrite to correct LLEXT pointers, created by Zephyr */ - for (i = 0, n_llext = 0; i < ARRAY_SIZE(_ext_lib->desc); i++) { - struct lib_manager_mod_ctx *ctx = _ext_lib->desc[i]; + /* Rewrite to correct LLEXT pointers, created by Zephyr */ + for (i = 0, n_llext = 0; i < ARRAY_SIZE(_ext_lib->desc); i++) { + struct lib_manager_mod_ctx *ctx = _ext_lib->desc[i]; - if (!ctx) - continue; + if (!ctx) + continue; - struct lib_manager_module *mod = ctx->mod; + struct lib_manager_module *mod = ctx->mod; - for (k = 0; k < ctx->n_mod; k++) { - if (mod[k].llext) - mod[k].llext = llext[n_llext++]; + for (k = 0; k < ctx->n_mod; k++) { + if (mod[k].llext) + mod[k].llext = llext[n_llext++]; + } } } diff --git a/src/math/Kconfig b/src/math/Kconfig index ebab5dd076de..a513f88799fc 100644 --- a/src/math/Kconfig +++ b/src/math/Kconfig @@ -102,6 +102,15 @@ config MATH_FFT Enable Fast Fourier Transform library, this should not be selected directly, please select it from other audio components where need it. +config MATH_FFT_MULTI + bool "FFT library for some non-power-of-two sizes" + depends on MATH_FFT + default n + help + Enable Fast Fourier Transform library for e.g. sizes 1536 and 3072, + this should not be selected directly, please select it from other + audio components where need it. + menu "Supported FFT word lengths" visible if MATH_FFT diff --git a/src/math/auditory/auditory.c b/src/math/auditory/auditory.c index dbfe47b1699c..57641c46aa5a 100644 --- a/src/math/auditory/auditory.c +++ b/src/math/auditory/auditory.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -85,7 +86,7 @@ int16_t psy_mel_to_hz(int16_t mel) return hz; } -int psy_get_mel_filterbank(struct psy_mel_filterbank *fb) +int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *fb) { int32_t up_slope; int32_t down_slope; @@ -200,8 +201,7 @@ int psy_get_mel_filterbank(struct psy_mel_filterbank *fb) } fb->data_length = &fb->scratch_data2[base_idx] - &fb->scratch_data2[0]; - fb->data = rzalloc(SOF_MEM_FLAG_USER, - sizeof(int16_t) * fb->data_length); + fb->data = mod_zalloc(mod, sizeof(int16_t) * fb->data_length); if (!fb->data) return -ENOMEM; @@ -210,3 +210,8 @@ int psy_get_mel_filterbank(struct psy_mel_filterbank *fb) fb->scratch_data2, sizeof(int16_t) * fb->data_length); return 0; } + +int mod_psy_free_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb) +{ + return mod_free(mod, mel_fb->data); +} diff --git a/src/math/dct.c b/src/math/dct.c index 15d23b67c7f9..de27cab4471e 100644 --- a/src/math/dct.c +++ b/src/math/dct.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -31,7 +32,7 @@ * multiply with the returned matrix. * \param[in,out] dct In input provide DCT type and size, in output the DCT matrix */ -int dct_initialize_16(struct dct_plan_16 *dct) +int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct) { int16_t dct_val; int32_t arg; @@ -51,7 +52,7 @@ int dct_initialize_16(struct dct_plan_16 *dct) if (dct->num_in > DCT_MATRIX_SIZE_MAX || dct->num_out > DCT_MATRIX_SIZE_MAX) return -EINVAL; - dct->matrix = mat_matrix_alloc_16b(dct->num_in, dct->num_out, 15); + dct->matrix = mod_mat_matrix_alloc_16b(mod, dct->num_in, dct->num_out, 15); if (!dct->matrix) return -ENOMEM; @@ -77,3 +78,8 @@ int dct_initialize_16(struct dct_plan_16 *dct) return 0; } + +int mod_dct_free_16(struct processing_module *mod, struct dct_plan_16 *dct) +{ + return mod_free(mod, dct->matrix); +} diff --git a/src/math/fft/CMakeLists.txt b/src/math/fft/CMakeLists.txt index 82b8aee77b4d..968c9ad38ac8 100644 --- a/src/math/fft/CMakeLists.txt +++ b/src/math/fft/CMakeLists.txt @@ -10,6 +10,10 @@ if(CONFIG_MATH_32BIT_FFT) list(APPEND base_files fft_32.c fft_32_hifi3.c) endif() +if(CONFIG_MATH_FFT_MULTI) + list(APPEND base_files fft_multi.c) +endif() + is_zephyr(zephyr) if(zephyr) ### Zephyr ### diff --git a/src/math/fft/fft_32.c b/src/math/fft/fft_32.c index 3806f37675b8..25dc71f57e2e 100644 --- a/src/math/fft/fft_32.c +++ b/src/math/fft/fft_32.c @@ -10,55 +10,13 @@ #include #include +#include + #ifdef FFT_GENERIC #include -/* - * These helpers are optimized for FFT calculation only. - * e.g. _add/sub() assume the output won't be saturate so no check needed, - * and _mul() assumes Q1.31 * Q1.31 so the output will be shifted to be Q1.31. - */ - -static inline void icomplex32_add(const struct icomplex32 *in1, const struct icomplex32 *in2, - struct icomplex32 *out) -{ - out->real = in1->real + in2->real; - out->imag = in1->imag + in2->imag; -} - -static inline void icomplex32_sub(const struct icomplex32 *in1, const struct icomplex32 *in2, - struct icomplex32 *out) -{ - out->real = in1->real - in2->real; - out->imag = in1->imag - in2->imag; -} +#include "fft_32.h" -static inline void icomplex32_mul(const struct icomplex32 *in1, const struct icomplex32 *in2, - struct icomplex32 *out) -{ - out->real = ((int64_t)in1->real * in2->real - (int64_t)in1->imag * in2->imag) >> 31; - out->imag = ((int64_t)in1->real * in2->imag + (int64_t)in1->imag * in2->real) >> 31; -} - -/* complex conjugate */ -static inline void icomplex32_conj(struct icomplex32 *comp) -{ - comp->imag = SATP_INT32((int64_t)-1 * comp->imag); -} - -/* shift a complex n bits, n > 0: left shift, n < 0: right shift */ -static inline void icomplex32_shift(const struct icomplex32 *input, int32_t n, - struct icomplex32 *output) -{ - if (n > 0) { - /* need saturation handling */ - output->real = SATP_INT32(SATM_INT32((int64_t)input->real << n)); - output->imag = SATP_INT32(SATM_INT32((int64_t)input->imag << n)); - } else { - output->real = input->real >> -n; - output->imag = input->imag >> -n; - } -} /** * \brief Execute the 32-bits Fast Fourier Transform (FFT) or Inverse FFT (IFFT) @@ -97,7 +55,7 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) } /* step 1: re-arrange input in bit reverse order, and shrink the level to avoid overflow */ - for (i = 1; i < plan->size; ++i) + for (i = 0; i < plan->size; ++i) icomplex32_shift(&inb[i], -(plan->len), &outb[plan->bit_reverse_idx[i]]); /* step 2: loop to do FFT transform in smaller size */ @@ -133,9 +91,11 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) * for Q1.31 format. Instead, we need to multiply N to compensate * the shrink we did in the FFT transform. */ - for (i = 0; i < plan->size; i++) + for (i = 0; i < plan->size; i++) { + icomplex32_conj(&outb[i]); icomplex32_shift(&outb[i], plan->len, &outb[i]); + } } } -#endif +#endif /* FFT_GENERIC */ diff --git a/src/math/fft/fft_32.h b/src/math/fft/fft_32.h new file mode 100644 index 000000000000..92a3131b5189 --- /dev/null +++ b/src/math/fft/fft_32.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020-2025 Intel Corporation. All rights reserved. +// +// Author: Amery Song +// Keyon Jie + +#include +#include +#include + +/* + * These helpers are optimized for FFT calculation only. + * e.g. _add/sub() assume the output won't be saturate so no check needed, + * and _mul() assumes Q1.31 * Q1.31 so the output will be shifted to be Q1.31. + */ + +static inline void icomplex32_add(const struct icomplex32 *in1, const struct icomplex32 *in2, + struct icomplex32 *out) +{ + out->real = in1->real + in2->real; + out->imag = in1->imag + in2->imag; +} + +static inline void icomplex32_adds(const struct icomplex32 *in1, const struct icomplex32 *in2, + struct icomplex32 *out) +{ + out->real = sat_int32((int64_t)in1->real + in2->real); + out->imag = sat_int32((int64_t)in1->imag + in2->imag); +} + +static inline void icomplex32_sub(const struct icomplex32 *in1, const struct icomplex32 *in2, + struct icomplex32 *out) +{ + out->real = in1->real - in2->real; + out->imag = in1->imag - in2->imag; +} + +static inline void icomplex32_mul(const struct icomplex32 *in1, const struct icomplex32 *in2, + struct icomplex32 *out) +{ + out->real = ((int64_t)in1->real * in2->real - (int64_t)in1->imag * in2->imag) >> 31; + out->imag = ((int64_t)in1->real * in2->imag + (int64_t)in1->imag * in2->real) >> 31; +} + +/* complex conjugate */ +static inline void icomplex32_conj(struct icomplex32 *comp) +{ + comp->imag = SATP_INT32((int64_t)-1 * comp->imag); +} + +/* shift a complex n bits, n > 0: left shift, n < 0: right shift */ +static inline void icomplex32_shift(const struct icomplex32 *input, int32_t n, + struct icomplex32 *output) +{ + if (n > 0) { + /* need saturation handling */ + output->real = SATP_INT32(SATM_INT32((int64_t)input->real << n)); + output->imag = SATP_INT32(SATM_INT32((int64_t)input->imag << n)); + } else { + output->real = input->real >> -n; + output->imag = input->imag >> -n; + } +} diff --git a/src/math/fft/fft_32_hifi3.c b/src/math/fft/fft_32_hifi3.c index 91cd18b6a3ed..1ca88c48268d 100644 --- a/src/math/fft/fft_32_hifi3.c +++ b/src/math/fft/fft_32_hifi3.c @@ -15,21 +15,17 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) { - struct icomplex32 tmp1; - ae_int32x2 *inx; - ae_int32x2 *out; - ae_int32x2 *outtop; - ae_int32x2 *outbottom; - ae_int32x2 *outx; + ae_int64 res, res1; ae_int32x2 sample; ae_int32x2 sample1; ae_int32x2 sample2; - ae_int64 res, res1; + ae_int32x2 *inx = (ae_int32x2 *)plan->inb32; + ae_int32x2 *outx = (ae_int32x2 *)plan->outb32; + ae_int32x2 *outtop; + ae_int32x2 *outbottom; + uint16_t *idx = &plan->bit_reverse_idx[0]; int depth, top, bottom, index; int i, j, k, m, n; - ae_int32 *in; - ae_valign inu = AE_ZALIGN64(); - ae_valign outu = AE_ZALIGN64(); int size = plan->size; int len = plan->len; @@ -39,29 +35,25 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) if (!plan->inb32 || !plan->outb32) return; - inx = (ae_int32x2 *)plan->inb32 + 1; - outx = (ae_int32x2 *)plan->outb32; - /* convert to complex conjugate for ifft */ + /* step 1: re-arrange input in bit reverse order, and shrink the level to avoid overflow */ if (ifft) { - in = (ae_int32 *)&plan->inb32->imag; - for (i = 0; i < size; i++) { - AE_L32_IP(sample, in, 0); - sample = AE_NEG32S(sample); - AE_S32_L_IP(sample, in, sizeof(struct icomplex32)); + /* convert to complex conjugate for ifft */ + for (i = 0; i < size; ++i) { + AE_L32X2_IP(sample, inx, sizeof(ae_int32x2)); + sample = AE_SRAA32S(sample, len); + sample1 = AE_NEG32S(sample); + sample = AE_SEL32_HL(sample, sample1); + AE_S32X2_X(sample, outx, idx[i] * sizeof(ae_int32x2)); + } + } else { + for (i = 0; i < size; ++i) { + AE_L32X2_IP(sample, inx, sizeof(ae_int32x2)); + sample = AE_SRAA32S(sample, len); + AE_S32X2_X(sample, outx, idx[i] * sizeof(ae_int32x2)); } } - /* step 1: re-arrange input in bit reverse order, and shrink the level to avoid overflow */ - inu = AE_LA64_PP(inx); - for (i = 1; i < size; ++i) { - AE_LA32X2_IP(sample, inu, inx); - sample = AE_SRAA32S(sample, len); - out = &outx[plan->bit_reverse_idx[i]]; - AE_SA32X2_IP(sample, outu, out); - } - AE_SA64POS_FP(outu, out); - /* step 2: loop to do FFT transform in smaller size */ for (depth = 1; depth <= len; ++depth) { m = 1 << depth; @@ -75,10 +67,12 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) index = i * j; top = k + j; bottom = top + n; - tmp1.real = twiddle_real_32[index]; - tmp1.imag = twiddle_imag_32[index]; - inx = (ae_int32x2 *)&tmp1; - AE_LA32X2_IP(sample1, inu, inx); + + /* load twiddle factor to sample1 */ + sample1 = twiddle_real_32[index]; + sample2 = twiddle_imag_32[index]; + sample1 = AE_SEL32_LH(sample1, sample2); + /* calculate the accumulator: twiddle * bottom */ sample2 = outx[bottom]; res = AE_MULF32S_HH(sample1, sample2); @@ -86,16 +80,16 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) res1 = AE_MULF32S_HL(sample1, sample2); AE_MULAF32S_LH(res1, sample1, sample2); sample = AE_ROUND32X2F64SSYM(res, res1); - sample1 = outx[top]; /* calculate the top output: top = top + accumulate */ sample2 = AE_ADD32S(sample1, sample); outtop = outx + top; - AE_SA32X2_IP(sample2, outu, outtop); + AE_S32X2_I(sample2, outtop, 0); + /* calculate the bottom output: bottom = top - accumulate */ sample2 = AE_SUB32S(sample1, sample); outbottom = outx + bottom; - AE_SA32X2_IP(sample2, outu, outbottom); + AE_S32X2_I(sample2, outbottom, 0); } } } @@ -105,16 +99,17 @@ void fft_execute_32(struct fft_plan *plan, bool ifft) /* * no need to divide N as it is already done in the input side * for Q1.31 format. Instead, we need to multiply N to compensate - * the shrink we did in the FFT transform. + * the shrink we did in the FFT transform. Also make complex + * conjugate by negating the imaginary part. */ inx = outx; - inu = AE_LA64_PP(inx); for (i = 0; i < size; ++i) { - AE_LA32X2_IP(sample, inu, inx); + AE_L32X2_IP(sample, inx, sizeof(ae_int32x2)); sample = AE_SLAA32S(sample, len); - AE_SA32X2_IP(sample, outu, outx); + sample1 = AE_NEG32S(sample); + sample = AE_SEL32_HL(sample, sample1); + AE_S32X2_IP(sample, outx, sizeof(ae_int32x2)); } - AE_SA64POS_FP(outu, outx); } } #endif diff --git a/src/math/fft/fft_common.c b/src/math/fft/fft_common.c index a2afd09cf127..5ce47acd025a 100644 --- a/src/math/fft/fft_common.c +++ b/src/math/fft/fft_common.c @@ -1,29 +1,46 @@ // SPDX-License-Identifier: BSD-3-Clause // -// Copyright(c) 2020 Intel Corporation. All rights reserved. +// Copyright(c) 2020-2025 Intel Corporation. // // Author: Amery Song // Keyon Jie +#include #include #include +#include +#include #include #include #include +#include "fft_common.h" -struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits) +LOG_MODULE_REGISTER(math_fft, CONFIG_SOF_LOG_LEVEL); +SOF_DEFINE_REG_UUID(math_fft); +DECLARE_TR_CTX(math_fft_tr, SOF_UUID(math_fft_uuid), LOG_LEVEL_INFO); + +struct fft_plan *fft_plan_common_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits) { struct fft_plan *plan; int lim = 1; int len = 0; - int i; - if (!inb || !outb) + if (!inb || !outb) { + comp_cl_err(mod->dev, "NULL input/output buffers."); return NULL; + } - plan = rzalloc(SOF_MEM_FLAG_USER, sizeof(struct fft_plan)); - if (!plan) + if (!is_power_of_2(size)) { + comp_cl_err(mod->dev, "The FFT size must be a power of two."); return NULL; + } + + plan = mod_zalloc(mod, sizeof(struct fft_plan)); + if (!plan) { + comp_cl_err(mod->dev, "Failed to allocate FFT plan."); + return NULL; + } switch (bits) { case 16: @@ -35,7 +52,7 @@ struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits) plan->outb32 = outb; break; default: - rfree(plan); + comp_cl_err(mod->dev, "Invalid word length."); return NULL; } @@ -47,27 +64,50 @@ struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits) plan->size = lim; plan->len = len; + return plan; +} - plan->bit_reverse_idx = rzalloc(SOF_MEM_FLAG_USER, - plan->size * sizeof(uint16_t)); - if (!plan->bit_reverse_idx) { - rfree(plan); +void fft_plan_init_bit_reverse(uint16_t *bit_reverse_idx, int size, int len) +{ + int i; + + /* Set up the bit reverse index. The array will contain the value of + * the index with the bits order reversed. Index can be skipped. + */ + for (i = 1; i < size; ++i) + bit_reverse_idx[i] = (bit_reverse_idx[i >> 1] >> 1) | ((i & 1) << (len - 1)); +} + +struct fft_plan *mod_fft_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits) +{ + struct fft_plan *plan; + + if (size > FFT_SIZE_MAX || size < FFT_SIZE_MIN) { + comp_cl_err(mod->dev, "Invalid FFT size %d", size); return NULL; } - /* set up the bit reverse index */ - for (i = 1; i < plan->size; ++i) - plan->bit_reverse_idx[i] = (plan->bit_reverse_idx[i >> 1] >> 1) | - ((i & 1) << (len - 1)); + plan = fft_plan_common_new(mod, inb, outb, size, bits); + if (!plan) + return NULL; + + plan->bit_reverse_idx = mod_zalloc(mod, plan->size * sizeof(uint16_t)); + if (!plan->bit_reverse_idx) { + comp_cl_err(mod->dev, "Failed to allocate bit reverse table."); + mod_free(mod, plan); + return NULL; + } + fft_plan_init_bit_reverse(plan->bit_reverse_idx, plan->size, plan->len); return plan; } -void fft_plan_free(struct fft_plan *plan) +void mod_fft_plan_free(struct processing_module *mod, struct fft_plan *plan) { if (!plan) return; - rfree(plan->bit_reverse_idx); - rfree(plan); + mod_free(mod, plan->bit_reverse_idx); + mod_free(mod, plan); } diff --git a/src/math/fft/fft_common.h b/src/math/fft/fft_common.h new file mode 100644 index 000000000000..9ea9998073ca --- /dev/null +++ b/src/math/fft/fft_common.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo + +/** + * fft_plan_common_new() - Common FFT prepare function + * @param mod: Pointer to module + * @param inb: Buffer to use for complex input data + * @param outb: Buffer to use for complex output data + * @param size: Size of FFT as number of bins + * @param bits: World length of FFT. Currently only 32 is supported. + * @return Pointer to FFT plan + */ +struct fft_plan *fft_plan_common_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits); + +/** + * fft_plan_init_bit_reverse - Configures a bit reversal lookup vector + * @param bit_reverse_idx: Pointer to array to store bit reverse lookup + * @param size: Size of FFT + * @param len: Power of two value equals FFT size + */ +void fft_plan_init_bit_reverse(uint16_t *bit_reverse_idx, int size, int len); diff --git a/src/math/fft/fft_multi.c b/src/math/fft/fft_multi.c new file mode 100644 index 000000000000..baa404315380 --- /dev/null +++ b/src/math/fft/fft_multi.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. +// +// Author: Seppo Ingalsuo + +#include +#include +#include +#include +#include +#include +#include +#include +#include "fft_common.h" +#include "fft_32.h" + +LOG_MODULE_REGISTER(math_fft_multi, CONFIG_SOF_LOG_LEVEL); +SOF_DEFINE_REG_UUID(math_fft_multi); +DECLARE_TR_CTX(math_fft_multi_tr, SOF_UUID(math_fft_multi_uuid), LOG_LEVEL_INFO); + +/* Constants for size 3 DFT */ +#define DFT3_COEFR -1073741824 /* int32(-0.5 * 2^31) */ +#define DFT3_COEFI 1859775393 /* int32(sqrt(3) / 2 * 2^31) */ +#define DFT3_SCALE 715827883 /* int32(1/3*2^31) */ + +struct fft_multi_plan *mod_fft_multi_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits) +{ + struct fft_multi_plan *plan; + size_t tmp_size; + const int size_div3 = size / 3; + int i; + + if (!inb || !outb) { + comp_cl_err(mod->dev, "Null buffers"); + return NULL; + } + + if (size < FFT_SIZE_MIN) { + comp_cl_err(mod->dev, "Invalid FFT size %d", size); + return NULL; + } + + plan = mod_zalloc(mod, sizeof(struct fft_multi_plan)); + if (!plan) + return NULL; + + if (is_power_of_2(size)) { + plan->num_ffts = 1; + } else if (size_div3 * 3 == size) { + plan->num_ffts = 3; + } else { + comp_cl_err(mod->dev, "Not supported FFT size %d", size); + goto err; + } + + /* Allocate common bit reverse table for all FFT plans */ + plan->total_size = size; + plan->fft_size = size / plan->num_ffts; + if (plan->fft_size > FFT_SIZE_MAX) { + comp_cl_err(mod->dev, "Requested size %d FFT is too large", size); + goto err; + } + + plan->bit_reverse_idx = mod_zalloc(mod, plan->fft_size * sizeof(uint16_t)); + if (!plan->bit_reverse_idx) { + comp_cl_err(mod->dev, "Failed to allocate FFT plan"); + goto err; + } + + switch (bits) { + case 32: + plan->inb32 = inb; + plan->outb32 = outb; + + if (plan->num_ffts > 1) { + /* Allocate input/output buffers for FFTs */ + tmp_size = 2 * plan->num_ffts * plan->fft_size * sizeof(struct icomplex32); + plan->tmp_i32[0] = mod_balloc(mod, tmp_size); + if (!plan->tmp_i32[0]) { + comp_cl_err(mod->dev, "Failed to allocate FFT buffers"); + goto err_free_bit_reverse; + } + + /* Set up buffers */ + plan->tmp_o32[0] = plan->tmp_i32[0] + plan->fft_size; + for (i = 1; i < plan->num_ffts; i++) { + plan->tmp_i32[i] = plan->tmp_o32[i - 1] + plan->fft_size; + plan->tmp_o32[i] = plan->tmp_i32[i] + plan->fft_size; + } + } else { + plan->tmp_i32[0] = inb; + plan->tmp_o32[0] = outb; + } + + for (i = 0; i < plan->num_ffts; i++) { + plan->fft_plan[i] = fft_plan_common_new(mod, + plan->tmp_i32[i], + plan->tmp_o32[i], + plan->fft_size, 32); + if (!plan->fft_plan[i]) + goto err_free_buffer; + + plan->fft_plan[i]->bit_reverse_idx = plan->bit_reverse_idx; + } + break; + default: + comp_cl_err(mod->dev, "Not supported word length %d", bits); + goto err; + } + + /* Set up common bit index reverse table */ + fft_plan_init_bit_reverse(plan->bit_reverse_idx, plan->fft_plan[0]->size, + plan->fft_plan[0]->len); + return plan; + +err_free_buffer: + mod_free(mod, plan->tmp_i32[0]); + +err_free_bit_reverse: + mod_free(mod, plan->bit_reverse_idx); + +err: + mod_free(mod, plan); + return NULL; +} + +void mod_fft_multi_plan_free(struct processing_module *mod, struct fft_multi_plan *plan) +{ + int i; + + if (!plan) + return; + + for (i = 0; i < plan->num_ffts; i++) + mod_free(mod, plan->fft_plan[i]); + + /* If single FFT, the internal buffers were not allocated. */ + if (plan->num_ffts > 1) + mod_free(mod, plan->tmp_i32[0]); + + mod_free(mod, plan->bit_reverse_idx); + mod_free(mod, plan); +} + +void dft3_32(struct icomplex32 *x_in, struct icomplex32 *y) +{ + const struct icomplex32 c0 = {DFT3_COEFR, -DFT3_COEFI}; + const struct icomplex32 c1 = {DFT3_COEFR, DFT3_COEFI}; + struct icomplex32 x[3]; + struct icomplex32 p1, p2, sum; + int i; + + for (i = 0; i < 3; i++) { + x[i].real = Q_MULTSR_32X32((int64_t)x_in[i].real, DFT3_SCALE, 31, 31, 31); + x[i].imag = Q_MULTSR_32X32((int64_t)x_in[i].imag, DFT3_SCALE, 31, 31, 31); + } + + /* + * | 1 1 1 | + * c = | 1 c0 c1 | , x = [ x0 x1 x2 ] + * | 1 c1 c0 | + * + * y(0) = c(0,0) * x(0) + c(1,0) * x(1) + c(2,0) * x(0) + * y(1) = c(0,1) * x(0) + c(1,1) * x(1) + c(2,1) * x(0) + * y(2) = c(0,2) * x(0) + c(1,2) * x(1) + c(2,2) * x(0) + */ + + /* y(0) = 1 * x(0) + 1 * x(1) + 1 * x(2) */ + icomplex32_adds(&x[0], &x[1], &sum); + icomplex32_adds(&x[2], &sum, &y[0]); + + /* y(1) = 1 * x(0) + c0 * x(1) + c1 * x(2) */ + icomplex32_mul(&c0, &x[1], &p1); + icomplex32_mul(&c1, &x[2], &p2); + icomplex32_adds(&p1, &p2, &sum); + icomplex32_adds(&x[0], &sum, &y[1]); + + /* y(2) = 1 * x(0) + c1 * x(1) + c0 * x(2) */ + icomplex32_mul(&c1, &x[1], &p1); + icomplex32_mul(&c0, &x[2], &p2); + icomplex32_adds(&p1, &p2, &sum); + icomplex32_adds(&x[0], &sum, &y[2]); +} + +void fft_multi_execute_32(struct fft_multi_plan *plan, bool ifft) +{ + struct icomplex32 x[FFT_MULTI_COUNT_MAX]; + struct icomplex32 y[FFT_MULTI_COUNT_MAX]; + struct icomplex32 t, c; + int i, j, k, m; + + /* Handle 2^N FFT */ + if (plan->num_ffts == 1) { + memset(plan->outb32, 0, plan->fft_size * sizeof(struct icomplex32)); + fft_execute_32(plan->fft_plan[0], ifft); + return; + } + +#ifdef DEBUG_DUMP_TO_FILE + FILE *fh1 = fopen("debug_fft_multi_int1.txt", "w"); + FILE *fh2 = fopen("debug_fft_multi_int2.txt", "w"); + FILE *fh3 = fopen("debug_fft_multi_twiddle.txt", "w"); + FILE *fh4 = fopen("debug_fft_multi_dft_out.txt", "w"); +#endif + + /* convert to complex conjugate for IFFT */ + if (ifft) { + for (i = 0; i < plan->total_size; i++) + icomplex32_conj(&plan->inb32[i]); + } + + /* Copy input buffers */ + k = 0; + for (i = 0; i < plan->fft_size; i++) + for (j = 0; j < plan->num_ffts; j++) + plan->tmp_i32[j][i] = plan->inb32[k++]; + + /* Clear output buffers and call individual FFTs*/ + for (j = 0; j < plan->num_ffts; j++) { + memset(&plan->tmp_o32[j][0], 0, plan->fft_size * sizeof(struct icomplex32)); + fft_execute_32(plan->fft_plan[j], 0); + } + +#ifdef DEBUG_DUMP_TO_FILE + for (j = 0; j < plan->num_ffts; j++) + for (i = 0; i < plan->fft_size; i++) + fprintf(fh1, "%d %d\n", plan->tmp_o32[j][i].real, plan->tmp_o32[j][i].imag); +#endif + + /* Multiply with twiddle factors */ + m = FFT_MULTI_TWIDDLE_SIZE / 2 / plan->fft_size; + for (j = 1; j < plan->num_ffts; j++) { + for (i = 0; i < plan->fft_size; i++) { + c = plan->tmp_o32[j][i]; + k = j * i * m; + t.real = multi_twiddle_real_32[k]; + t.imag = multi_twiddle_imag_32[k]; + //fprintf(fh3, "%d %d\n", t.real, t.imag); + icomplex32_mul(&t, &c, &plan->tmp_o32[j][i]); + } + } + +#ifdef DEBUG_DUMP_TO_FILE + for (j = 0; j < plan->num_ffts; j++) + for (i = 0; i < plan->fft_size; i++) + fprintf(fh2, "%d %d\n", plan->tmp_o32[j][i].real, plan->tmp_o32[j][i].imag); +#endif + + /* DFT of size 3 */ + j = plan->fft_size; + k = 2 * plan->fft_size; + for (i = 0; i < plan->fft_size; i++) { + x[0] = plan->tmp_o32[0][i]; + x[1] = plan->tmp_o32[1][i]; + x[2] = plan->tmp_o32[2][i]; + dft3_32(x, y); + plan->outb32[i] = y[0]; + plan->outb32[i + j] = y[1]; + plan->outb32[i + k] = y[2]; + } + +#ifdef DEBUG_DUMP_TO_FILE + for (i = 0; i < plan->total_size; i++) + fprintf(fh4, "%d %d\n", plan->outb32[i].real, plan->outb32[i].imag); +#endif + + /* shift back for IFFT */ + + /* TODO: Check if time shift method for IFFT is more efficient or more accurate + * tmp = 1 / N * fft(X); + * x = tmp([1 N:-1:2]) + */ + if (ifft) { + /* + * no need to divide N as it is already done in the input side + * for Q1.31 format. Instead, we need to multiply N to compensate + * the shrink we did in the FFT transform. + */ + for (i = 0; i < plan->total_size; i++) { + /* Need to negate imag part to match reference */ + plan->outb32[i].imag = -plan->outb32[i].imag; + icomplex32_shift(&plan->outb32[i], plan->fft_plan[0]->len, + &plan->outb32[i]); + plan->outb32[i].real = sat_int32((int64_t)plan->outb32[i].real * 3); + plan->outb32[i].imag = sat_int32((int64_t)plan->outb32[i].imag * 3); + } + } + +#ifdef DEBUG_DUMP_TO_FILE + fclose(fh1); fclose(fh2); fclose(fh3); fclose(fh4); +#endif +} diff --git a/src/math/fft/tune/README.md b/src/math/fft/tune/README.md index d0ff5781890e..e753716a8952 100644 --- a/src/math/fft/tune/README.md +++ b/src/math/fft/tune/README.md @@ -7,3 +7,9 @@ octave -q --eval "sof_export_twiddle(32, 'twiddle_32.h', 1024);" octave -q --eval "sof_export_twiddle(16, 'twiddle_16.h', 1024);" cp twiddle_32.h ../../../include/sof/audio/coefficients/fft/ cp twiddle_16.h ../../../include/sof/audio/coefficients/fft/ + +To generate the twiddle factors for the non-power-of-two FFT implementation for max +size 3072 run these shell commands: + +octave -q --eval "sof_export_twiddle(32, 'twiddle_3072_32.h', 2048, 3072, 'FFT_MULTI_TWIDDLE_SIZE', 'multi_twiddle');" +cp twiddle_3072_32.h ../../../include/sof/audio/coefficients/fft/ diff --git a/src/math/fft/tune/sof_export_twiddle.m b/src/math/fft/tune/sof_export_twiddle.m index 48bf069e391f..9e6b1489c8b5 100644 --- a/src/math/fft/tune/sof_export_twiddle.m +++ b/src/math/fft/tune/sof_export_twiddle.m @@ -1,15 +1,18 @@ -% sof_export_twiddle(bits, fn, fft_size_max) +% sof_export_twiddle(bits, fn, fft_size_max, denom, str_size_max, str_var) % % Input % bits - Number of bits for data, 16 or 32 % fn - File name, defaults to twiddle.h % fft_size_max - Number of twiddle factors, defaults to 1024 if omitted +% denom - divide index * 2 * pi by denom instead of fft_size_max, same if omitted +% str_size_max - macro name for values array size, FFT_SIZE_MAX if omitted +% str_var - variable name prefix, twiddle if omitted % SPDX-License-Identifier: BSD-3-Clause % % Copyright (c) 2022, Intel Corporation. All rights reserved. -function sof_export_twiddle(bits, fn, fft_size_max) +function sof_export_twiddle(bits, fn, fft_size_max, denom, str_size_max, str_var) if nargin < 2 fn = 'twiddle.h'; @@ -19,6 +22,18 @@ function sof_export_twiddle(bits, fn, fft_size_max) fft_size_max = 1024; end +if nargin < 4 + denom = fft_size_max; +end + +if nargin < 5 + str_size_max = 'FFT_SIZE_MAX'; +end + +if nargin < 6 + str_var = 'twiddle'; +end + switch bits case 16, qx = 1; @@ -34,8 +49,8 @@ function sof_export_twiddle(bits, fn, fft_size_max) hcaps = upper(hname); i = 0:(fft_size_max - 1); -twiddle_real = cos(i * 2 * pi / fft_size_max); -twiddle_imag = -sin(i * 2 * pi / fft_size_max); +twiddle_real = cos(i * 2 * pi / denom); +twiddle_imag = -sin(i * 2 * pi / denom); year = datestr(now(), 'yyyy'); fh = fopen(fn, 'w'); @@ -48,12 +63,14 @@ function sof_export_twiddle(bits, fn, fft_size_max) fprintf(fh, '#ifndef __INCLUDE_%s_H__\n', hcaps); fprintf(fh, '#define __INCLUDE_%s_H__\n\n', hcaps); fprintf(fh, '#include \n\n'); -fprintf(fh, '#define FFT_SIZE_MAX %d\n\n', fft_size_max); +fprintf(fh, '#define %s\t%d\n\n', str_size_max, fft_size_max); fprintf(fh, '/* in Q1.%d, generated from cos(i * 2 * pi / FFT_SIZE_MAX) */\n', qy); -c_export_int(fh, 'twiddle_real', 'FFT_SIZE_MAX', twiddle_real, qx, qy); +str_real = sprintf('%s_real', str_var); +c_export_int(fh, str_real, str_size_max, twiddle_real, qx, qy); fprintf(fh, '/* in Q1.%d, generated from sin(i * 2 * pi / FFT_SIZE_MAX) */\n', qy); -c_export_int(fh, 'twiddle_imag', 'FFT_SIZE_MAX', twiddle_imag, qx, qy); +str_imag = sprintf('%s_imag', str_var); +c_export_int(fh, str_imag, str_size_max, twiddle_imag, qx, qy); fprintf(fh, '#endif\n'); fclose(fh); diff --git a/src/math/numbers.c b/src/math/numbers.c index b4d6ade10421..df4f822c749a 100644 --- a/src/math/numbers.c +++ b/src/math/numbers.c @@ -15,6 +15,9 @@ #include #include +/* see numbers.h */ +#ifdef USE_SOF_GCD + /* This function returns the greatest common divisor of two numbers * If both parameters are 0, gcd(0, 0) returns 0 * If first parameters is 0 or second parameter is 0, gcd(0, b) returns b @@ -74,6 +77,7 @@ int gcd(int a, int b) return a << k; } EXPORT_SYMBOL(gcd); +#endif /* USE_SOF_GCD */ #if CONFIG_NUMBERS_VECTOR_FIND diff --git a/src/math/power.c b/src/math/power.c index fd120271d160..ff9e5f911d5f 100644 --- a/src/math/power.c +++ b/src/math/power.c @@ -10,6 +10,7 @@ #include #include #include + #include #include #include diff --git a/src/math/trig.c b/src/math/trig.c index 32613d393034..1c1e221a5887 100644 --- a/src/math/trig.c +++ b/src/math/trig.c @@ -13,18 +13,13 @@ #include #include -/* Use a local definition to avoid adding a dependency on */ -#define _M_PI 3.14159265358979323846 /* pi */ +#define CORDIC_SINE_COS_LUT_Q29 652032874 /* deg = 69.586061, int32(1.214505869895220 * 2^29) */ + +#define CORDIC_SINCOS_PIOVERTWO_Q28 421657428 /* int32(pi / 2 * 2^28) */ +#define CORDIC_SINCOS_PI_Q28 843314857 /* int32(pi * 2^28) */ +#define CORDIC_SINCOS_TWOPI_Q28 1686629713 /* int32(2 * pi * 2^28) */ +#define CORDIC_SINCOS_ONEANDHALFPI_Q28 1264972285 /* int32(1.5 * pi * 2^28) */ -/* 652032874 , deg = 69.586061*/ -const int32_t cordic_sine_cos_lut_q29fl = Q_CONVERT_FLOAT(1.214505869895220, 29); -/* 1686629713, deg = 90.000000 */ -const int32_t cordic_sine_cos_piovertwo_q30fl = Q_CONVERT_FLOAT(_M_PI / 2, 30); -/* 421657428 , deg = 90.000000 */ -const int32_t cord_sincos_piovertwo_q28fl = Q_CONVERT_FLOAT(_M_PI / 2, 28); -/* 843314857, deg = 90.000000 */ -const int32_t cord_sincos_piovertwo_q29fl = Q_CONVERT_FLOAT(_M_PI / 2, 29); -/* arc trignometry constant*/ /** * CORDIC-based approximation of sine and cosine * \+----------+----------------------------------------+--------------------+-------------------+ @@ -36,20 +31,25 @@ const int32_t cord_sincos_piovertwo_q29fl = Q_CONVERT_FLOAT(_M_PI / 2, 29); * \|1686629713| Q_CONVERT_FLOAT(1.5707963267341256, 30)| 89.9999999965181| 1.57079632673413 | * \+----------+----------------------------------------+--------------------+-------------------+ */ -/* 379625062, deg = 81.0284683480568475 or round(1.4142135605216026*2^28) */ -const int32_t cord_arcsincos_q28fl = Q_CONVERT_FLOAT(1.4142135605216026 / 2, 28); -/* 1073741824, deg = 57.2957795130823229 or round(1*2^30)*/ -const int32_t cord_arcsincos_q30fl = Q_CONVERT_FLOAT(1.0000000000000000, 30); + +#define CORDIC_ARCSINCOS_SQRT2_DIV4_Q30 379625062 /* int32(sqrt(2) / 4 * 2^30) */ +#define CORDIC_ARCSINCOS_ONE_Q30 1073741824 /* int32(1 * 2^30) */ + /** * CORDIC-based approximation of sine, cosine and complex exponential */ void cordic_approx(int32_t th_rad_fxp, int32_t a_idx, int32_t *sign, int32_t *b_yn, int32_t *xn, int32_t *th_cdc_fxp) { + int32_t direction; + int32_t abs_th; int32_t b_idx; - int32_t xtmp; - int32_t ytmp; - *sign = 1; + int32_t xn_local = CORDIC_SINE_COS_LUT_Q29; + int32_t yn_local = 0; + int32_t xtmp = CORDIC_SINE_COS_LUT_Q29; + int32_t ytmp = 0; + int shift; + /* Addition or subtraction by a multiple of pi/2 is done in the data type * of the input. When the fraction length is 29, then the quantization error * introduced by the addition or subtraction of pi/2 is done with 29 bits of @@ -58,57 +58,46 @@ void cordic_approx(int32_t th_rad_fxp, int32_t a_idx, int32_t *sign, int32_t *b_ * without overflow.Increase of fractionLength makes the addition or * subtraction of a multiple of pi/2 more precise */ - if (th_rad_fxp > cord_sincos_piovertwo_q28fl) { - if ((th_rad_fxp - cord_sincos_piovertwo_q29fl) <= cord_sincos_piovertwo_q28fl) { - th_rad_fxp -= cord_sincos_piovertwo_q29fl; - *sign = -1; - } else { - th_rad_fxp -= cordic_sine_cos_piovertwo_q30fl; - } - } else if (th_rad_fxp < -cord_sincos_piovertwo_q28fl) { - if ((th_rad_fxp + cord_sincos_piovertwo_q29fl) >= -cord_sincos_piovertwo_q28fl) { - th_rad_fxp += cord_sincos_piovertwo_q29fl; - *sign = -1; + abs_th = (th_rad_fxp >= 0) ? th_rad_fxp : -th_rad_fxp; + direction = (th_rad_fxp >= 0) ? 1 : -1; + *sign = 1; + if (abs_th > CORDIC_SINCOS_PIOVERTWO_Q28) { + if (abs_th <= CORDIC_SINCOS_ONEANDHALFPI_Q28) { + th_rad_fxp -= direction * CORDIC_SINCOS_PI_Q28; + *sign = -1; } else { - th_rad_fxp += cordic_sine_cos_piovertwo_q30fl; + th_rad_fxp -= direction * CORDIC_SINCOS_TWOPI_Q28; } } th_rad_fxp <<= 2; - *b_yn = 0; - *xn = cordic_sine_cos_lut_q29fl; - xtmp = cordic_sine_cos_lut_q29fl; - ytmp = 0; /* Calculate the correct coefficient values from rotation angle. * Find difference between the coefficients from the lookup table * and those from the calculation */ for (b_idx = 0; b_idx < a_idx; b_idx++) { - if (th_rad_fxp < 0) { - th_rad_fxp += cordic_lookup[b_idx]; - *xn += ytmp; - *b_yn -= xtmp; - } else { - th_rad_fxp -= cordic_lookup[b_idx]; - *xn -= ytmp; - *b_yn += xtmp; - } - xtmp = *xn >> (b_idx + 1); - ytmp = *b_yn >> (b_idx + 1); + direction = (th_rad_fxp >= 0) ? 1 : -1; + shift = b_idx + 1; + th_rad_fxp -= direction * cordic_lookup[b_idx]; + xn_local -= direction * ytmp; + yn_local += direction * xtmp; + xtmp = xn_local >> shift; + ytmp = yn_local >> shift; } - /* Q2.30 format -sine, cosine*/ + + /* Write back results once */ + *xn = xn_local; + *b_yn = yn_local; *th_cdc_fxp = th_rad_fxp; } EXPORT_SYMBOL(cordic_approx); /** * CORDIC-based approximation for inverse cosine - * Arguments : int32_t cosvalue - * int16_t numiters - * Return Type : int32_t + * cosvalue is Q2.30, return value is angle in Q3.29 format */ -int32_t is_scalar_cordic_acos(int32_t cosvalue, int16_t numiters) +int32_t is_scalar_cordic_acos(int32_t cosvalue, int numiters) { int32_t xdshift; int32_t ydshift; @@ -118,25 +107,22 @@ int32_t is_scalar_cordic_acos(int32_t cosvalue, int16_t numiters) int32_t y = 0; int32_t z = 0; int32_t sign; - int32_t b_i; - int i; + int b_i; int j; - int k; /* Initialize the variables for the cordic iteration * angles less than pi/4, we initialize (x,y) along the x-axis. * angles greater than or equal to pi/4, we initialize (x,y) * along the y-axis. This improves the accuracy of the algorithm * near the edge of the domain of convergence + * + * Note: not pi/4 but sqrt(2)/4 is used as the threshold */ - if ((cosvalue >> 1) < cord_arcsincos_q28fl) { - x = 0; - y = cord_arcsincos_q30fl; + if (cosvalue < CORDIC_ARCSINCOS_SQRT2_DIV4_Q30) { + y = CORDIC_ARCSINCOS_ONE_Q30; z = PI_DIV2_Q3_29; } else { - x = cord_arcsincos_q30fl; - y = 0; - z = 0; + x = CORDIC_ARCSINCOS_ONE_Q30; } /* DCORDIC(Double CORDIC) algorithm */ @@ -144,20 +130,14 @@ int32_t is_scalar_cordic_acos(int32_t cosvalue, int16_t numiters) /* CORDIC method,where the iteration step value changes EVERY time, i.e. on */ /* each iteration, in the double iteration method, the iteration step value */ /* is repeated twice and changes only through one iteration */ - i = numiters - 1; - for (b_i = 0; b_i < i; b_i++) { + for (b_i = 0; b_i < numiters; b_i++) { j = (b_i + 1) << 1; if (j >= 31) j = 31; - if (b_i < 31) - k = b_i; - else - k = 31; - - xshift = x >> k; + xshift = x >> b_i; + yshift = y >> b_i; xdshift = x >> j; - yshift = y >> k; ydshift = y >> j; /* Do nothing if x currently equals the target value. Allowed for * double rotations algorithms, as it is equivalent to rotating by @@ -184,11 +164,9 @@ int32_t is_scalar_cordic_acos(int32_t cosvalue, int16_t numiters) /** * CORDIC-based approximation for inverse sine - * Arguments : int32_t sinvalue - * int16_t numiters - * Return Type : int32_t + * sinvalue is Q2.30, return value is angle in Q2.30 format */ -int32_t is_scalar_cordic_asin(int32_t sinvalue, int16_t numiters) +int32_t is_scalar_cordic_asin(int32_t sinvalue, int numiters) { int32_t xdshift; int32_t ydshift; @@ -198,25 +176,22 @@ int32_t is_scalar_cordic_asin(int32_t sinvalue, int16_t numiters) int32_t y = 0; int32_t z = 0; int32_t sign; - int32_t b_i; - int i; + int b_i; int j; - int k; /* Initialize the variables for the cordic iteration * angles less than pi/4, we initialize (x,y) along the x-axis. * angles greater than or equal to pi/4, we initialize (x,y) * along the y-axis. This improves the accuracy of the algorithm * near the edge of the domain of convergence + * + * Note: Instead of pi/4, sqrt(2)/4 is used as the threshold */ - if ((sinvalue >> 1) > cord_arcsincos_q28fl) { - x = 0; - y = cord_arcsincos_q30fl; + if (sinvalue > CORDIC_ARCSINCOS_SQRT2_DIV4_Q30) { + y = CORDIC_ARCSINCOS_ONE_Q30; z = PI_DIV2_Q3_29; } else { - x = cord_arcsincos_q30fl; - y = 0; - z = 0; + x = CORDIC_ARCSINCOS_ONE_Q30; } /* DCORDIC(Double CORDIC) algorithm */ @@ -224,21 +199,15 @@ int32_t is_scalar_cordic_asin(int32_t sinvalue, int16_t numiters) /* CORDIC method,where the iteration step value changes EVERY time, i.e. on */ /* each iteration, in the double iteration method, the iteration step value */ /* is repeated twice and changes only through one iteration */ - i = numiters - 1; - for (b_i = 0; b_i < i; b_i++) { + for (b_i = 0; b_i < numiters; b_i++) { j = (b_i + 1) << 1; if (j >= 31) j = 31; - if (b_i < 31) - k = b_i; - else - k = 31; - - xshift = x >> k; - xdshift = x >> j; - yshift = y >> k; + xshift = x >> b_i; + yshift = y >> b_i; ydshift = y >> j; + xdshift = x >> j; /* Do nothing if x currently equals the target value. Allowed for * double rotations algorithms, as it is equivalent to rotating by * the same angle in opposite directions sequentially. Accounts for @@ -263,13 +232,9 @@ int32_t is_scalar_cordic_asin(int32_t sinvalue, int16_t numiters) } /** - * approximated complex result - * Arguments : int32_t sign - * int32_t b_yn - * int32_t xn - * enum type - * struct cordic_cmpx - * Return Type : none + * cmpx_cexp() - CORDIC-based approximation of complex exponential e^(j*THETA) + * + * The sine and cosine values are in Q2.30 format from cordic_approx()function. */ void cmpx_cexp(int32_t sign, int32_t b_yn, int32_t xn, cordic_cfg type, struct cordic_cmpx *cexp) { diff --git a/src/math/window.c b/src/math/window.c index 4795112ffc0f..39739ef24be3 100644 --- a/src/math/window.c +++ b/src/math/window.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause // -// Copyright(c) 2022 Intel Corporation. All rights reserved. +// Copyright(c) 2022-2025 Intel Corporation. // // Author: Seppo Ingalsuo @@ -16,6 +16,7 @@ #define WIN_ONE_Q31 INT32_MAX #define WIN_05_Q31 Q_CONVERT_FLOAT(0.5, 31) +#define WIN_PI_Q28 Q_CONVERT_FLOAT(3.1415926536, 28) #define WIN_TWO_PI_Q28 Q_CONVERT_FLOAT(6.2831853072, 28) #define WIN_085_Q31 Q_CONVERT_FLOAT(0.85, 31) @@ -29,12 +30,10 @@ /* Common approximations to match e.g. Octave */ #define WIN_HAMMING_A0_Q30 Q_CONVERT_FLOAT(0.54, 30) #define WIN_HAMMING_A1_Q30 Q_CONVERT_FLOAT(0.46, 30) +#define WIN_HAMMING_A0_Q31 Q_CONVERT_FLOAT(0.54, 31) +#define WIN_HAMMING_A1_Q31 Q_CONVERT_FLOAT(0.46, 31) -/** - * \brief Return rectangular window, simply values of one - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector - */ +/* Rectangular window */ void win_rectangular_16b(int16_t *win, int length) { int i; @@ -43,14 +42,15 @@ void win_rectangular_16b(int16_t *win, int length) win[i] = WIN_ONE_Q15; } -/** - * \brief Calculate Blackman window function, reference - * https://en.wikipedia.org/wiki/Window_function#Blackman_window +void win_rectangular_32b(int32_t *win, int length) +{ + int i; - * \param[in,out] win Output vector with coefficients - * \param[in] length Length of coefficients vector - * \param[in] a0 Parameter for window shape, use e.g. 0.42 as Q1.15 - */ + for (i = 0; i < length; i++) + win[i] = WIN_ONE_Q31; +} + +/* Blackman window */ void win_blackman_16b(int16_t win[], int length, int16_t a0) { const int32_t a1 = Q_CONVERT_FLOAT(0.5, 31); @@ -77,6 +77,64 @@ void win_blackman_16b(int16_t win[], int length, int16_t a0) } } +void win_blackman_32b(int32_t win[], int length, int32_t a0) +{ + const int32_t a1 = Q_CONVERT_FLOAT(0.5, 31); + int64_t val; + int32_t inv_length; + int32_t a; + int16_t alpha; + int32_t a2; + int32_t c1; + int32_t c2; + int n; + + alpha = WIN_ONE_Q31 - 2 * a0; /* Q1.31 */ + a2 = alpha << 15; /* Divided by 2 in Q1.31 */ + a = WIN_TWO_PI_Q28 / (length - 1); /* Q4.28 */ + inv_length = WIN_ONE_Q31 / length; + + for (n = 0; n < length; n++) { + c1 = cos_fixed_32b(a * n); + c2 = cos_fixed_32b(2 * n * Q_MULTSR_32X32((int64_t)a, inv_length, 28, 31, 28)); + val = a0 - Q_MULTSR_32X32((int64_t)a1, c1, 31, 31, 31) + + Q_MULTSR_32X32((int64_t)a2, c2, 31, 31, 31); + win[n] = sat_int32(val); + } +} + +/* Hann window */ +void win_hann_16b(int16_t win[], int length) +{ + int32_t val; + int32_t a; + int n; + + a = WIN_PI_Q28 / (length - 1); /* Q4.28 */ + for (n = 0; n < length; n++) { + /* Calculate sin(a * n)^2 */ + val = sin_fixed_32b(a * n); /* Q4.28 -> Q1.31 */ + val = Q_MULTSR_32X32((int64_t)val, val, 31, 31, 15); /* Q1.15 */ + win[n] = sat_int16(val); + } +} + +void win_hann_32b(int32_t win[], int length) +{ + int64_t val; + int32_t a; + int n; + + a = WIN_PI_Q28 / (length - 1); /* Q4.28 */ + for (n = 0; n < length; n++) { + /* Calculate sin(a * n)^2 */ + val = sin_fixed_32b(a * n); /* Q4.28 -> Q1.31 */ + val = Q_MULTSR_32X32((int64_t)val, val, 31, 31, 31); /* Q1.31 */ + win[n] = sat_int32(val); + } +} + +/* Hamming window */ void win_hamming_16b(int16_t win[], int length) { int32_t val; @@ -95,6 +153,23 @@ void win_hamming_16b(int16_t win[], int length) } } +void win_hamming_32b(int32_t win[], int length) +{ + int64_t val; + int32_t a; + int n; + + a = WIN_TWO_PI_Q28 / (length - 1); /* Q4.28 */ + for (n = 0; n < length; n++) { + /* Calculate 0.54 - 0.46 * cos(a * n) */ + val = cos_fixed_32b(a * n); /* Q4.28 -> Q1.31 */ + val = Q_MULTSR_32X32((int64_t)val, WIN_HAMMING_A1_Q31, 31, 31, 31); /* Q1.31 */ + val = WIN_HAMMING_A0_Q31 - val; + win[n] = sat_int32(val); + } +} + +/* Povey window */ void win_povey_16b(int16_t win[], int length) { int32_t cos_an; diff --git a/src/platform/Kconfig b/src/platform/Kconfig index ebbe0540b7d4..a8e0addc3b98 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -332,21 +332,30 @@ config MT8196 endchoice -config MAX_CORE_COUNT +# +# For non-Zephyr builds like testbench, cmocka and SOF ALSA plugin, +# set core count separately. +# +if !ZEPHYR_SOF_MODULE + +config MP_MAX_NUM_CPUS int - default 5 if LUNARLAKE || PANTHERLAKE - default 4 if TIGERLAKE || NOVALAKE - default 3 if METEORLAKE - default 3 if WILDCATLAKE default 1 help Maximum number of cores per configuration +endif # !ZEPHYR_SOF_MODULE + +config MAX_CORE_COUNT + int + default MP_MAX_NUM_CPUS + help + Maximum number of cores per configuration + config CORE_COUNT int "Number of cores" - default MP_MAX_NUM_CPUS if KERNEL_BIN_NAME = "zephyr" - default MAX_CORE_COUNT - range 1 MAX_CORE_COUNT + default MP_MAX_NUM_CPUS + range 1 MP_MAX_NUM_CPUS help Number of used cores Lowering available core count could result in lower power consumption diff --git a/src/platform/amd/acp_6_3/lib/clk.c b/src/platform/amd/acp_6_3/lib/clk.c index 5a735d4241fa..f060aafc22c6 100644 --- a/src/platform/amd/acp_6_3/lib/clk.c +++ b/src/platform/amd/acp_6_3/lib/clk.c @@ -191,7 +191,7 @@ void acp_change_clock_notify(uint32_t clock_freq) acp_6_3_get_boot_ref_clock(&boot_ref_clk); - tr_info(&acp_clk_tr, "acp_change_clock_notify clock_freq : %d clock_type : %d", + tr_info(&acp_clk_tr, "clock_freq : %d clock_type : %d", clock_freq, clock_type); fraction_val = (float)(clock_freq / (float)1000000.0f); @@ -212,7 +212,7 @@ void acp_change_clock_notify(uint32_t clock_freq) bypass_cntl.bitfields.CLK1_BYPASS_DIV = 0xF; } else { did = (float)(boot_ref_clk / (float)fraction_val); - tr_info(&acp_clk_tr, "acp_change_clock_notify CLK Divider : %d boot_ref_clk : %d\n", + tr_info(&acp_clk_tr, "CLK Divider : %d boot_ref_clk : %d\n", (uint32_t)(did * 100), (uint32_t)boot_ref_clk); if (did > 62.0f) { @@ -251,7 +251,7 @@ void acp_change_clock_notify(uint32_t clock_freq) do { dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK1_DFS_STATUS, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK1 CLK1_DIVIDER : %d dfsstatus %d ", + tr_info(&acp_clk_tr, "ACLK1 CLK1_DIVIDER : %d dfsstatus %d ", dfs_cntl.u32all, dfs_status.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); updated_clk = acp_reg_read_via_smn(CLK5_CLK1_CURRENT_CNT, sizeof(int)); @@ -268,7 +268,7 @@ void acp_change_clock_notify(uint32_t clock_freq) dfs_cntl.u32all = acp_reg_read_via_smn(CLK5_CLK1_DFS_CNTL, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK2 CLK1_DIVIDER:%d dfsstatus %d ", + tr_info(&acp_clk_tr, "ACLK2 CLK1_DIVIDER:%d dfsstatus %d ", dfs_cntl.u32all, dfs_status.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); } @@ -281,7 +281,7 @@ void acp_change_clock_notify(uint32_t clock_freq) do { dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK0_DFS_STATUS, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify SCLK CLK1_DIVIDER: %d", + tr_info(&acp_clk_tr, "SCLK CLK1_DIVIDER: %d", dfs_cntl.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); diff --git a/src/platform/amd/acp_7_0/lib/clk.c b/src/platform/amd/acp_7_0/lib/clk.c index 89fa787db1c3..12c710155260 100644 --- a/src/platform/amd/acp_7_0/lib/clk.c +++ b/src/platform/amd/acp_7_0/lib/clk.c @@ -183,7 +183,7 @@ void acp_change_clock_notify(uint32_t clock_freq) acp_7_0_get_boot_ref_clock(&boot_ref_clk); - tr_info(&acp_clk_tr, "acp_change_clock_notify clock_freq : %d clock_type : %d", + tr_info(&acp_clk_tr, "clock_freq : %d clock_type : %d", clock_freq, clock_type); fraction_val = (float)(clock_freq / 1000000.0f); @@ -204,7 +204,7 @@ void acp_change_clock_notify(uint32_t clock_freq) bypass_cntl.bitfields.CLK1_BYPASS_DIV = 0xF; } else { did = boot_ref_clk / fraction_val; - tr_info(&acp_clk_tr, "acp_change_clock_notify CLK Divider : %d boot_ref_clk : %d\n", + tr_info(&acp_clk_tr, "CLK Divider : %d boot_ref_clk : %d\n", (uint32_t)(did * 100), (uint32_t)boot_ref_clk); if (did > 62.0f) { @@ -241,7 +241,7 @@ void acp_change_clock_notify(uint32_t clock_freq) do { dfs_status.u32all = acp_reg_read_via_smn(CLK7_CLK1_DFS_STATUS, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK1 CLK1_DIVIDER : %d dfsstatus %d ", + tr_info(&acp_clk_tr, "ACLK1 CLK1_DIVIDER : %d dfsstatus %d ", dfs_cntl.u32all, dfs_status.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); updated_clk = acp_reg_read_via_smn(CLK7_CLK1_CURRENT_CNT, sizeof(int)); @@ -258,7 +258,7 @@ void acp_change_clock_notify(uint32_t clock_freq) dfs_cntl.u32all = acp_reg_read_via_smn(CLK7_CLK1_DFS_CNTL, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK2 CLK1_DIVIDER:%d dfsstatus %d ", + tr_info(&acp_clk_tr, "ACLK2 CLK1_DIVIDER:%d dfsstatus %d ", dfs_cntl.u32all, dfs_status.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); } @@ -272,7 +272,7 @@ void acp_change_clock_notify(uint32_t clock_freq) do { dfs_status.u32all = acp_reg_read_via_smn(CLK7_CLK0_DFS_STATUS, sizeof(int)); - tr_info(&acp_clk_tr, "acp_change_clock_notify SCLK CLK1_DIVIDER: %d", + tr_info(&acp_clk_tr, "SCLK CLK1_DIVIDER: %d", dfs_cntl.u32all); } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index 366424bae1dd..8a1a7c59c3b5 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -107,9 +107,7 @@ int platform_boot_complete(uint32_t boot_message) return 0; } -static struct pm_notifier pm_state_notifier = { - .state_exit = cpu_notify_state_exit, -}; +static struct pm_notifier pm_state_notifier; /* Runs on the primary core only */ int platform_init(struct sof *sof) @@ -138,6 +136,7 @@ int platform_init(struct sof *sof) return ret; /* register power states exit notifiers */ + pm_state_notifier.state_exit = cpu_notify_state_exit; pm_notifier_register(&pm_state_notifier); /* initialize the host IPC mechanisms */ diff --git a/src/platform/library/lib/alloc.c b/src/platform/library/lib/alloc.c index ec7667b351be..74cb926e4aff 100644 --- a/src/platform/library/lib/alloc.c +++ b/src/platform/library/lib/alloc.c @@ -16,6 +16,11 @@ /* testbench mem alloc definition */ +void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment) +{ + return malloc(bytes); +} + void *rmalloc(uint32_t flags, size_t bytes) { return malloc(bytes); @@ -43,6 +48,17 @@ void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes, return realloc(ptr, bytes); } +void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, + size_t alignment) +{ + return malloc(bytes); +} + +void sof_heap_free(struct k_heap *heap, void *addr) +{ + free(addr); +} + void heap_trace(struct mm_heap *heap, int size) { #if MALLOC_DEBUG @@ -54,3 +70,8 @@ void heap_trace_all(int force) { heap_trace(NULL, 0); } + +struct k_heap *sof_sys_heap_get(void) +{ + return NULL; +} diff --git a/src/platform/mt8186/lib/clk.c b/src/platform/mt8186/lib/clk.c index 555ab83c2a4f..033580a280bf 100644 --- a/src/platform/mt8186/lib/clk.c +++ b/src/platform/mt8186/lib/clk.c @@ -36,7 +36,7 @@ static SHARED_DATA struct clock_info platform_clocks_info[NUM_CLOCKS]; static void clk_dsppll_enable(uint32_t value) { - tr_dbg(&clkdrv_tr, "clk_dsppll_enable: %d\n", value); + tr_dbg(&clkdrv_tr, "%d\n", value); switch (value) { case ADSP_CLK_PLL_300M: @@ -60,7 +60,7 @@ static void clk_dsppll_enable(uint32_t value) static void clk_dsppll_disable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_disable\n"); + tr_dbg(&clkdrv_tr, "entry"); io_reg_update_bits(MTK_ADSPPLL_CON0, MTK_PLL_BASE_EN, 0); wait_delay_us(1); diff --git a/src/platform/mt8188/lib/clk.c b/src/platform/mt8188/lib/clk.c index d11b9fe2317b..f39872fca845 100644 --- a/src/platform/mt8188/lib/clk.c +++ b/src/platform/mt8188/lib/clk.c @@ -36,7 +36,7 @@ static SHARED_DATA struct clock_info platform_clocks_info[NUM_CLOCKS]; static void clk_dsppll_enable(uint32_t value) { - tr_dbg(&clkdrv_tr, "clk_dsppll_enable %d\n", value); + tr_dbg(&clkdrv_tr, "%d\n", value); switch (value) { case ADSP_CLK_PLL_400M: @@ -60,7 +60,7 @@ static void clk_dsppll_enable(uint32_t value) static void clk_dsppll_disable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_disable\n"); + tr_dbg(&clkdrv_tr, "entry"); io_reg_update_bits(MTK_ADSPPLL_CON0, MTK_PLL_EN, 0); wait_delay_us(1); diff --git a/src/platform/mt8195/lib/clk.c b/src/platform/mt8195/lib/clk.c index 3f69c5e2d8f1..1514b9d9307d 100644 --- a/src/platform/mt8195/lib/clk.c +++ b/src/platform/mt8195/lib/clk.c @@ -77,7 +77,7 @@ static inline int dsp_clk_value_convert(int value) static void clk_dsppll_enable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_enable\n"); + tr_dbg(&clkdrv_tr, "entry"); io_reg_update_bits(AUDIODSP_CK_CG, 0x1 << RG_AUDIODSP_SW_CG, 0x0); clk_setl(DSPPLL_CON4, PLL_PWR_ON); @@ -91,7 +91,7 @@ static void clk_dsppll_enable(void) static void clk_dsppll_disable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_disable\n"); + tr_dbg(&clkdrv_tr, "entry"); clk_clrl(DSPPLL_CON0, PLL_EN); wait_delay_us(1); @@ -144,7 +144,7 @@ static int clock_platform_set_cpu_freq(int clock, int freq_idx) if (adsp_clock == adsp_clk_req) return 0; - tr_info(&clkdrv_tr, "clock_platform_set_cpu_freq %d\n", adsp_clk_req); + tr_info(&clkdrv_tr, "%d\n", adsp_clk_req); /* convert res manager value to driver map */ clk_mux = dsp_clk_value_convert(freq_idx); diff --git a/src/platform/mt8365/lib/clk.c b/src/platform/mt8365/lib/clk.c index 80f95ea30708..8101d4fd0f2c 100644 --- a/src/platform/mt8365/lib/clk.c +++ b/src/platform/mt8365/lib/clk.c @@ -79,7 +79,7 @@ static inline int dsp_clk_value_convert(int value) static void clk_dsppll_enable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_enable\n"); + tr_dbg(&clkdrv_tr, "entry"); clk_setl(DSPPLL_CON3, PLL_PWR_ON); wait_delay_us(1); @@ -93,7 +93,7 @@ static void clk_dsppll_enable(void) static void clk_dsppll_disable(void) { - tr_dbg(&clkdrv_tr, "clk_dsppll_disable\n"); + tr_dbg(&clkdrv_tr, "entry"); clk_clrl(DSPPLL_CON0, PLL_BASE_EN); wait_delay_us(1); diff --git a/src/platform/mtk/dai.c b/src/platform/mtk/dai.c index cb6ebc144624..17fbc665dfbe 100644 --- a/src/platform/mtk/dai.c +++ b/src/platform/mtk/dai.c @@ -22,6 +22,9 @@ #elif defined(CONFIG_SOC_MT8196) #define MTK_AFE_BASE 0x1a110000 #define SRAM_CPU_START 0x1a210000 +#elif defined(CONFIG_SOC_MT8365) +#define MTK_AFE_BASE 0x11220000 +#define SRAM_CPU_START 0x1e000000 #else #error Unrecognized device #endif @@ -133,7 +136,7 @@ static void cfg_convert(const struct afe_cfg *src, struct mtk_base_memif_data *d .base = DT_PROP(n, base), \ .end = DT_PROP(n, end), \ .cur = DT_PROP(n, cur), \ - .fs = DT_PROP(n, fs), \ + COND_PROP(n, fs) \ .hd = DT_PROP(n, hd), \ .enable = DT_PROP(n, enable), \ COND_PROP(n, mono) \ @@ -269,6 +272,20 @@ static unsigned int mtk_afe_fs_timing(unsigned int rate) { 192000, 14 }, { 352800, 7 }, { 384000, 3 }, +#elif defined(CONFIG_SOC_MT8365) + { 8000, 0 }, + { 11025, 1 }, + { 12000, 2 }, + { 16000, 4 }, + { 22050, 5 }, + { 24000, 6 }, + { 32000, 8 }, + { 44100, 9 }, + { 48000, 10 }, + { 88200, 11 }, + { 96000, 12 }, + { 176400, 13 }, + { 192000, 14 }, #else { 8000, 0 }, { 11025, 1 }, diff --git a/src/platform/mtk/include/platform/lib/memory.h b/src/platform/mtk/include/platform/lib/memory.h index a84809bf2d48..26806ab394ba 100644 --- a/src/platform/mtk/include/platform/lib/memory.h +++ b/src/platform/mtk/include/platform/lib/memory.h @@ -42,7 +42,7 @@ static inline void *platform_shared_get(void *ptr, int bytes) * validation that the kernel driver interprets the manifest * correctly. Right now we're using the historical addresses. */ -#ifdef CONFIG_SOC_MT8195 +#if defined(CONFIG_SOC_MT8195) || defined(CONFIG_SOC_MT8365) #define MTK_IPC_BASE (DT_REG_ADDR(DT_NODELABEL(dram0)) + 0x800000) #else #define MTK_IPC_BASE (DT_REG_ADDR(DT_NODELABEL(dram0)) + 0x500000) diff --git a/src/platform/mtk/platform.c b/src/platform/mtk/platform.c index 1592c020f7a2..c189af1f0a16 100644 --- a/src/platform/mtk/platform.c +++ b/src/platform/mtk/platform.c @@ -24,12 +24,25 @@ void mtk_dai_init(struct sof *sof); +#ifndef CONFIG_SOC_MT8365 #define MBOX0 DEVICE_DT_GET(DT_INST(0, mediatek_mbox)) #define MBOX1 DEVICE_DT_GET(DT_INST(1, mediatek_mbox)) +#else +#define IPI DEVICE_DT_GET(DT_INST(0, mediatek_ipi)) + +#define MAILBOX_DEBUG_BASE MTK_IPC_WIN_BASE(DEBUG) + +#define SRAM_REG_OP_CPU2DSP 0x8 +#define SRAM_REG_OP_DSP2CPU 0xC + +#define ADSP_IPI_OP_REQ 0x1 +#define ADSP_IPI_OP_RSP 0x2 +#endif /* Use the same UUID as in "ipc-zephyr.c", which is actually an Intel driver */ SOF_DEFINE_REG_UUID(zipc_task); +#ifndef CONFIG_SOC_MT8365 static void mbox_cmd_fn(const struct device *mbox, void *arg) { /* We're in ISR context. This unblocks the IPC task thread, @@ -38,6 +51,7 @@ static void mbox_cmd_fn(const struct device *mbox, void *arg) */ ipc_schedule_process(ipc_get()); } +#endif enum task_state ipc_platform_do_cmd(struct ipc *ipc) { @@ -54,13 +68,23 @@ enum task_state ipc_platform_do_cmd(struct ipc *ipc) void ipc_platform_complete_cmd(struct ipc *ipc) { +#ifndef CONFIG_SOC_MT8365 mtk_adsp_mbox_signal(MBOX0, 1); +#else + *(uint32_t *)(MAILBOX_DEBUG_BASE + SRAM_REG_OP_DSP2CPU) = ADSP_IPI_OP_RSP; + mtk_adsp_ipi_signal(IPI, 1); +#endif } static void mtk_ipc_send(const void *msg, size_t sz) { mailbox_dspbox_write(0, msg, sz); +#ifndef CONFIG_SOC_MT8365 mtk_adsp_mbox_signal(MBOX1, 0); +#else + *(uint32_t *)(MAILBOX_DEBUG_BASE + SRAM_REG_OP_DSP2CPU) = ADSP_IPI_OP_REQ; + mtk_adsp_ipi_signal(IPI, 1); +#endif } int ipc_platform_send_msg(const struct ipc_msg *msg) @@ -75,11 +99,36 @@ int ipc_platform_send_msg(const struct ipc_msg *msg) return 0; } +#ifndef CONFIG_SOC_MT8365 static void mbox_reply_fn(const struct device *mbox, void *arg) { ipc_get()->is_notification_pending = false; } +#else + +static void ipi_handler_fn(const struct device *ipi, void *arg) +{ + uint32_t op; + + op = *(uint32_t *)(MAILBOX_DEBUG_BASE + SRAM_REG_OP_CPU2DSP); + + switch (op) { + case ADSP_IPI_OP_REQ: + /* new message from host */ + ipc_schedule_process(ipc_get()); + break; + case ADSP_IPI_OP_RSP: + /* reply message(done) from host */ + ipc_get()->is_notification_pending = false; + break; + default: + /* do nothing */ + break; + } +} +#endif + /* "Host Page Table" support. The platform is responsible for * providing a buffer into which the IPC layer reads a DMA "page * table" from the host. This isn't really a page table, it's a @@ -114,8 +163,12 @@ int platform_ipc_init(struct ipc *ipc) schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(zipc_task_uuid), &ipc_task_ops, ipc, 0, 0); +#ifndef CONFIG_SOC_MT8365 mtk_adsp_mbox_set_handler(MBOX0, 0, mbox_cmd_fn, NULL); mtk_adsp_mbox_set_handler(MBOX1, 1, mbox_reply_fn, NULL); +#else + mtk_adsp_ipi_set_handler(IPI, 0, ipi_handler_fn, NULL); +#endif return 0; } diff --git a/src/platform/novalake/include/platform/lib/memory.h b/src/platform/novalake/include/platform/lib/memory.h index 19ade62dfb2b..666c4fc9eb89 100644 --- a/src/platform/novalake/include/platform/lib/memory.h +++ b/src/platform/novalake/include/platform/lib/memory.h @@ -56,6 +56,12 @@ */ #define HEAPMEM_SIZE CONFIG_SOF_ZEPHYR_HEAP_SIZE +#if CONFIG_COLD_STORE_EXECUTE_DRAM && \ + (CONFIG_LLEXT_TYPE_ELF_RELOCATABLE || !defined(LL_EXTENSION_BUILD)) +#define __cold __section(".cold") +#define __cold_rodata __section(".coldrodata") +#endif + #endif /* __PLATFORM_LIB_MEMORY_H__ */ #else diff --git a/src/probe/probe.c b/src/probe/probe.c index 339935993ef1..f15ee84f7daf 100644 --- a/src/probe/probe.c +++ b/src/probe/probe.c @@ -80,11 +80,11 @@ struct probe_dma_ext { * Probe main struct */ struct probe_pdata { + struct task dmap_work; /**< probe task */ struct probe_dma_ext ext_dma; /**< extraction DMA */ struct probe_dma_ext inject_dma[CONFIG_PROBE_DMA_MAX]; /**< injection DMA */ struct probe_point probe_points[CONFIG_PROBE_POINTS_MAX]; /**< probe points */ struct probe_data_packet header; /**< data packet header */ - struct task dmap_work; /**< probe task */ }; /** @@ -102,7 +102,7 @@ static int probe_dma_buffer_init(struct probe_dma_buf *buffer, uint32_t size, size, align); if (!buffer->addr) { - tr_err(&pr_tr, "probe_dma_buffer_init(): alloc failed"); + tr_err(&pr_tr, "alloc failed"); return -ENOMEM; } @@ -145,7 +145,7 @@ static int probe_dma_init(struct probe_dma_ext *dma, uint32_t direction) dma->dc.dmac = dma_get(direction, 0, SOF_DMA_DEV_HOST, SOF_DMA_ACCESS_SHARED); if (!dma->dc.dmac) { - tr_err(&pr_tr, "probe_dma_init(): dma->dc.dmac = NULL"); + tr_err(&pr_tr, "dma->dc.dmac = NULL"); return -ENODEV; } dma->dc.dmac->priv_data = &dma->dc.dmac->chan->index; @@ -201,7 +201,7 @@ static int probe_dma_init(struct probe_dma_ext *dma, uint32_t direction) dma->dc.dmac = sof_dma_get(direction, 0, SOF_DMA_DEV_HOST, SOF_DMA_ACCESS_SHARED); if (!dma->dc.dmac) { - tr_err(&pr_tr, "probe_dma_init(): dma->dc.dmac = NULL"); + tr_err(&pr_tr, "dma->dc.dmac = NULL"); return -ENODEV; } @@ -213,7 +213,7 @@ static int probe_dma_init(struct probe_dma_ext *dma, uint32_t direction) channel = dma_request_channel(dma->dc.dmac->z_dev, &channel); if (channel < 0) { - tr_err(&pr_tr, "probe_dma_init(): dma_request_channel() failed"); + tr_err(&pr_tr, "dma_request_channel() failed"); return -EINVAL; } dma->dc.chan = &dma->dc.dmac->chan[channel]; @@ -262,7 +262,7 @@ static int probe_dma_deinit(struct probe_dma_ext *dma) err = dma_stop_legacy(dma->dc.chan); #endif if (err < 0) { - tr_err(&pr_tr, "probe_dma_deinit(): dma_stop() failed"); + tr_err(&pr_tr, "dma_stop() failed"); return err; } #if CONFIG_ZEPHYR_NATIVE_DRIVERS @@ -303,7 +303,7 @@ static enum task_state probe_task(void *data) ©_align); #endif if (err < 0) { - tr_err(&pr_tr, "probe_task(): dma_get_attribute failed."); + tr_err(&pr_tr, "dma_get_attribute failed."); return SOF_TASK_STATE_COMPLETED; } @@ -325,7 +325,7 @@ static enum task_state probe_task(void *data) return SOF_TASK_STATE_RESCHEDULE; if (err < 0) { - tr_err(&pr_tr, "probe_task(): dma_copy_to_host() failed."); + tr_err(&pr_tr, "dma_copy_to_host() failed."); return err; } @@ -357,7 +357,7 @@ static void probe_auto_enable_logs(uint32_t stream_tag) ret = probe_point_add(1, &log_point); if (ret) - tr_err(&pr_tr, "probe_auto_enable_logs() failed"); + tr_err(&pr_tr, "failed"); } #endif @@ -367,10 +367,10 @@ int probe_init(const struct probe_dma *probe_dma) uint32_t i; int err; - tr_dbg(&pr_tr, "probe_init()"); + tr_dbg(&pr_tr, "entry"); if (_probe) { - tr_err(&pr_tr, "probe_init(): Probes already initialized."); + tr_err(&pr_tr, "Probes already initialized."); return -EINVAL; } @@ -378,13 +378,13 @@ int probe_init(const struct probe_dma *probe_dma) sof_get()->probe = rzalloc(SOF_MEM_FLAG_USER, sizeof(*_probe)); if (!sof_get()->probe) { - tr_err(&pr_tr, "probe_init(): Alloc failed."); + tr_err(&pr_tr, "Alloc failed."); return -ENOMEM; } _probe = probe_get(); if (!_probe) { - tr_err(&pr_tr, "probe_init(): Alloc failed."); + tr_err(&pr_tr, "Alloc failed."); return -ENOMEM; } @@ -406,7 +406,7 @@ int probe_init(const struct probe_dma *probe_dma) err = probe_dma_init(&_probe->ext_dma, SOF_DMA_DIR_LMEM_TO_HMEM); if (err < 0) { - tr_err(&pr_tr, "probe_init(): probe_dma_init() failed"); + tr_err(&pr_tr, "probe_dma_init() failed"); _probe->ext_dma.stream_tag = PROBE_DMA_INVALID; return err; } @@ -416,7 +416,7 @@ int probe_init(const struct probe_dma *probe_dma) err = dma_start_legacy(_probe->ext_dma.dc.chan); #endif if (err < 0) { - tr_err(&pr_tr, "probe_init(): failed to start extraction dma"); + tr_err(&pr_tr, "failed to start extraction dma"); return -EBUSY; } @@ -444,10 +444,10 @@ int probe_deinit(void) uint32_t i; int err; - tr_dbg(&pr_tr, "probe_deinit()"); + tr_dbg(&pr_tr, "entry"); if (!_probe) { - tr_err(&pr_tr, "probe_deinit(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -455,7 +455,7 @@ int probe_deinit(void) /* check for attached injection probe DMAs */ for (i = 0; i < CONFIG_PROBE_DMA_MAX; i++) { if (_probe->inject_dma[i].stream_tag != PROBE_DMA_INVALID) { - tr_err(&pr_tr, "probe_deinit(): Cannot deinitialize with injection DMAs attached."); + tr_err(&pr_tr, "Cannot deinitialize with injection DMAs attached."); return -EINVAL; } } @@ -463,13 +463,13 @@ int probe_deinit(void) /* check for connected probe points */ for (i = 0; i < CONFIG_PROBE_POINTS_MAX; i++) { if (_probe->probe_points[i].stream_tag != PROBE_POINT_INVALID) { - tr_err(&pr_tr, "probe_deinit(): Cannot deinitialize with probe points connected."); + tr_err(&pr_tr, "Cannot deinitialize with probe points connected."); return -EINVAL; } } if (_probe->ext_dma.stream_tag != PROBE_DMA_INVALID) { - tr_dbg(&pr_tr, "probe_deinit() Freeing task and extraction DMA."); + tr_dbg(&pr_tr, "Freeing task and extraction DMA."); schedule_task_free(&_probe->dmap_work); err = probe_dma_deinit(&_probe->ext_dma); if (err < 0) @@ -491,10 +491,10 @@ int probe_dma_add(uint32_t count, const struct probe_dma *probe_dma) uint32_t first_free; int err; - tr_dbg(&pr_tr, "probe_dma_add() count = %u", count); + tr_dbg(&pr_tr, "count = %u", count); if (!_probe) { - tr_err(&pr_tr, "probe_dma_add(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -520,14 +520,14 @@ int probe_dma_add(uint32_t count, const struct probe_dma *probe_dma) } if (stream_tag == probe_dma[i].stream_tag) { - tr_err(&pr_tr, "probe_dma_add(): Probe DMA %u already attached.", + tr_err(&pr_tr, "Probe DMA %u already attached.", stream_tag); return -EINVAL; } } if (first_free == CONFIG_PROBE_DMA_MAX) { - tr_err(&pr_tr, "probe_dma_add(): Exceeded maximum number of DMAs attached = " + tr_err(&pr_tr, "Exceeded maximum number of DMAs attached = " STRINGIFY(CONFIG_PROBE_DMA_MAX)); return -EINVAL; } @@ -540,7 +540,7 @@ int probe_dma_add(uint32_t count, const struct probe_dma *probe_dma) err = probe_dma_init(&_probe->inject_dma[first_free], SOF_DMA_DIR_HMEM_TO_LMEM); if (err < 0) { - tr_err(&pr_tr, "probe_dma_add(): probe_dma_init() failed"); + tr_err(&pr_tr, "probe_dma_init() failed"); _probe->inject_dma[first_free].stream_tag = PROBE_DMA_INVALID; return err; @@ -575,10 +575,10 @@ int probe_dma_remove(uint32_t count, const uint32_t *stream_tag) uint32_t j; int err; - tr_dbg(&pr_tr, "probe_dma_remove() count = %u", count); + tr_dbg(&pr_tr, "count = %u", count); if (!_probe) { - tr_err(&pr_tr, "probe_dma_remove(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -633,7 +633,7 @@ static int copy_to_pbuffer(struct probe_dma_buf *pbuf, void *data, /* copy data to probe buffer */ if (memcpy_s((void *)pbuf->w_ptr, pbuf->end_addr - pbuf->w_ptr, data, head)) { - tr_err(&pr_tr, "copy_to_pbuffer(): memcpy_s() failed"); + tr_err(&pr_tr, "memcpy_s() failed"); return -EINVAL; } dcache_writeback_region((__sparse_force void __sparse_cache *)pbuf->w_ptr, head); @@ -643,7 +643,7 @@ static int copy_to_pbuffer(struct probe_dma_buf *pbuf, void *data, pbuf->w_ptr = pbuf->addr; if (memcpy_s((void *)pbuf->w_ptr, (char *)pbuf->end_addr - (char *)pbuf->w_ptr, (char *)data + head, tail)) { - tr_err(&pr_tr, "copy_to_pbuffer(): memcpy_s() failed"); + tr_err(&pr_tr, "memcpy_s() failed"); return -EINVAL; } dcache_writeback_region((__sparse_force void __sparse_cache *)pbuf->w_ptr, tail); @@ -690,7 +690,7 @@ static int copy_from_pbuffer(struct probe_dma_buf *pbuf, void *data, /* data from DMA so invalidate it */ dcache_invalidate_region((__sparse_force void __sparse_cache *)pbuf->r_ptr, head); if (memcpy_s(data, bytes, (void *)pbuf->r_ptr, head)) { - tr_err(&pr_tr, "copy_from_pbuffer(): memcpy_s() failed"); + tr_err(&pr_tr, "memcpy_s() failed"); return -EINVAL; } @@ -700,7 +700,7 @@ static int copy_from_pbuffer(struct probe_dma_buf *pbuf, void *data, pbuf->r_ptr = pbuf->addr; dcache_invalidate_region((__sparse_force void __sparse_cache *)pbuf->r_ptr, tail); if (memcpy_s((char *)data + head, tail, (void *)pbuf->r_ptr, tail)) { - tr_err(&pr_tr, "copy_from_pbuffer(): memcpy_s() failed"); + tr_err(&pr_tr, "memcpy_s() failed"); return -EINVAL; } pbuf->r_ptr = pbuf->r_ptr + tail; @@ -789,7 +789,7 @@ static uint32_t probe_gen_format(uint32_t frame_fmt, uint32_t rate, float_fmt = 1; break; default: - tr_err(&pr_tr, "probe_gen_format(): Invalid frame format specified = 0x%08x", + tr_err(&pr_tr, "Invalid frame format specified = 0x%08x", frame_fmt); return 0; } @@ -929,7 +929,7 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) break; if (i == CONFIG_PROBE_POINTS_MAX) { - tr_err(&pr_tr, "probe_cb_produce(): probe not found for buffer id: %d", + tr_err(&pr_tr, "probe not found for buffer id: %d", buffer_id); return; } @@ -986,7 +986,7 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) } } if (j == CONFIG_PROBE_DMA_MAX) { - tr_err(&pr_tr, "probe_cb_produce(): dma not found"); + tr_err(&pr_tr, "dma not found"); return; } dma = &_probe->inject_dma[j]; @@ -1003,7 +1003,7 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) &free_bytes); #endif if (ret < 0) { - tr_err(&pr_tr, "probe_cb_produce(): dma_get_data_size() failed, ret = %u", + tr_err(&pr_tr, "dma_get_data_size() failed, ret = %u", ret); goto err; } @@ -1063,7 +1063,7 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) } return; err: - tr_err(&pr_tr, "probe_cb_produce(): failed to generate probe data"); + tr_err(&pr_tr, "failed to generate probe data"); } /** @@ -1077,11 +1077,11 @@ static void probe_cb_free(void *arg, enum notify_id type, void *data) uint32_t buffer_id = *(int *)arg; int ret; - tr_dbg(&pr_tr, "probe_cb_free() buffer_id = %u", buffer_id); + tr_dbg(&pr_tr, "buffer_id = %u", buffer_id); ret = probe_point_remove(1, &buffer_id); if (ret < 0) - tr_err(&pr_tr, "probe_cb_free(): probe_point_remove() failed"); + tr_err(&pr_tr, "probe_point_remove() failed"); } static bool probe_purpose_needs_ext_dma(uint32_t purpose) @@ -1102,7 +1102,7 @@ static struct comp_buffer *ipc4_get_buffer(struct ipc_comp_dev *dev, probe_point switch (probe_point.fields.type) { case PROBE_TYPE_INPUT: comp_dev_for_each_producer(dev->cd, buf) { - queue_id = IPC4_SRC_QUEUE_ID(buf_get_id(buf)); + queue_id = IPC4_SINK_QUEUE_ID(buf_get_id(buf)); if (queue_id == probe_point.fields.index) return buf; @@ -1110,7 +1110,7 @@ static struct comp_buffer *ipc4_get_buffer(struct ipc_comp_dev *dev, probe_point break; case PROBE_TYPE_OUTPUT: comp_dev_for_each_consumer(dev->cd, buf) { - queue_id = IPC4_SINK_QUEUE_ID(buf_get_id(buf)); + queue_id = IPC4_SRC_QUEUE_ID(buf_get_id(buf)); if (queue_id == probe_point.fields.index) return buf; @@ -1155,10 +1155,10 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) #if CONFIG_IPC_MAJOR_4 struct comp_buffer *buf = NULL; #endif - tr_dbg(&pr_tr, "probe_point_add() count = %u", count); + tr_dbg(&pr_tr, "count = %u", count); if (!_probe) { - tr_err(&pr_tr, "probe_point_add(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -1173,7 +1173,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) probe[i].stream_tag); if (!verify_purpose(probe[i].purpose)) { - tr_err(&pr_tr, "probe_point_add() error: invalid purpose %d", + tr_err(&pr_tr, "error: invalid purpose %d", probe[i].purpose); return -EINVAL; @@ -1181,7 +1181,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) if (_probe->ext_dma.stream_tag == PROBE_DMA_INVALID && probe_purpose_needs_ext_dma(probe[i].purpose)) { - tr_err(&pr_tr, "probe_point_add(): extraction DMA not enabled."); + tr_err(&pr_tr, "extraction DMA not enabled."); return -EINVAL; } @@ -1197,7 +1197,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) #endif /* check if buffer exists */ if (!dev) { - tr_err(&pr_tr, "probe_point_add(): No device with ID %u found.", + tr_err(&pr_tr, "No device with ID %u found.", buf_id->full_id); return -EINVAL; @@ -1205,14 +1205,14 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) #if CONFIG_IPC_MAJOR_4 buf = ipc4_get_buffer(dev, *buf_id); if (!buf) { - tr_err(&pr_tr, "probe_point_add(): buffer %u not found.", + tr_err(&pr_tr, "buffer %u not found.", buf_id->full_id); return -EINVAL; } #else if (dev->type != COMP_TYPE_BUFFER) { - tr_err(&pr_tr, "probe_point_add(): Device ID %u is not a buffer.", + tr_err(&pr_tr, "Device ID %u is not a buffer.", buf_id->full_id); return -EINVAL; @@ -1236,7 +1236,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) if (buffer_id == buf_id->full_id) { if (_probe->probe_points[j].purpose == probe[i].purpose) { - tr_err(&pr_tr, "probe_point_add(): Probe already attached to buffer %u with purpose %u", + tr_err(&pr_tr, "Probe already attached to buffer %u with purpose %u", buffer_id, probe[i].purpose); @@ -1246,7 +1246,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) } if (first_free == CONFIG_PROBE_POINTS_MAX) { - tr_err(&pr_tr, "probe_point_add(): Maximum number of probe points connected aleady: " + tr_err(&pr_tr, "Maximum number of probe points connected aleady: " STRINGIFY(CONFIG_PROBE_POINTS_MAX)); return -EINVAL; @@ -1267,7 +1267,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) } if (!dma_found) { - tr_err(&pr_tr, "probe_point_add(): No DMA with stream tag %u found for injection.", + tr_err(&pr_tr, "No DMA with stream tag %u found for injection.", probe[i].stream_tag); return -EINVAL; @@ -1278,7 +1278,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) #else if (dma_start_legacy(_probe->inject_dma[j].dc.chan) < 0) { #endif - tr_err(&pr_tr, "probe_point_add(): failed to start dma"); + tr_err(&pr_tr, "failed to start dma"); return -EBUSY; } @@ -1293,7 +1293,7 @@ int probe_point_add(uint32_t count, const struct probe_point *probe) } if (j == CONFIG_PROBE_POINTS_MAX) { - tr_dbg(&pr_tr, "probe_point_add(): start probe task"); + tr_dbg(&pr_tr, "start probe task"); schedule_task(&_probe->dmap_work, 1000, 1000); } /* ignore probe stream tag for extraction probes */ @@ -1338,10 +1338,10 @@ int probe_dma_info(struct sof_ipc_probe_info_params *data, uint32_t max_size) uint32_t i = 0; uint32_t j = 0; - tr_dbg(&pr_tr, "probe_dma_info()"); + tr_dbg(&pr_tr, "entry"); if (!_probe) { - tr_err(&pr_tr, "probe_dma_info(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -1376,10 +1376,10 @@ int probe_point_info(struct sof_ipc_probe_info_params *data, uint32_t max_size) uint32_t i = 0; uint32_t j = 0; - tr_dbg(&pr_tr, "probe_point_info()"); + tr_dbg(&pr_tr, "entry"); if (!_probe) { - tr_err(&pr_tr, "probe_point_info(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } @@ -1418,10 +1418,10 @@ int probe_point_remove(uint32_t count, const uint32_t *buffer_id) struct comp_buffer *buf; #endif - tr_dbg(&pr_tr, "probe_point_remove() count = %u", count); + tr_dbg(&pr_tr, "count = %u", count); if (!_probe) { - tr_err(&pr_tr, "probe_point_remove(): Not initialized."); + tr_err(&pr_tr, "Not initialized."); return -EINVAL; } /* remove each requested probe point */ @@ -1470,7 +1470,7 @@ int probe_point_remove(uint32_t count, const uint32_t *buffer_id) break; } if (j == CONFIG_PROBE_POINTS_MAX) { - tr_dbg(&pr_tr, "probe_point_remove(): cancel probe task"); + tr_dbg(&pr_tr, "cancel probe task"); schedule_task_cancel(&_probe->dmap_work); } @@ -1485,7 +1485,7 @@ static int probe_mod_init(struct processing_module *mod) const struct ipc4_probe_module_cfg *probe_cfg = mod_data->cfg.init_data; int ret; - comp_info(dev, "probe_mod_init()"); + comp_info(dev, "entry"); ret = probe_init(&probe_cfg->gtw_cfg); if (ret < 0) @@ -1498,7 +1498,7 @@ static int probe_free(struct processing_module *mod) { struct comp_dev *dev = mod->dev; - comp_info(dev, "probe_free()"); + comp_info(dev, "entry"); probe_deinit(); @@ -1515,7 +1515,7 @@ static int probe_set_config(struct processing_module *mod, uint32_t param_id, { struct comp_dev *dev = mod->dev; - comp_info(dev, "probe_set_config()"); + comp_info(dev, "entry"); switch (param_id) { case IPC4_PROBE_MODULE_PROBE_POINTS_ADD: @@ -1581,14 +1581,14 @@ static int probe_get_available_points(struct processing_module *mod, id.fields.type = PROBE_TYPE_INPUT; comp_dev_for_each_producer(icd->cd, buf) { - id.fields.index = IPC4_SRC_QUEUE_ID(buf_get_id(buf)); + id.fields.index = IPC4_SINK_QUEUE_ID(buf_get_id(buf)); if (probe_add_point_info_params(info, id, i, max_size)) return 0; i++; } id.fields.type = PROBE_TYPE_OUTPUT; comp_dev_for_each_consumer(icd->cd, buf) { - id.fields.index = IPC4_SINK_QUEUE_ID(buf_get_id(buf)); + id.fields.index = IPC4_SRC_QUEUE_ID(buf_get_id(buf)); if (probe_add_point_info_params(info, id, i, max_size)) return 0; i++; @@ -1640,7 +1640,7 @@ static int probe_dummy_process(struct processing_module *mod, { struct comp_dev *dev = mod->dev; - comp_warn(dev, "probe_dummy_process() called"); + comp_warn(dev, "called"); return 0; } diff --git a/src/samples/audio/detect_test.c b/src/samples/audio/detect_test.c index 1b9082a9ab8c..35ed6ecd2011 100644 --- a/src/samples/audio/detect_test.c +++ b/src/samples/audio/detect_test.c @@ -139,7 +139,7 @@ static void notify_host(const struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_info(dev, "notify_host()"); + comp_info(dev, "entry"); #if CONFIG_IPC_MAJOR_4 ipc_msg_send(cd->msg, NULL, true); @@ -177,7 +177,7 @@ static void notify_kpb(const struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_info(dev, "notify_kpb(), preamble: %u", cd->detect_preamble); + comp_info(dev, "preamble: %u", cd->detect_preamble); cd->client_data.r_ptr = NULL; cd->client_data.sink = NULL; @@ -282,7 +282,7 @@ static int test_keyword_get_threshold(struct comp_dev *dev, int sample_width) return ACTIVATION_DEFAULT_THRESHOLD_S32; #endif /* CONFIG_FORMAT_S32LE */ default: - comp_err(dev, "test_keyword_get_threshold(), unsupported sample width: %d", + comp_err(dev, "unsupported sample width: %d", sample_width); return -EINVAL; } @@ -311,7 +311,7 @@ static int test_keyword_apply_config(struct comp_dev *dev, if (!cd->config.activation_threshold) { ret = test_keyword_get_threshold(dev, sample_width); if (ret < 0) { - comp_err(dev, "test_keyword_apply_config(): unsupported sample width %u", + comp_err(dev, "unsupported sample width %u", sample_width); return ret; } @@ -332,7 +332,7 @@ static void test_keyword_set_params(struct comp_dev *dev, struct comp_data *cd = comp_get_drvdata(dev); enum sof_ipc_frame valid_fmt, frame_fmt; - comp_info(dev, "test_keyword_set_params()"); + comp_info(dev, "entry"); memset(params, 0, sizeof(*params)); params->channels = cd->base_cfg.audio_fmt.channels_count; @@ -361,11 +361,11 @@ static int test_keyword_set_config(struct comp_dev *dev, const char *data, cfg = (const struct sof_detect_test_config *)data; cfg_size = data_size; - comp_info(dev, "test_keyword_set_config(): config size = %u", + comp_info(dev, "config size = %u", cfg_size); if (cfg_size != sizeof(struct sof_detect_test_config)) { - comp_err(dev, "test_keyword_set_config(): invalid config size"); + comp_err(dev, "invalid config size"); return -EINVAL; } @@ -379,12 +379,12 @@ static int test_keyword_get_config(struct comp_dev *dev, char *data, size_t cfg_size; int ret; - comp_info(dev, "test_keyword_get_config()"); + comp_info(dev, "entry"); cfg_size = sizeof(struct sof_detect_test_config); if (cfg_size > *data_size) { - comp_err(dev, "test_keyword_get_config(): wrong config size: %d", + comp_err(dev, "wrong config size: %d", *data_size); return -EINVAL; } @@ -405,7 +405,7 @@ static int test_keyword_set_large_config(struct comp_dev *dev, uint32_t data_offset, const char *data) { - comp_dbg(dev, "test_keyword_set_large_config()"); + comp_dbg(dev, "entry"); struct comp_data *cd = comp_get_drvdata(dev); switch (param_id) { @@ -429,7 +429,7 @@ static int test_keyword_get_large_config(struct comp_dev *dev, uint32_t *data_offset, char *data) { - comp_dbg(dev, "test_keyword_get_large_config()"); + comp_dbg(dev, "entry"); switch (param_id) { case IPC4_DETECT_TEST_GET_CONFIG: @@ -492,10 +492,10 @@ static int test_keyword_set_config(struct comp_dev *dev, cfg = (struct sof_detect_test_config *)cdata->data->data; bs = cfg->size; - comp_info(dev, "test_keyword_set_config(), blob size = %zu", bs); + comp_info(dev, "blob size = %zu", bs); if (bs != sizeof(struct sof_detect_test_config)) { - comp_err(dev, "test_keyword_set_config(): invalid blob size"); + comp_err(dev, "invalid blob size"); return -EINVAL; } @@ -573,7 +573,7 @@ static int test_keyword_get_config(struct comp_dev *dev, size_t bs; int ret = 0; - comp_info(dev, "test_keyword_get_config()"); + comp_info(dev, "entry"); /* Copy back to user space */ bs = cd->config.size; @@ -606,7 +606,7 @@ static int test_keyword_ctrl_get_bin_data(struct comp_dev *dev, ret = comp_data_blob_get_cmd(cd->model_handler, cdata, size); break; default: - comp_err(dev, "test_keyword_ctrl_get_bin_data(): unknown binary data type"); + comp_err(dev, "unknown binary data type"); break; } @@ -618,14 +618,14 @@ static int test_keyword_ctrl_get_data(struct comp_dev *dev, { int ret = 0; - comp_info(dev, "test_keyword_ctrl_get_data() size: %d", size); + comp_info(dev, "size: %d", size); switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: ret = test_keyword_ctrl_get_bin_data(dev, cdata, size); break; default: - comp_err(dev, "test_keyword_ctrl_get_data(): invalid cdata->cmd"); + comp_err(dev, "invalid cdata->cmd"); return -EINVAL; } @@ -638,7 +638,7 @@ static int test_keyword_cmd(struct comp_dev *dev, int cmd, void *data, { struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); - comp_info(dev, "test_keyword_cmd()"); + comp_info(dev, "entry"); switch (cmd) { case COMP_CMD_SET_DATA: @@ -766,7 +766,7 @@ static struct comp_dev *test_keyword_new(const struct comp_driver *drv, comp_data_blob_handler_free(cd->model_handler); rfree(cd); fail: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -774,7 +774,7 @@ static void test_keyword_free(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_info(dev, "test_keyword_free()"); + comp_info(dev, "entry"); #if CONFIG_AMS int ret; @@ -782,13 +782,13 @@ static void test_keyword_free(struct comp_dev *dev) /* Unregister KD as AMS producer */ ret = ams_helper_unregister_producer(dev, cd->kpd_uuid_id); if (ret) - comp_err(dev, "test_keyword_free(): unregister ams error %d", ret); + comp_err(dev, "unregister ams error %d", ret); #endif ipc_msg_free(cd->msg); comp_data_blob_handler_free(cd->model_handler); rfree(cd); - rfree(dev); + comp_free_device(dev); } static int test_keyword_verify_params(struct comp_dev *dev, @@ -796,11 +796,11 @@ static int test_keyword_verify_params(struct comp_dev *dev, { int ret; - comp_dbg(dev, "test_keyword_verify_params()"); + comp_dbg(dev, "entry"); ret = comp_verify_params(dev, 0, params); if (ret < 0) { - comp_err(dev, "test_keyword_verify_params(): verification failed!"); + comp_err(dev, "verification failed!"); return ret; } @@ -821,7 +821,7 @@ static int test_keyword_params(struct comp_dev *dev, err = test_keyword_verify_params(dev, params); if (err < 0) { - comp_err(dev, "test_keyword_params(): pcm params verification failed."); + comp_err(dev, "pcm params verification failed."); return err; } @@ -834,7 +834,7 @@ static int test_keyword_params(struct comp_dev *dev, if (!cd->config.activation_threshold) { err = test_keyword_get_threshold(dev, params->sample_valid_bytes * 8); if (err < 0) { - comp_err(dev, "test_keyword_params(): unsupported sample width %u", + comp_err(dev, "unsupported sample width %u", params->sample_valid_bytes * 8); return err; } @@ -850,12 +850,12 @@ static int test_keyword_params(struct comp_dev *dev, rate = audio_stream_get_rate(&sourceb->stream); if (channels != 1) { - comp_err(dev, "test_keyword_params(): only single-channel supported"); + comp_err(dev, "only single-channel supported"); return -EINVAL; } if (!detector_is_sample_width_supported(frame_fmt)) { - comp_err(dev, "test_keyword_params(): only 16-bit format supported"); + comp_err(dev, "only 16-bit format supported"); return -EINVAL; } @@ -880,7 +880,7 @@ static int test_keyword_trigger(struct comp_dev *dev, int cmd) int ret; struct comp_data *cd = comp_get_drvdata(dev); - comp_info(dev, "test_keyword_trigger()"); + comp_info(dev, "entry"); ret = comp_set_state(dev, cmd); if (ret) @@ -903,7 +903,7 @@ static int test_keyword_copy(struct comp_dev *dev) struct comp_buffer *source; uint32_t frames; - comp_dbg(dev, "test_keyword_copy()"); + comp_dbg(dev, "entry"); /* keyword components will only ever have 1 source */ source = comp_dev_get_first_data_producer(dev); @@ -927,7 +927,7 @@ static int test_keyword_reset(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - comp_info(dev, "test_keyword_reset()"); + comp_info(dev, "entry"); cd->activation = 0; cd->detect_preamble = 0; @@ -950,11 +950,11 @@ static int test_keyword_prepare(struct comp_dev *dev) sample_width = cd->config.sample_width; #endif /* CONFIG_IPC_MAJOR_4 */ - comp_info(dev, "test_keyword_prepare()"); + comp_info(dev, "entry"); ret = test_keyword_params(dev, ¶ms); if (ret < 0) { - comp_err(dev, "test_keyword_prepare(): params config failed."); + comp_err(dev, "params config failed."); return ret; } @@ -969,7 +969,7 @@ static int test_keyword_prepare(struct comp_dev *dev) ret = test_keyword_get_threshold(dev, valid_bits); if (ret < 0) { - comp_err(dev, "test_keyword_prepare(): unsupported sample width %u", + comp_err(dev, "unsupported sample width %u", valid_bits); return ret; } diff --git a/src/samples/audio/kwd_nn_detect_test.c b/src/samples/audio/kwd_nn_detect_test.c index ef71a441580b..5d1f054bb040 100644 --- a/src/samples/audio/kwd_nn_detect_test.c +++ b/src/samples/audio/kwd_nn_detect_test.c @@ -84,18 +84,18 @@ void kwd_nn_detect_test(struct comp_dev *dev, result = kwd_nn_detect_postprocess(confidences); time_stop = sof_cycle_get_64(); comp_dbg(dev, - "KWD: kwd_nn_detect_test_copy() inference done in %u ms", + "KWD: inference done in %u ms", (unsigned int)k_cyc_to_ms_near64(time_stop - time_start)); switch (result) { case KWD_NN_YES_KEYWORD: case KWD_NN_NO_KEYWORD: if (result == KWD_NN_NO_KEYWORD) comp_info(dev, - "kwd_nn_detect_test_copy(): keyword NO detected confidence %d", + "keyword NO detected confidence %d", confidences[3]); else comp_info(dev, - "kwd_nn_detect_test_copy(): keyword YES detected confidences %d", + "keyword YES detected confidences %d", confidences[2]); /* The algorithm shall use cd->drain_req * to specify its draining size request. diff --git a/src/samples/audio/smart_amp_test.toml b/src/samples/audio/smart_amp_test.toml index f0f4fa9339dc..1576ed449bf6 100644 --- a/src/samples/audio/smart_amp_test.toml +++ b/src/samples/audio/smart_amp_test.toml @@ -23,8 +23,8 @@ REM # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] #ifdef CONFIG_METEORLAKE mod_cfg = [0, 0, 0, 0, 296, 5000000, 384, 384, 0, 5000, 0] -#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#elif defined(CONFIG_LUNARLAKE) || defined(CONFIG_SOC_ACE30) || \ + defined(CONFIG_SOC_ACE40) mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] #endif diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index 610e38f6d753..3e69bb5f308e 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -88,7 +88,7 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, comp_data_blob_handler_free(sad->model_handler); rfree(sad); fail: - rfree(dev); + comp_free_device(dev); return NULL; } @@ -110,11 +110,11 @@ static int smart_amp_set_config(struct comp_dev *dev, ASSUME_ALIGNED(&cdata->data->data, sizeof(uint32_t)); bs = cfg->size; - comp_dbg(dev, "smart_amp_set_config(), actual blob size = %zu, expected blob size = %zu", + comp_dbg(dev, "actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); if (bs != sizeof(struct sof_smart_amp_config)) { - comp_err(dev, "smart_amp_set_config(): invalid blob size, actual blob size = %zu, expected blob size = %zu", + comp_err(dev, "invalid blob size, actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); return -EINVAL; } @@ -164,7 +164,7 @@ static int smart_amp_ctrl_get_bin_data(struct comp_dev *dev, case SOF_SMART_AMP_MODEL: return comp_data_blob_get_cmd(sad->model_handler, cdata, size); default: - comp_warn(dev, "smart_amp_ctrl_get_bin_data(): unknown binary data type"); + comp_warn(dev, "unknown binary data type"); break; } @@ -174,13 +174,13 @@ static int smart_amp_ctrl_get_bin_data(struct comp_dev *dev, static int smart_amp_ctrl_get_data(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata, int size) { - comp_info(dev, "smart_amp_ctrl_get_data() size: %d", size); + comp_info(dev, "size: %d", size); switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: return smart_amp_ctrl_get_bin_data(dev, cdata, size); default: - comp_err(dev, "smart_amp_ctrl_get_data(): invalid cdata->cmd"); + comp_err(dev, "invalid cdata->cmd"); return -EINVAL; } } @@ -193,7 +193,7 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, assert(sad); if (dev->state < COMP_STATE_READY) { - comp_err(dev, "smart_amp_ctrl_set_bin_data(): driver in init!"); + comp_err(dev, "driver in init!"); return -EBUSY; } @@ -203,7 +203,7 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, case SOF_SMART_AMP_MODEL: return comp_data_blob_set_cmd(sad->model_handler, cdata); default: - comp_warn(dev, "smart_amp_ctrl_set_bin_data(): unknown binary data type"); + comp_warn(dev, "unknown binary data type"); break; } @@ -215,19 +215,19 @@ static int smart_amp_ctrl_set_data(struct comp_dev *dev, { /* Check version from ABI header */ if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { - comp_err(dev, "smart_amp_ctrl_set_data(): invalid version"); + comp_err(dev, "invalid version"); return -EINVAL; } switch (cdata->cmd) { case SOF_CTRL_CMD_ENUM: - comp_info(dev, "smart_amp_ctrl_set_data(), SOF_CTRL_CMD_ENUM"); + comp_info(dev, "SOF_CTRL_CMD_ENUM"); break; case SOF_CTRL_CMD_BINARY: - comp_info(dev, "smart_amp_ctrl_set_data(), SOF_CTRL_CMD_BINARY"); + comp_info(dev, "SOF_CTRL_CMD_BINARY"); return smart_amp_ctrl_set_bin_data(dev, cdata); default: - comp_err(dev, "smart_amp_ctrl_set_data(): invalid cdata->cmd"); + comp_err(dev, "invalid cdata->cmd"); return -EINVAL; } @@ -240,7 +240,7 @@ static int smart_amp_cmd(struct comp_dev *dev, int cmd, void *data, { struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); - comp_info(dev, "smart_amp_cmd(): cmd: %d", cmd); + comp_info(dev, "cmd: %d", cmd); switch (cmd) { case COMP_CMD_SET_DATA: @@ -256,12 +256,12 @@ static void smart_amp_free(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - comp_info(dev, "smart_amp_free()"); + comp_info(dev, "entry"); comp_data_blob_handler_free(sad->model_handler); rfree(sad); - rfree(dev); + comp_free_device(dev); } static int smart_amp_verify_params(struct comp_dev *dev, @@ -269,11 +269,11 @@ static int smart_amp_verify_params(struct comp_dev *dev, { int ret; - comp_info(dev, "smart_amp_verify_params()"); + comp_info(dev, "entry"); ret = comp_verify_params(dev, BUFF_PARAMS_CHANNELS, params); if (ret < 0) { - comp_err(dev, "smart_amp_verify_params() error: comp_verify_params() failed."); + comp_err(dev, "error: comp_verify_params() failed."); return ret; } @@ -285,13 +285,13 @@ static int smart_amp_params(struct comp_dev *dev, { int err; - comp_info(dev, "smart_amp_params()"); + comp_info(dev, "entry"); smart_amp_set_params(dev, params); err = smart_amp_verify_params(dev, params); if (err < 0) { - comp_err(dev, "smart_amp_params(): pcm params verification failed."); + comp_err(dev, "pcm params verification failed."); return err; } @@ -303,7 +303,7 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) struct smart_amp_data *sad = comp_get_drvdata(dev); int ret = 0; - comp_info(dev, "smart_amp_trigger(), command = %u", cmd); + comp_info(dev, "command = %u", cmd); ret = comp_set_state(dev, cmd); @@ -340,7 +340,7 @@ static int smart_amp_process_s16(struct comp_dev *dev, int i; int j; - comp_dbg(dev, "smart_amp_process_s16()"); + comp_dbg(dev, "entry"); for (i = 0; i < frames; i++) { for (j = 0 ; j < sad->out_channels; j++) { @@ -372,7 +372,7 @@ static int smart_amp_process_s32(struct comp_dev *dev, int i; int j; - comp_dbg(dev, "smart_amp_process_s32()"); + comp_dbg(dev, "entry"); for (i = 0; i < frames; i++) { for (j = 0 ; j < sad->out_channels; j++) { @@ -419,7 +419,7 @@ static int smart_amp_copy(struct comp_dev *dev) uint32_t sink_bytes; uint32_t feedback_bytes; - comp_dbg(dev, "smart_amp_copy()"); + comp_dbg(dev, "entry"); /* available bytes and samples calculation */ avail_passthrough_frames = @@ -440,7 +440,7 @@ static int smart_amp_copy(struct comp_dev *dev) feedback_bytes = avail_frames * audio_stream_frame_bytes(&buf->stream); - comp_dbg(dev, "smart_amp_copy(): processing %d feedback frames (avail_passthrough_frames: %d)", + comp_dbg(dev, "processing %d feedback frames (avail_passthrough_frames: %d)", avail_frames, avail_passthrough_frames); /* perform buffer writeback after source_buf process */ @@ -476,7 +476,7 @@ static int smart_amp_copy(struct comp_dev *dev) static int smart_amp_reset(struct comp_dev *dev) { - comp_info(dev, "smart_amp_reset()"); + comp_info(dev, "entry"); comp_set_state(dev, COMP_TRIGGER_RESET); @@ -489,7 +489,7 @@ static int smart_amp_prepare(struct comp_dev *dev) struct comp_buffer *source_buffer; int ret; - comp_info(dev, "smart_amp_prepare()"); + comp_info(dev, "entry"); ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); if (ret < 0) @@ -527,7 +527,7 @@ static int smart_amp_prepare(struct comp_dev *dev) sad->process = get_smart_amp_process(dev, sad->source_buf); if (!sad->process) { - comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed"); + comp_err(dev, "get_smart_amp_process failed"); ret = -EINVAL; } return ret; diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 52e92699e669..89d5861fed71 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -62,14 +62,14 @@ static int smart_amp_init(struct processing_module *mod) comp_dbg(dev, "entry"); - sad = rzalloc(SOF_MEM_FLAG_USER, sizeof(*sad)); + sad = mod_zalloc(mod, sizeof(*sad)); if (!sad) return -ENOMEM; mod_data->private = sad; /* component model data handler */ - sad->model_handler = comp_data_blob_handler_new(dev); + sad->model_handler = mod_data_blob_handler_new(mod); if (!sad->model_handler) { ret = -ENOMEM; goto sad_fail; @@ -93,8 +93,8 @@ static int smart_amp_init(struct processing_module *mod) return 0; sad_fail: - comp_data_blob_handler_free(sad->model_handler); - rfree(sad); + mod_data_blob_handler_free(mod, sad->model_handler); + mod_free(mod, sad); return ret; } @@ -107,7 +107,7 @@ static int smart_amp_set_config(struct processing_module *mod, uint32_t config_i struct comp_dev *dev = mod->dev; struct smart_amp_data *sad = module_get_private_data(mod); - comp_dbg(dev, "smart_amp_set_config()"); + comp_dbg(dev, "entry"); switch (config_id) { case SMART_AMP_SET_MODEL: @@ -115,11 +115,11 @@ static int smart_amp_set_config(struct processing_module *mod, uint32_t config_i data_offset_size, fragment, fragment_size); case SMART_AMP_SET_CONFIG: if (fragment_size != sizeof(sad->config)) { - comp_err(dev, "smart_amp_set_config(): invalid config size %u, expect %u", + comp_err(dev, "invalid config size %u, expect %u", fragment_size, sizeof(struct sof_smart_amp_config)); return -EINVAL; } - comp_dbg(dev, "smart_amp_set_config(): config size = %u", fragment_size); + comp_dbg(dev, "config size = %u", fragment_size); memcpy_s(&sad->config, sizeof(sad->config), fragment, fragment_size); return 0; default: @@ -135,13 +135,13 @@ static inline int smart_amp_get_config(struct processing_module *mod, struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "smart_amp_get_config()"); + comp_dbg(dev, "entry"); switch (config_id) { case SMART_AMP_GET_CONFIG: ret = memcpy_s(fragment, fragment_size, &sad->config, sizeof(sad->config)); if (ret) { - comp_err(dev, "smart_amp_get_config(): wrong config size %d", + comp_err(dev, "wrong config size %d", fragment_size); return ret; } @@ -157,9 +157,9 @@ static int smart_amp_free(struct processing_module *mod) struct smart_amp_data *sad = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - comp_dbg(dev, "smart_amp_free()"); - comp_data_blob_handler_free(sad->model_handler); - rfree(sad); + comp_dbg(dev, "entry"); + mod_data_blob_handler_free(mod, sad->model_handler); + mod_free(mod, sad); return 0; } diff --git a/src/schedule/CMakeLists.txt b/src/schedule/CMakeLists.txt index afa1cdc95324..622b75e46888 100644 --- a/src/schedule/CMakeLists.txt +++ b/src/schedule/CMakeLists.txt @@ -29,7 +29,7 @@ if (CONFIG_SOC_ACP_6_0) ) else() zephyr_library_sources( - ll_schedule.c + ll_schedule_xtos.c ) endif() else() @@ -38,12 +38,24 @@ else() ) endif() -zephyr_library_sources_ifdef(CONFIG_ZEPHYR_DP_SCHEDULER - zephyr_dp_schedule.c -) +if (CONFIG_SOF_USERSPACE_APPLICATION) + zephyr_library_sources_ifdef(CONFIG_ZEPHYR_DP_SCHEDULER + zephyr_dp_schedule.c + zephyr_dp_schedule_application.c + ) +else() + zephyr_library_sources_ifdef(CONFIG_ZEPHYR_DP_SCHEDULER + zephyr_dp_schedule.c + zephyr_dp_schedule_thread.c + ) +endif() zephyr_library_sources_ifdef(CONFIG_ZEPHYR_TWB_SCHEDULER zephyr_twb_schedule.c ) +zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_LL + zephyr_ll_user.c +) + endif() diff --git a/src/schedule/Kconfig b/src/schedule/Kconfig index 99ca2861f650..f1383e70103f 100644 --- a/src/schedule/Kconfig +++ b/src/schedule/Kconfig @@ -15,6 +15,7 @@ config SCHEDULE_DMA_MULTI_CHANNEL config SCHEDULE_LL_STATS_LOG bool "Log low-latency scheduler statistics" default y + depends on !SOF_USERSPACE_LL help Log statistics from low-latency scheduler. This is a low overhead mechanism to gather average and worst-case execution times of diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule_xtos.c similarity index 100% rename from src/schedule/ll_schedule.c rename to src/schedule/ll_schedule_xtos.c diff --git a/src/schedule/zephyr_domain.c b/src/schedule/zephyr_domain.c index 6e03158f2bb9..6a5812353d9e 100644 --- a/src/schedule/zephyr_domain.c +++ b/src/schedule/zephyr_domain.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -38,17 +39,28 @@ LOG_MODULE_DECLARE(ll_schedule, CONFIG_SOF_LOG_LEVEL); #define ZEPHYR_LL_STACK_SIZE 8192 +#if CONFIG_SOF_USERSPACE_LL +K_THREAD_STACK_ARRAY_DEFINE(ll_sched_stack, CONFIG_CORE_COUNT, ZEPHYR_LL_STACK_SIZE); +#else K_KERNEL_STACK_ARRAY_DEFINE(ll_sched_stack, CONFIG_CORE_COUNT, ZEPHYR_LL_STACK_SIZE); +#endif struct zephyr_domain_thread { - struct k_thread ll_thread; - struct k_sem sem; + struct k_thread *ll_thread; + struct k_sem *sem; +#ifndef CONFIG_SOF_USERSPACE_LL + struct k_thread ll_thread_obj; + struct k_sem sem_obj; +#endif void (*handler)(void *arg); void *arg; }; struct zephyr_domain { - struct k_timer timer; + struct k_timer *timer; +#ifndef CONFIG_SOF_USERSPACE_LL + struct k_timer timer_obj; +#endif struct zephyr_domain_thread domain_thread[CONFIG_CORE_COUNT]; struct ll_schedule_domain *ll_domain; #if CONFIG_CROSS_CORE_STREAM @@ -77,16 +89,18 @@ static inline void stats_report(unsigned int runs, int core, unsigned int cycles static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3) { struct zephyr_domain *zephyr_domain = p1; - int core = cpu_get_id(); + int core = POINTER_TO_INT(p2); struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + core; #ifdef CONFIG_SCHEDULE_LL_STATS_LOG unsigned int runs = 0, overruns = 0, cycles_sum = 0, cycles_max = 0; unsigned int cycles0, cycles1, diff, timer_fired; #endif + tr_dbg(&ll_tr, "ll core %u thread starting", core); + for (;;) { /* immediately go to sleep, waiting to be woken up by the timer */ - k_sem_take(&dt->sem, K_FOREVER); + k_sem_take(dt->sem, K_FOREVER); #ifdef CONFIG_SCHEDULE_LL_STATS_LOG cycles0 = k_cycle_get_32(); @@ -120,7 +134,7 @@ static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3) /* This handles wrapping correctly too */ diff = cycles1 - cycles0; - timer_fired = k_timer_status_get(&zephyr_domain->timer); + timer_fired = k_timer_status_get(zephyr_domain->timer); if (timer_fired > 1) overruns++; @@ -163,10 +177,13 @@ static void zephyr_domain_timer_fn(struct k_timer *timer) struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + core; if (dt->handler) - k_sem_give(&dt->sem); + k_sem_give(dt->sem); } } +/* The normal kernel-space implementation for register/unregister */ +#ifndef CONFIG_SOF_USERSPACE_LL + static int zephyr_domain_register(struct ll_schedule_domain *domain, struct task *task, void (*handler)(void *arg), void *arg) @@ -188,15 +205,16 @@ static int zephyr_domain_register(struct ll_schedule_domain *domain, dt->arg = arg; /* 10 is rather random, we better not accumulate 10 missed timer interrupts */ - k_sem_init(&dt->sem, 0, 10); + k_sem_init(dt->sem, 0, 10); thread_name[sizeof(thread_name) - 2] = '0' + core; - thread = k_thread_create(&dt->ll_thread, - ll_sched_stack[core], - ZEPHYR_LL_STACK_SIZE, - zephyr_domain_thread_fn, zephyr_domain, NULL, NULL, - CONFIG_LL_THREAD_PRIORITY, 0, K_FOREVER); + /* not allocated dynamically when LL in kernel space */ + dt->ll_thread = &dt->ll_thread_obj; + + thread = k_thread_create(dt->ll_thread, ll_sched_stack[core], ZEPHYR_LL_STACK_SIZE, + zephyr_domain_thread_fn, zephyr_domain, INT_TO_POINTER(core), + NULL, CONFIG_LL_THREAD_PRIORITY, 0, K_FOREVER); k_thread_cpu_mask_clear(thread); k_thread_cpu_mask_enable(thread, core); @@ -206,13 +224,13 @@ static int zephyr_domain_register(struct ll_schedule_domain *domain, key = k_spin_lock(&domain->lock); - if (!k_timer_user_data_get(&zephyr_domain->timer)) { + if (!k_timer_user_data_get(zephyr_domain->timer)) { k_timeout_t start = {0}; - k_timer_init(&zephyr_domain->timer, zephyr_domain_timer_fn, NULL); - k_timer_user_data_set(&zephyr_domain->timer, zephyr_domain); + k_timer_init(zephyr_domain->timer, zephyr_domain_timer_fn, NULL); + k_timer_user_data_set(zephyr_domain->timer, zephyr_domain); - k_timer_start(&zephyr_domain->timer, start, K_USEC(LL_TIMER_PERIOD_US)); + k_timer_start(zephyr_domain->timer, start, K_USEC(LL_TIMER_PERIOD_US)); /* Enable the watchdog */ watchdog_enable(core); @@ -220,7 +238,7 @@ static int zephyr_domain_register(struct ll_schedule_domain *domain, k_spin_unlock(&domain->lock, key); - tr_info(&ll_tr, "zephyr_domain_register domain->type %d domain->clk %d domain->ticks_per_ms %d period %d", + tr_info(&ll_tr, "domain->type %d domain->clk %d domain->ticks_per_ms %d period %d", domain->type, domain->clk, domain->ticks_per_ms, (uint32_t)LL_TIMER_PERIOD_US); return 0; @@ -245,26 +263,160 @@ static int zephyr_domain_unregister(struct ll_schedule_domain *domain, /* Disable the watchdog */ watchdog_disable(core); - k_timer_stop(&zephyr_domain->timer); - k_timer_user_data_set(&zephyr_domain->timer, NULL); + k_timer_stop(zephyr_domain->timer); + k_timer_user_data_set(zephyr_domain->timer, NULL); } zephyr_domain->domain_thread[core].handler = NULL; k_spin_unlock(&domain->lock, key); - tr_info(&ll_tr, "zephyr_domain_unregister domain->type %d domain->clk %d", + tr_info(&ll_tr, "domain->type %d domain->clk %d", domain->type, domain->clk); /* * If running in the context of the domain thread, k_thread_abort() will * not return */ - k_thread_abort(&zephyr_domain->domain_thread[core].ll_thread); + k_thread_abort(zephyr_domain->domain_thread[core].ll_thread); + + tr_dbg(&ll_tr, "exit"); return 0; } +#else /* CONFIG_SOF_USERSPACE_LL */ + +/* User-space implementation for register/unregister */ + +static int zephyr_domain_register_user(struct ll_schedule_domain *domain, + struct task *task, + void (*handler)(void *arg), void *arg) +{ + struct zephyr_domain *zephyr_domain = ll_sch_domain_get_pdata(domain); + int core = cpu_get_id(); + struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + core; + char thread_name[] = "ll_thread0"; + k_tid_t thread; + + tr_dbg(&ll_tr, "entry"); + + /* domain work only needs registered once on each core */ + if (dt->handler) + return 0; + + __ASSERT_NO_MSG(task->core == core); + + dt->handler = handler; + dt->arg = arg; + + /* 10 is rather random, we better not accumulate 10 missed timer interrupts */ + k_sem_init(dt->sem, 0, 10); + + thread_name[sizeof(thread_name) - 2] = '0' + core; + + if (!dt->ll_thread) { + /* Allocate thread structure dynamically */ + dt->ll_thread = k_object_alloc(K_OBJ_THREAD); + if (!dt->ll_thread) { + tr_err(&ll_tr, "Failed to allocate thread object for core %d", core); + dt->handler = NULL; + dt->arg = NULL; + return -ENOMEM; + } + + thread = k_thread_create(dt->ll_thread, ll_sched_stack[core], ZEPHYR_LL_STACK_SIZE, + zephyr_domain_thread_fn, zephyr_domain, + INT_TO_POINTER(core), NULL, CONFIG_LL_THREAD_PRIORITY, + K_USER, K_FOREVER); + + k_thread_cpu_mask_clear(thread); + k_thread_cpu_mask_enable(thread, core); + k_thread_name_set(thread, thread_name); + + k_mem_domain_add_thread(zephyr_ll_mem_domain(), thread); + k_thread_access_grant(thread, dt->sem, domain->lock, zephyr_domain->timer); + user_grant_dai_access_all(thread); + user_grant_dma_access_all(thread); + tr_dbg(&ll_tr, "granted LL access to thread %p (core %d)", thread, core); + + k_thread_start(thread); + } + + k_mutex_lock(domain->lock, K_FOREVER); + if (!k_timer_user_data_get(zephyr_domain->timer)) { + k_timeout_t start = {0}; + + k_timer_init(zephyr_domain->timer, zephyr_domain_timer_fn, NULL); + k_timer_user_data_set(zephyr_domain->timer, zephyr_domain); + + k_timer_start(zephyr_domain->timer, start, K_USEC(LL_TIMER_PERIOD_US)); + + /* Enable the watchdog */ + watchdog_enable(core); + } + + k_mutex_unlock(domain->lock); + + tr_info(&ll_tr, "domain->type %d domain->clk %d domain->ticks_per_ms %d period %d", + domain->type, domain->clk, domain->ticks_per_ms, (uint32_t)LL_TIMER_PERIOD_US); + + return 0; +} + +static int zephyr_domain_unregister_user(struct ll_schedule_domain *domain, + struct task *task, uint32_t num_tasks) +{ + struct zephyr_domain *zephyr_domain = ll_sch_domain_get_pdata(domain); + int core = task->core; + + tr_dbg(&ll_tr, "entry"); + + /* tasks still registered on this core */ + if (num_tasks) + return 0; + + k_mutex_lock(domain->lock, K_FOREVER); + + if (!atomic_read(&domain->total_num_tasks)) { + /* Disable the watchdog */ + watchdog_disable(core); + + k_timer_stop(zephyr_domain->timer); + k_timer_user_data_set(zephyr_domain->timer, NULL); + } + + zephyr_domain->domain_thread[core].handler = NULL; + + k_mutex_unlock(domain->lock); + + tr_info(&ll_tr, "domain->type %d domain->clk %d", + domain->type, domain->clk); + + /* Thread not removed here, only the timer is stopped. + * Thread object cleanup would require k_thread_abort() which cannot + * be safely called from this context. The thread remains allocated + * but dormant until next registration or system shutdown. + */ + + tr_dbg(&ll_tr, "exit"); + + return 0; +} + +struct k_thread *zephyr_domain_thread_tid(struct ll_schedule_domain *domain) +{ + struct zephyr_domain *zephyr_domain = ll_sch_domain_get_pdata(domain); + int core = cpu_get_id(); + struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + core; + + tr_dbg(&ll_tr, "entry"); + + return dt->ll_thread; +} + +#endif /* CONFIG_SOF_USERSPACE_LL */ + #if CONFIG_CROSS_CORE_STREAM static void zephyr_domain_block(struct ll_schedule_domain *domain) { @@ -290,9 +442,14 @@ static void zephyr_domain_unblock(struct ll_schedule_domain *domain) } #endif -static const struct ll_schedule_domain_ops zephyr_domain_ops = { +APP_TASK_DATA static const struct ll_schedule_domain_ops zephyr_domain_ops = { +#ifdef CONFIG_SOF_USERSPACE_LL + .domain_register = zephyr_domain_register_user, + .domain_unregister = zephyr_domain_unregister_user, +#else .domain_register = zephyr_domain_register, .domain_unregister = zephyr_domain_unregister, +#endif #if CONFIG_CROSS_CORE_STREAM .domain_block = zephyr_domain_block, .domain_unblock = zephyr_domain_unblock, @@ -303,6 +460,8 @@ struct ll_schedule_domain *zephyr_domain_init(int clk) { struct ll_schedule_domain *domain; struct zephyr_domain *zephyr_domain; + struct zephyr_domain_thread *dt; + int core; domain = domain_init(SOF_SCHEDULE_LL_TIMER, clk, false, &zephyr_domain_ops); @@ -311,16 +470,37 @@ struct ll_schedule_domain *zephyr_domain_init(int clk) return NULL; } +#if CONFIG_SOF_USERSPACE_LL + zephyr_domain = sof_heap_alloc(zephyr_ll_user_heap(), + SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*zephyr_domain), sizeof(void *)); + if (zephyr_domain) + memset(zephyr_domain, 0, sizeof(*zephyr_domain)); +#else zephyr_domain = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, sizeof(*zephyr_domain)); +#endif if (!zephyr_domain) { tr_err(&ll_tr, "domain allocation failed"); - rfree(domain); + k_panic(); return NULL; } zephyr_domain->ll_domain = domain; +#if CONFIG_SOF_USERSPACE_LL + /* Allocate timer dynamically for userspace access */ + zephyr_domain->timer = k_object_alloc(K_OBJ_TIMER); + if (!zephyr_domain->timer) { + tr_err(&ll_tr, "timer allocation failed"); + k_panic(); + return NULL; + } +#else + /* not allocated dynamically when LL in kernel space */ + zephyr_domain->timer = &zephyr_domain->timer_obj; +#endif + #if CONFIG_CROSS_CORE_STREAM atomic_set(&zephyr_domain->block, 0); k_mutex_init(&zephyr_domain->block_mutex); @@ -329,6 +509,20 @@ struct ll_schedule_domain *zephyr_domain_init(int clk) ll_sch_domain_set_pdata(domain, zephyr_domain); + for (core = 0; core < CONFIG_CORE_COUNT; core++) { + dt = zephyr_domain->domain_thread + core; +#ifdef CONFIG_SOF_USERSPACE_LL + dt->sem = k_object_alloc(K_OBJ_SEM); + if (!dt->sem) { + tr_err(&ll_tr, "Failed to allocate semaphore for core %d", core); + k_panic(); + } +#else + /* not allocated dynamically when LL in kernel space */ + dt->sem = &dt->sem_obj; +#endif + } + return domain; } @@ -342,6 +536,6 @@ bool ll_sch_is_current(void) struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + cpu_get_id(); - return k_current_get() == &dt->ll_thread; + return k_current_get() == dt->ll_thread; } EXPORT_SYMBOL(ll_sch_is_current); diff --git a/src/schedule/zephyr_dp_schedule.c b/src/schedule/zephyr_dp_schedule.c index c4f3aaedeb37..3c88573b92e5 100644 --- a/src/schedule/zephyr_dp_schedule.c +++ b/src/schedule/zephyr_dp_schedule.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,8 @@ #include #include +#include "zephyr_dp_schedule.h" + #include LOG_MODULE_REGISTER(dp_schedule, CONFIG_SOF_LOG_LEVEL); @@ -30,29 +33,6 @@ SOF_DEFINE_REG_UUID(dp_sched); DECLARE_TR_CTX(dp_tr, SOF_UUID(dp_sched_uuid), LOG_LEVEL_INFO); -struct scheduler_dp_data { - struct list_item tasks; /* list of active dp tasks */ - struct task ll_tick_src; /* LL task - source of DP tick */ -}; - -struct task_dp_pdata { - k_tid_t thread_id; /* zephyr thread ID */ - struct k_thread *thread; /* pointer to the kernels' thread object */ - struct k_thread thread_struct; /* thread object for kernel threads */ - uint32_t deadline_clock_ticks; /* dp module deadline in Zephyr ticks */ - k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */ - size_t stack_size; /* size of the stack in bytes */ - struct k_sem *sem; /* pointer to semaphore for task scheduling */ - struct k_sem sem_struct; /* semaphore for task scheduling for kernel threads */ - struct processing_module *mod; /* the module to be scheduled */ - uint32_t ll_cycles_to_start; /* current number of LL cycles till delayed start */ -}; - -#ifdef CONFIG_USERSPACE -/* Single CPU-wide lock - * The irq_lock is not available for USERSPACE (non-privileged) threads. - * Therefore semaphore is used to control critical section. - */ #define DP_LOCK_INIT(i, _) Z_SEM_INITIALIZER(dp_lock[i], 1, 1) #define DP_LOCK_INIT_LIST LISTIFY(CONFIG_MP_MAX_NUM_CPUS, DP_LOCK_INIT, (,)) @@ -63,42 +43,27 @@ struct task_dp_pdata { static STRUCT_SECTION_ITERABLE_ARRAY(k_sem, dp_lock, CONFIG_MP_MAX_NUM_CPUS) = { DP_LOCK_INIT_LIST }; -static inline unsigned int scheduler_dp_lock(uint16_t core) +/* Each per-core instance of DP scheduler has separate structures; hence, locks are per-core. + * + * TODO: consider using cpu_get_id() instead of supplying core as a parameter. + */ +unsigned int scheduler_dp_lock(uint16_t core) { k_sem_take(&dp_lock[core], K_FOREVER); return core; } -static inline void scheduler_dp_unlock(unsigned int key) +void scheduler_dp_unlock(unsigned int key) { k_sem_give(&dp_lock[key]); } -static inline void scheduler_dp_grant(k_tid_t thread_id, uint16_t core) +void scheduler_dp_grant(k_tid_t thread_id, uint16_t core) { +#if CONFIG_USERSPACE k_thread_access_grant(thread_id, &dp_lock[core]); -} - -#else /* CONFIG_USERSPACE */ - -static inline void scheduler_dp_grant(k_tid_t thread_id, uint16_t core) -{ -} - -/* Single CPU-wide lock - * as each per-core instance if dp-scheduler has separate structures, it is enough to - * use irq_lock instead of cross-core spinlocks - */ -static inline unsigned int scheduler_dp_lock(uint16_t core) -{ - return irq_lock(); -} - -static inline void scheduler_dp_unlock(unsigned int key) -{ - irq_unlock(key); -} #endif +} /* dummy LL task - to start LL on secondary cores */ static enum task_state scheduler_dp_ll_tick_dummy(void *data) @@ -258,73 +223,54 @@ static enum task_state scheduler_dp_ll_tick_dummy(void *data) * Now - pipeline is in stable state, CPU used almost in 100% (it would be 100% if DP3 * needed 1.2ms for processing - but the example would be too complicated) */ + void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void *caller_data) { (void)receiver_data; (void)event_type; (void)caller_data; - struct list_item *tlist; - struct task *curr_task; - struct task_dp_pdata *pdata; unsigned int lock_key; struct scheduler_dp_data *dp_sch = scheduler_get_data(SOF_SCHEDULE_DP); + /* remember current timestamp as "NOW" */ + dp_sch->last_ll_tick_timestamp = k_cycle_get_32(); + lock_key = scheduler_dp_lock(cpu_get_id()); - list_for_item(tlist, &dp_sch->tasks) { - curr_task = container_of(tlist, struct task, list); - pdata = curr_task->priv_data; - struct processing_module *mod = pdata->mod; - - /* decrease number of LL ticks/cycles left till the module reaches its deadline */ - if (pdata->ll_cycles_to_start) { - pdata->ll_cycles_to_start--; - if (!pdata->ll_cycles_to_start) - /* deadline reached, clear startup delay flag. - * see dp_startup_delay comment for details - */ - mod->dp_startup_delay = false; - } - - if (curr_task->state == SOF_TASK_STATE_QUEUED) { - bool mod_ready; - - mod_ready = module_is_ready_to_process(mod, mod->sources, - mod->num_of_sources, - mod->sinks, - mod->num_of_sinks); - if (mod_ready) { - /* set a deadline for given num of ticks, starting now */ - k_thread_deadline_set(pdata->thread_id, - pdata->deadline_clock_ticks); - - /* trigger the task */ - curr_task->state = SOF_TASK_STATE_RUNNING; - k_sem_give(pdata->sem); - } - } - } + scheduler_dp_recalculate(dp_sch, event_type == NOTIFIER_ID_LL_POST_RUN); scheduler_dp_unlock(lock_key); } +#if CONFIG_SOF_USERSPACE_APPLICATION static int scheduler_dp_task_cancel(void *data, struct task *task) +{ + /* Should never be called */ + k_panic(); + return -EOPNOTSUPP; +} +#endif + +static int scheduler_dp_task_stop(void *data, struct task *task) { unsigned int lock_key; struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; struct task_dp_pdata *pdata = task->priv_data; - /* this is asyn cancel - mark the task as canceled and remove it from scheduling */ lock_key = scheduler_dp_lock(cpu_get_id()); task->state = SOF_TASK_STATE_CANCEL; list_item_del(&task->list); - /* if there're no more DP task, stop LL tick source */ + /* if there're no more DP task, stop LL tick source */ if (list_is_empty(&dp_sch->tasks)) schedule_task_cancel(&dp_sch->ll_tick_src); - /* if the task is waiting on a semaphore - let it run and self-terminate */ + /* if the task is waiting - let it run and self-terminate */ +#if CONFIG_SOF_USERSPACE_APPLICATION k_sem_give(pdata->sem); +#else + k_event_set(pdata->event, DP_TASK_EVENT_CANCEL); +#endif scheduler_dp_unlock(lock_key); /* wait till the task has finished, if there was any task created */ @@ -339,7 +285,7 @@ static int scheduler_dp_task_free(void *data, struct task *task) struct task_dp_pdata *pdata = task->priv_data; int ret; - scheduler_dp_task_cancel(data, task); + scheduler_dp_task_stop(data, task); /* the thread should be terminated at this moment, * abort is safe and will ensure no use after free @@ -349,79 +295,13 @@ static int scheduler_dp_task_free(void *data, struct task *task) pdata->thread_id = NULL; } -#ifdef CONFIG_USERSPACE - if (pdata->sem != &pdata->sem_struct) - k_object_free(pdata->sem); - if (pdata->thread != &pdata->thread_struct) - k_object_free(pdata->thread); -#endif - /* free task stack */ - ret = user_stack_free((__sparse_force void *)pdata->p_stack); + ret = user_stack_free(pdata->p_stack); pdata->p_stack = NULL; - /* all other memory has been allocated as a single malloc, will be freed later by caller */ - return ret; -} - -/* Thread function called in component context, on target core */ -static void dp_thread_fn(void *p1, void *p2, void *p3) -{ - struct task *task = p1; - (void)p2; - (void)p3; - struct task_dp_pdata *task_pdata = task->priv_data; - unsigned int lock_key; - enum task_state state; - bool task_stop; - - do { - /* - * the thread is started immediately after creation, it will stop on semaphore - * Semaphore will be released once the task is ready to process - */ - k_sem_take(task_pdata->sem, K_FOREVER); - - if (task->state == SOF_TASK_STATE_RUNNING) - state = task_run(task); - else - state = task->state; /* to avoid undefined variable warning */ - - lock_key = scheduler_dp_lock(task->core); - /* - * check if task is still running, may have been canceled by external call - * if not, set the state returned by run procedure - */ - if (task->state == SOF_TASK_STATE_RUNNING) { - task->state = state; - switch (state) { - case SOF_TASK_STATE_RESCHEDULE: - /* mark to reschedule, schedule time is already calculated */ - task->state = SOF_TASK_STATE_QUEUED; - break; - - case SOF_TASK_STATE_CANCEL: - case SOF_TASK_STATE_COMPLETED: - /* remove from scheduling */ - list_item_del(&task->list); - break; - - default: - /* illegal state, serious defect, won't happen */ - k_panic(); - } - } - - /* if true exit the while loop, terminate the thread */ - task_stop = task->state == SOF_TASK_STATE_COMPLETED || - task->state == SOF_TASK_STATE_CANCEL; + scheduler_dp_internal_free(task); - scheduler_dp_unlock(lock_key); - } while (!task_stop); - - /* call task_complete */ - if (task->state == SOF_TASK_STATE_COMPLETED) - task_complete(task); + return ret; } static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t start, @@ -430,11 +310,15 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; struct task_dp_pdata *pdata = task->priv_data; unsigned int lock_key; - uint64_t deadline_clock_ticks; - int ret; lock_key = scheduler_dp_lock(cpu_get_id()); + if (task_is_active(task)) { + scheduler_dp_unlock(lock_key); + tr_dbg(&dp_tr, "DP task already active"); + return 0; + } + if (task->state != SOF_TASK_STATE_INIT && task->state != SOF_TASK_STATE_CANCEL && task->state != SOF_TASK_STATE_COMPLETED) { @@ -442,39 +326,6 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta return -EINVAL; } - /* create a zephyr thread for the task */ - pdata->thread_id = k_thread_create(pdata->thread, (__sparse_force void *)pdata->p_stack, - pdata->stack_size, dp_thread_fn, task, NULL, NULL, - CONFIG_DP_THREAD_PRIORITY, task->flags, K_FOREVER); - if (!pdata->thread_id) { - tr_err(&dp_tr, "DP thread creation failed"); - scheduler_dp_unlock(lock_key); - return -ECHILD; - } - - k_thread_access_grant(pdata->thread_id, pdata->sem); - scheduler_dp_grant(pdata->thread_id, cpu_get_id()); - /* pin the thread to specific core */ - ret = k_thread_cpu_pin(pdata->thread_id, task->core); - if (ret < 0) { - tr_err(&dp_tr, "zephyr task pin to core failed"); - goto err; - } - -#ifdef CONFIG_USERSPACE - if (task->flags & K_USER) { - ret = user_memory_init_shared(pdata->thread_id, pdata->mod); - if (ret < 0) { - tr_err(&dp_tr, "user_memory_init_shared() failed"); - goto err; - } - } -#endif /* CONFIG_USERSPACE */ - - /* start the thread, it should immediately stop at a semaphore, so clean it */ - k_sem_init(pdata->sem, 0, 1); - k_thread_start(pdata->thread_id); - /* if there's no DP tasks scheduled yet, run ll tick source task */ if (list_is_empty(&dp_sch->tasks)) schedule_task(&dp_sch->ll_tick_src, 0, 0); @@ -483,30 +334,20 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta task->state = SOF_TASK_STATE_QUEUED; list_item_prepend(&task->list, &dp_sch->tasks); - deadline_clock_ticks = period * CONFIG_SYS_CLOCK_TICKS_PER_SEC; - /* period/deadline is in us - convert to seconds in next step - * or it always will be zero because of integer calculation - */ - deadline_clock_ticks /= 1000000; - - pdata->deadline_clock_ticks = deadline_clock_ticks; - pdata->ll_cycles_to_start = period / LL_TIMER_PERIOD_US; pdata->mod->dp_startup_delay = true; scheduler_dp_unlock(lock_key); tr_dbg(&dp_tr, "DP task scheduled with period %u [us]", (uint32_t)period); return 0; - -err: - /* cleanup - unlock and free all allocated resources */ - scheduler_dp_unlock(lock_key); - k_thread_abort(pdata->thread_id); - return ret; } static struct scheduler_ops schedule_dp_ops = { .schedule_task = scheduler_dp_task_shedule, +#if CONFIG_SOF_USERSPACE_APPLICATION .schedule_task_cancel = scheduler_dp_task_cancel, +#else + .schedule_task_cancel = scheduler_dp_task_stop, +#endif .schedule_task_free = scheduler_dp_task_free, }; @@ -537,107 +378,6 @@ int scheduler_dp_init(void) return 0; } -int scheduler_dp_task_init(struct task **task, - const struct sof_uuid_entry *uid, - const struct task_ops *ops, - struct processing_module *mod, - uint16_t core, - size_t stack_size, - uint32_t options) -{ - void __sparse_cache *p_stack = NULL; - struct sys_heap *const user_heap = mod->dev->drv->user_heap; - - /* memory allocation helper structure */ - struct { - struct task task; - struct task_dp_pdata pdata; - } *task_memory; - - int ret; - - /* must be called on the same core the task will be binded to */ - assert(cpu_get_id() == core); - - /* - * allocate memory - * to avoid multiple malloc operations allocate all required memory as a single structure - * and return pointer to task_memory->task - * As the structure contains zephyr kernel specific data, it must be located in - * shared, non cached memory - */ - task_memory = module_driver_heap_rzalloc(user_heap, SOF_MEM_FLAG_USER | - SOF_MEM_FLAG_COHERENT, sizeof(*task_memory)); - if (!task_memory) { - tr_err(&dp_tr, "memory alloc failed"); - return -ENOMEM; - } - - /* allocate stack - must be aligned and cached so a separate alloc */ - p_stack = user_stack_allocate(stack_size, options); - if (!p_stack) { - tr_err(&dp_tr, "stack alloc failed"); - ret = -ENOMEM; - goto err; - } - - /* internal SOF task init */ - ret = schedule_task_init(&task_memory->task, uid, SOF_SCHEDULE_DP, 0, ops->run, - mod, core, options); - if (ret < 0) { - tr_err(&dp_tr, "schedule_task_init failed"); - goto err; - } - - /* Point to ksem semaphore for kernel threads synchronization */ - /* It will be overwritten for K_USER threads to dynamic ones. */ - task_memory->pdata.sem = &task_memory->pdata.sem_struct; - task_memory->pdata.thread = &task_memory->pdata.thread_struct; - -#ifdef CONFIG_USERSPACE - if (options & K_USER) { - task_memory->pdata.sem = k_object_alloc(K_OBJ_SEM); - if (!task_memory->pdata.sem) { - tr_err(&dp_tr, "Semaphore object allocation failed"); - ret = -ENOMEM; - goto err; - } - - task_memory->pdata.thread = k_object_alloc(K_OBJ_THREAD); - if (!task_memory->pdata.thread) { - tr_err(&dp_tr, "Thread object allocation failed"); - ret = -ENOMEM; - goto err; - } - } -#endif /* CONFIG_USERSPACE */ - - /* initialize other task structures */ - task_memory->task.ops.complete = ops->complete; - task_memory->task.ops.get_deadline = ops->get_deadline; - task_memory->task.state = SOF_TASK_STATE_INIT; - task_memory->task.core = core; - - /* success, fill the structures */ - task_memory->task.priv_data = &task_memory->pdata; - task_memory->pdata.p_stack = p_stack; - task_memory->pdata.stack_size = stack_size; - task_memory->pdata.mod = mod; - *task = &task_memory->task; - - return 0; -err: - /* cleanup - free all allocated resources */ - if (user_stack_free((__sparse_force void *)p_stack)) - tr_err(&dp_tr, "user_stack_free failed!"); - - /* k_object_free looks for a pointer in the list, any invalid value can be passed */ - k_object_free(task_memory->pdata.sem); - k_object_free(task_memory->pdata.thread); - module_driver_heap_free(user_heap, task_memory); - return ret; -} - void scheduler_get_task_info_dp(struct scheduler_props *scheduler_props, uint32_t *data_off_size) { unsigned int lock_key; diff --git a/src/schedule/zephyr_dp_schedule.h b/src/schedule/zephyr_dp_schedule.h new file mode 100644 index 000000000000..2df6f2a83f62 --- /dev/null +++ b/src/schedule/zephyr_dp_schedule.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Marcin Szkudlinski + */ + +#include +#include +#include +#include + +#include + +#include +#include + +struct scheduler_dp_data { + struct list_item tasks; /* list of active dp tasks */ + struct task ll_tick_src; /* LL task - source of DP tick */ + uint32_t last_ll_tick_timestamp;/* a timestamp as k_cycle_get_32 of last LL tick, + * "NOW" for DP deadline calculation + */ +}; + +enum sof_dp_part_type { + SOF_DP_PART_HEAP, + SOF_DP_PART_HEAP_CACHE, + SOF_DP_PART_CFG, + SOF_DP_PART_CFG_CACHE, + SOF_DP_PART_TYPE_COUNT, +}; + +struct ipc4_flat; +struct task_dp_pdata { + k_tid_t thread_id; /* zephyr thread ID */ + struct k_thread *thread; /* pointer to the kernels' thread object */ + struct k_thread thread_struct; /* thread object for kernel threads */ + uint32_t deadline_clock_ticks; /* dp module deadline in Zephyr ticks */ + k_thread_stack_t *p_stack; /* pointer to thread stack */ + struct processing_module *mod; /* the module to be scheduled */ + uint32_t ll_cycles_to_start; /* current number of LL cycles till delayed start */ +#if CONFIG_SOF_USERSPACE_APPLICATION + struct k_sem *sem; /* pointer to semaphore for task scheduling */ + struct ipc4_flat *flat; + unsigned char pend_ipc; + unsigned char pend_proc; + struct k_mem_partition mpart[SOF_DP_PART_TYPE_COUNT]; +#else + struct k_event *event; /* pointer to event for task scheduling */ + struct k_event event_struct; /* event for task scheduling for kernel threads */ +#endif +}; + +void scheduler_dp_recalculate(struct scheduler_dp_data *dp_sch, bool is_ll_post_run); +void dp_thread_fn(void *p1, void *p2, void *p3); +unsigned int scheduler_dp_lock(uint16_t core); +void scheduler_dp_unlock(unsigned int key); +void scheduler_dp_grant(k_tid_t thread_id, uint16_t core); +int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, + const struct task_ops *ops, struct processing_module *mod, + uint16_t core, size_t stack_size, uint32_t options); +void scheduler_dp_internal_free(struct task *task); diff --git a/src/schedule/zephyr_dp_schedule_application.c b/src/schedule/zephyr_dp_schedule_application.c new file mode 100644 index 000000000000..3c063559a9a6 --- /dev/null +++ b/src/schedule/zephyr_dp_schedule_application.c @@ -0,0 +1,600 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2025 Intel Corporation. All rights reserved. + * + * Author: Marcin Szkudlinski + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "zephyr_dp_schedule.h" + +LOG_MODULE_DECLARE(dp_schedule, CONFIG_SOF_LOG_LEVEL); +extern struct tr_ctx dp_tr; + +static struct objpool_head dp_mdom_head = {.list = LIST_INIT(dp_mdom_head.list)}; + +/* Synchronization semaphore for the scheduler thread to wait for DP startup */ +#define DP_SYNC_INIT(i, _) Z_SEM_INITIALIZER(dp_sync[i], 0, 1) +#define DP_SYNC_INIT_LIST LISTIFY(CONFIG_CORE_COUNT, DP_SYNC_INIT, (,)) +static STRUCT_SECTION_ITERABLE_ARRAY(k_sem, dp_sync, CONFIG_CORE_COUNT) = { DP_SYNC_INIT_LIST }; + +struct ipc4_flat { + unsigned int cmd; + int ret; + union { + struct { + struct ipc4_module_bind_unbind bu; + enum bind_type type; + } bind; + struct { + unsigned int trigger_cmd; + enum ipc4_pipeline_state state; + int n_sources; + int n_sinks; + struct sof_source *source[CONFIG_MODULE_MAX_CONNECTIONS]; + struct sof_sink *sink[CONFIG_MODULE_MAX_CONNECTIONS]; + } pipeline_state; + }; +}; + +/* Pack IPC input data */ +static int ipc_thread_flatten(unsigned int cmd, const union scheduler_dp_thread_ipc_param *param, + struct ipc4_flat *flat) +{ + flat->cmd = cmd; + + /* + * FIXME: SOF_IPC4_MOD_* and SOF_IPC4_GLB_* aren't fully orthogonal, but + * so far none of the used ones overlap + */ + switch (cmd) { + case SOF_IPC4_MOD_BIND: + case SOF_IPC4_MOD_UNBIND: + flat->bind.bu = *param->bind_data->ipc4_data; + flat->bind.type = param->bind_data->bind_type; + break; + case SOF_IPC4_GLB_SET_PIPELINE_STATE: + flat->pipeline_state.trigger_cmd = param->pipeline_state.trigger_cmd; + switch (param->pipeline_state.trigger_cmd) { + case COMP_TRIGGER_STOP: + break; + case COMP_TRIGGER_PREPARE: + if (param->pipeline_state.n_sources > CONFIG_MODULE_MAX_CONNECTIONS || + param->pipeline_state.n_sinks > CONFIG_MODULE_MAX_CONNECTIONS) + return -ENOMEM; + + flat->pipeline_state.state = param->pipeline_state.state; + flat->pipeline_state.n_sources = param->pipeline_state.n_sources; + flat->pipeline_state.n_sinks = param->pipeline_state.n_sinks; + /* Up to 2 * CONFIG_MODULE_MAX_CONNECTIONS */ + memcpy(flat->pipeline_state.source, param->pipeline_state.sources, + flat->pipeline_state.n_sources * + sizeof(flat->pipeline_state.source[0])); + memcpy(flat->pipeline_state.sink, param->pipeline_state.sinks, + flat->pipeline_state.n_sinks * + sizeof(flat->pipeline_state.sink[0])); + } + } + + return 0; +} + +/* Unpack IPC data and execute a callback */ +static void ipc_thread_unflatten_run(struct processing_module *pmod, struct ipc4_flat *flat) +{ + const struct module_interface *const ops = pmod->dev->drv->adapter_ops; + + switch (flat->cmd) { + case SOF_IPC4_MOD_BIND: + if (ops->bind) { + struct bind_info bind_data = { + .ipc4_data = &flat->bind.bu, + .bind_type = flat->bind.type, + }; + + flat->ret = ops->bind(pmod, &bind_data); + } else { + flat->ret = 0; + } + break; + case SOF_IPC4_MOD_UNBIND: + if (ops->unbind) { + struct bind_info bind_data = { + .ipc4_data = &flat->bind.bu, + .bind_type = flat->bind.type, + }; + + flat->ret = ops->unbind(pmod, &bind_data); + } else { + flat->ret = 0; + } + break; + case SOF_IPC4_MOD_DELETE_INSTANCE: + flat->ret = ops->free(pmod); + break; + case SOF_IPC4_MOD_INIT_INSTANCE: + flat->ret = ops->init(pmod); + break; + case SOF_IPC4_GLB_SET_PIPELINE_STATE: + switch (flat->pipeline_state.trigger_cmd) { + case COMP_TRIGGER_STOP: + flat->ret = ops->reset(pmod); + break; + case COMP_TRIGGER_PREPARE: + flat->ret = ops->prepare(pmod, + flat->pipeline_state.source, + flat->pipeline_state.n_sources, + flat->pipeline_state.sink, + flat->pipeline_state.n_sinks); + } + } +} + +#define DP_THREAD_IPC_TIMEOUT K_MSEC(100) + +/* Signal an IPC and wait for processing completion */ +int scheduler_dp_thread_ipc(struct processing_module *pmod, unsigned int cmd, + const union scheduler_dp_thread_ipc_param *param) +{ + struct task_dp_pdata *pdata = pmod->dev->task->priv_data; + int ret; + + if (!pmod) { + tr_err(&dp_tr, "no thread module"); + return -EINVAL; + } + + if (cmd == SOF_IPC4_MOD_INIT_INSTANCE) { + /* Wait for the DP thread to start */ + ret = k_sem_take(&dp_sync[pmod->dev->task->core], DP_THREAD_IPC_TIMEOUT); + if (ret < 0) { + tr_err(&dp_tr, "Failed waiting for DP thread to start: %d", ret); + return ret; + } + } + + unsigned int lock_key = scheduler_dp_lock(pmod->dev->task->core); + + /* IPCs are serialised */ + pdata->flat->ret = -ENOSYS; + + ret = ipc_thread_flatten(cmd, param, pdata->flat); + if (!ret) { + pdata->pend_ipc++; + k_sem_give(pdata->sem); + } + + scheduler_dp_unlock(lock_key); + + if (!ret) { + /* Wait for completion */ + ret = k_sem_take(&dp_sync[cpu_get_id()], DP_THREAD_IPC_TIMEOUT); + if (ret < 0) + tr_err(&dp_tr, "Failed waiting for DP thread: %d", ret); + else + ret = pdata->flat->ret; + } + + return ret; +} + +/* Go through all DP tasks and recalculate their readiness and deadlines + * NOT REENTRANT, called with scheduler_dp_lock() held + */ +void scheduler_dp_recalculate(struct scheduler_dp_data *dp_sch, bool is_ll_post_run) +{ + struct list_item *tlist; + struct task *curr_task; + struct task_dp_pdata *pdata; + + list_for_item(tlist, &dp_sch->tasks) { + curr_task = container_of(tlist, struct task, list); + pdata = curr_task->priv_data; + struct processing_module *mod = pdata->mod; + bool trigger_task = false; + + /* decrease number of LL ticks/cycles left till the module reaches its deadline */ + if (mod->dp_startup_delay && is_ll_post_run && pdata->ll_cycles_to_start) { + pdata->ll_cycles_to_start--; + if (!pdata->ll_cycles_to_start) + /* delayed start complete, clear startup delay flag. + * see dp_startup_delay comment for details + */ + mod->dp_startup_delay = false; + } + + if (curr_task->state == SOF_TASK_STATE_QUEUED && + mod->dev->state >= COMP_STATE_ACTIVE) { + /* trigger the task */ + curr_task->state = SOF_TASK_STATE_RUNNING; + trigger_task = true; + pdata->pend_proc++; + k_sem_give(pdata->sem); + } + + if (curr_task->state == SOF_TASK_STATE_RUNNING) { + /* (re) calculate deadline for all running tasks */ + /* get module deadline in us */ + uint32_t deadline = module_get_deadline(mod); + + /* if a deadline cannot be calculated, use a fixed value relative to its + * first start + */ + if (deadline >= UINT32_MAX / 2 && trigger_task) + deadline = module_get_lpt(mod); + + if (deadline < UINT32_MAX) { + /* round down to 1ms */ + deadline = deadline / 1000; + + /* calculate number of ticks */ + deadline = deadline * (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000); + + /* add to "NOW", overflows are OK */ + deadline = dp_sch->last_ll_tick_timestamp + deadline; + + /* set in Zephyr. Note that it may be in past, it does not matter, + * Zephyr still will schedule the thread with earlier deadline + * first + */ + k_thread_absolute_deadline_set(pdata->thread_id, deadline); + } + } + } +} + +/* Thread function called in component context, on target core */ +void dp_thread_fn(void *p1, void *p2, void *p3) +{ + struct task *task = p1; + struct task_dp_pdata *task_pdata = task->priv_data; + struct processing_module *pmod = task_pdata->mod; + unsigned int lock_key; + enum task_state state; + bool task_stop; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + /* The IPC thread is waiting for the thread to be started, it can proceed now. */ + k_sem_give(&dp_sync[task->core]); + comp_info(pmod->dev, "userspace thread started"); + + do { + /* + * The thread is started immediately after creation, it stops here and waits + * for the semaphore to be signalled to handle IPC or process audio data. + */ + k_sem_take(task_pdata->sem, K_FOREVER); + + lock_key = scheduler_dp_lock(task->core); + + unsigned char pend_ipc = task_pdata->pend_ipc, + pend_proc = task_pdata->pend_proc; + + task_pdata->pend_proc = 0; + task_pdata->pend_ipc = 0; + + scheduler_dp_unlock(lock_key); + + /* + * Only 0:1, 1:0 and 1:1 are valid. 0:0 is also possible if IPC and audio + * were signalled in a quick succession before we took the lock above. Any + * value > 1 would mean that we've missed IPCs or LL ticks while in queued / + * idle state, which shouldn't happen. + */ + if (pend_ipc > 1 || pend_proc > 1) { + tr_err(&dp_tr, "Invalid wake up %u:%u", pend_proc, pend_ipc); + continue; + } + + if (pend_ipc) { + /* handle IPC */ + tr_dbg(&dp_tr, "got IPC wake up for %p state %d", pmod, task->state); + ipc_thread_unflatten_run(pmod, task_pdata->flat); + k_sem_give(&dp_sync[task->core]); + } + + if (pend_proc) { + bool ready; + + if (task->state == SOF_TASK_STATE_RUNNING) { + ready = module_is_ready_to_process(pmod, pmod->sources, + pmod->num_of_sources, + pmod->sinks, pmod->num_of_sinks); + } else { + state = task->state; /* to avoid undefined variable warning */ + ready = false; + } + + if (ready) { + if (pmod->dp_startup_delay && !task_pdata->ll_cycles_to_start) { + /* first time run - use delayed start */ + task_pdata->ll_cycles_to_start = + module_get_lpt(pmod) / LL_TIMER_PERIOD_US; + + /* in case LPT < LL cycle - delay at least cycle */ + if (!task_pdata->ll_cycles_to_start) + task_pdata->ll_cycles_to_start = 1; + } + + state = task_run(task); + } + + lock_key = scheduler_dp_lock(task->core); + /* + * check if task is still running, may have been canceled by external call + * if not, set the state returned by run procedure + */ + if (ready && task->state == SOF_TASK_STATE_RUNNING) { + task->state = state; + switch (state) { + case SOF_TASK_STATE_RESCHEDULE: + /* mark to reschedule, schedule time is already calculated */ + task->state = SOF_TASK_STATE_QUEUED; + break; + + case SOF_TASK_STATE_CANCEL: + case SOF_TASK_STATE_COMPLETED: + /* task already removed from scheduling */ + break; + + default: + /* illegal state, serious defect, won't happen */ + k_oops(); + } + } else { + task->state = SOF_TASK_STATE_QUEUED; + } + } else { + lock_key = scheduler_dp_lock(task->core); + } + + /* if true exit the while loop, terminate the thread */ + task_stop = task->state == SOF_TASK_STATE_COMPLETED || + task->state == SOF_TASK_STATE_CANCEL; + + scheduler_dp_unlock(lock_key); + } while (!task_stop); + + /* call task_complete */ + if (task->state == SOF_TASK_STATE_COMPLETED) + task_complete(task); +} + +/* + * Safe to call with partial successful initialisation, + * k_mem_domain_remove_partition() then just returns -ENOENT + */ +static void scheduler_dp_domain_free(struct task_dp_pdata *pdata) +{ + struct processing_module *pmod = pdata->mod; + struct k_mem_domain *mdom = pmod->mdom; + + llext_manager_rm_domain(pmod->dev->ipc_config.id, mdom); + + k_mem_domain_remove_partition(mdom, pdata->mpart + SOF_DP_PART_HEAP); + k_mem_domain_remove_partition(mdom, pdata->mpart + SOF_DP_PART_HEAP_CACHE); + k_mem_domain_remove_partition(mdom, pdata->mpart + SOF_DP_PART_CFG); + k_mem_domain_remove_partition(mdom, pdata->mpart + SOF_DP_PART_CFG_CACHE); + + pmod->mdom = NULL; + objpool_free(&dp_mdom_head, mdom); +} + +/* memory allocation helper structure */ +struct scheduler_dp_task_memory { + struct task task; + struct task_dp_pdata pdata; + struct comp_driver drv; + struct ipc4_flat flat; +}; + +void scheduler_dp_internal_free(struct task *task) +{ + struct task_dp_pdata *pdata = task->priv_data; + + k_object_free(pdata->sem); + k_object_free(pdata->thread); + scheduler_dp_domain_free(pdata); + + mod_free(pdata->mod, container_of(task, struct scheduler_dp_task_memory, task)); +} + +/* Called only in IPC context */ +int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, + const struct task_ops *ops, struct processing_module *mod, + uint16_t core, size_t stack_size, uint32_t options) +{ + k_thread_stack_t *p_stack; + struct scheduler_dp_task_memory *task_memory; + + int ret; + + /* must be called on the same core the task will be bound to */ + assert(cpu_get_id() == core); + + /* + * allocate memory + * to avoid multiple malloc operations allocate all required memory as a single structure + * and return pointer to task_memory->task + * As the structure contains zephyr kernel specific data, it must be located in + * shared, non cached memory + */ + task_memory = mod_alloc_ext(mod, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*task_memory), 0); + if (!task_memory) { + tr_err(&dp_tr, "memory alloc failed"); + return -ENOMEM; + } + + memset(task_memory, 0, sizeof(*task_memory)); + + task_memory->drv = *mod->dev->drv; + mod->dev->drv = &task_memory->drv; + + /* allocate stack - must be aligned and cached so a separate alloc */ + p_stack = user_stack_allocate(stack_size, options); + if (!p_stack) { + tr_err(&dp_tr, "stack alloc failed"); + ret = -ENOMEM; + goto e_tmem; + } + + struct task *ptask = &task_memory->task; + + /* internal SOF task init */ + ret = schedule_task_init(ptask, uid, SOF_SCHEDULE_DP, 0, ops->run, mod, core, options); + if (ret < 0) { + tr_err(&dp_tr, "schedule_task_init failed"); + goto e_stack; + } + + struct task_dp_pdata *pdata = &task_memory->pdata; + + pdata->flat = &task_memory->flat; + + pdata->sem = k_object_alloc(K_OBJ_SEM); + if (!pdata->sem) { + tr_err(&dp_tr, "Event object allocation failed"); + ret = -ENOMEM; + goto e_stack; + } + + pdata->thread = k_object_alloc(K_OBJ_THREAD); + if (!pdata->thread) { + tr_err(&dp_tr, "Thread object allocation failed"); + ret = -ENOMEM; + goto e_kobj; + } + memset(&pdata->thread->arch, 0, sizeof(pdata->thread->arch)); + + /* success, fill the structures */ + pdata->p_stack = p_stack; + pdata->mod = mod; + + /* initialize other task structures */ + ptask->ops.complete = ops->complete; + ptask->ops.get_deadline = ops->get_deadline; + ptask->priv_data = pdata; + list_init(&ptask->list); + *task = ptask; + + /* create a zephyr thread for the task */ + pdata->thread_id = k_thread_create(pdata->thread, p_stack, + stack_size, dp_thread_fn, ptask, NULL, NULL, + CONFIG_DP_THREAD_PRIORITY, ptask->flags, K_FOREVER); + + /* pin the thread to specific core */ + ret = k_thread_cpu_pin(pdata->thread_id, core); + if (ret < 0) { + tr_err(&dp_tr, "zephyr task pin to core failed"); + goto e_thread; + } + + k_thread_access_grant(pdata->thread_id, pdata->sem, &dp_sync[core]); + scheduler_dp_grant(pdata->thread_id, core); + + unsigned int pidx; + size_t size; + uintptr_t start; + struct k_mem_domain *mdom = objpool_alloc(&dp_mdom_head, sizeof(*mdom), + SOF_MEM_FLAG_COHERENT); + + if (!mdom) { + tr_err(&dp_tr, "objpool allocation failed"); + ret = -ENOMEM; + goto e_thread; + } + + mod->mdom = mdom; + + if (!mdom->arch.ptables) { + ret = k_mem_domain_init(mdom, 0, NULL); + if (ret < 0) + goto e_dom; + } + + /* Module heap partition */ + mod_heap_info(mod, &size, &start); + pdata->mpart[SOF_DP_PART_HEAP] = (struct k_mem_partition){ + .start = start, + .size = size, + .attr = K_MEM_PARTITION_P_RW_U_RW, + }; + pdata->mpart[SOF_DP_PART_HEAP_CACHE] = (struct k_mem_partition){ + .start = (uintptr_t)sys_cache_cached_ptr_get((void *)start), + .size = size, + .attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB, + }; + /* Host mailbox partition for additional IPC parameters: read-only */ + pdata->mpart[SOF_DP_PART_CFG] = (struct k_mem_partition){ + .start = (uintptr_t)sys_cache_uncached_ptr_get((void *)MAILBOX_HOSTBOX_BASE), + .size = 4096, + .attr = K_MEM_PARTITION_P_RO_U_RO, + }; + pdata->mpart[SOF_DP_PART_CFG_CACHE] = (struct k_mem_partition){ + .start = (uintptr_t)MAILBOX_HOSTBOX_BASE, + .size = 4096, + .attr = K_MEM_PARTITION_P_RO_U_RO | XTENSA_MMU_CACHED_WB, + }; + + for (pidx = 0; pidx < SOF_DP_PART_TYPE_COUNT; pidx++) { + ret = k_mem_domain_add_partition(mdom, pdata->mpart + pidx); + if (ret < 0) + goto e_dom; + } + + ret = llext_manager_add_domain(mod->dev->ipc_config.id, mdom); + if (ret < 0) { + tr_err(&dp_tr, "failed to add LLEXT to domain %d", ret); + goto e_dom; + } + + /* + * Keep this call last, able to fail, otherwise domain will be removed + * before its thread + */ + ret = k_mem_domain_add_thread(mdom, pdata->thread_id); + if (ret < 0) { + tr_err(&dp_tr, "failed to add thread to domain %d", ret); + goto e_dom; + } + + /* start the thread, it should immediately stop at the semaphore */ + k_sem_init(pdata->sem, 0, 1); + k_thread_start(pdata->thread_id); + + return 0; + +e_dom: + scheduler_dp_domain_free(pdata); +e_thread: + k_thread_abort(pdata->thread_id); +e_kobj: + /* k_object_free looks for a pointer in the list, any invalid value can be passed */ + k_object_free(pdata->thread); + k_object_free(pdata->sem); +e_stack: + user_stack_free(p_stack); +e_tmem: + mod_free(mod, task_memory); + return ret; +} diff --git a/src/schedule/zephyr_dp_schedule_thread.c b/src/schedule/zephyr_dp_schedule_thread.c new file mode 100644 index 000000000000..e21644797310 --- /dev/null +++ b/src/schedule/zephyr_dp_schedule_thread.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2025 Intel Corporation. All rights reserved. + * + * Author: Marcin Szkudlinski + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "zephyr_dp_schedule.h" + +LOG_MODULE_DECLARE(dp_schedule, CONFIG_SOF_LOG_LEVEL); +extern struct tr_ctx dp_tr; + +/* Go through all DP tasks and recalculate their readiness and deadlines + * NOT REENTRANT, should be called with scheduler_dp_lock() + */ +void scheduler_dp_recalculate(struct scheduler_dp_data *dp_sch, bool is_ll_post_run) +{ + struct list_item *tlist; + struct task *curr_task; + struct task_dp_pdata *pdata; + + list_for_item(tlist, &dp_sch->tasks) { + curr_task = container_of(tlist, struct task, list); + pdata = curr_task->priv_data; + struct processing_module *mod = pdata->mod; + bool trigger_task = false; + + /* decrease number of LL ticks/cycles left till the module reaches its deadline */ + if (mod->dp_startup_delay && is_ll_post_run && pdata->ll_cycles_to_start) { + pdata->ll_cycles_to_start--; + if (!pdata->ll_cycles_to_start) + /* delayed start complete, clear startup delay flag. + * see dp_startup_delay comment for details + */ + mod->dp_startup_delay = false; + } + + if (curr_task->state == SOF_TASK_STATE_QUEUED) { + bool mod_ready; + + mod_ready = module_is_ready_to_process(mod, mod->sources, + mod->num_of_sources, + mod->sinks, + mod->num_of_sinks); + if (mod_ready) { + /* trigger the task */ + curr_task->state = SOF_TASK_STATE_RUNNING; + if (mod->dp_startup_delay && !pdata->ll_cycles_to_start) { + /* first time run - use delayed start */ + pdata->ll_cycles_to_start = + module_get_lpt(pdata->mod) / LL_TIMER_PERIOD_US; + + /* in case LPT < LL cycle - delay at least cycle */ + if (!pdata->ll_cycles_to_start) + pdata->ll_cycles_to_start = 1; + } + trigger_task = true; + k_event_post(pdata->event, DP_TASK_EVENT_PROCESS); + } + } + if (curr_task->state == SOF_TASK_STATE_RUNNING) { + /* (re) calculate deadline for all running tasks */ + /* get module deadline in us*/ + uint32_t deadline = module_get_deadline(mod); + + /* if a deadline cannot be calculated, use a fixed value relative to its + * first start + */ + if (deadline >= UINT32_MAX / 2 && trigger_task) + deadline = module_get_lpt(mod); + + if (deadline < UINT32_MAX) { + /* round down to 1ms */ + deadline = deadline / 1000; + + /* calculate number of ticks */ + deadline = deadline * (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000); + + /* add to "NOW", overflows are OK */ + deadline = dp_sch->last_ll_tick_timestamp + deadline; + + /* set in Zephyr. Note that it may be in past, it does not matter, + * Zephyr still will schedule the thread with earlier deadline + * first + */ + k_thread_absolute_deadline_set(pdata->thread_id, deadline); + } + } + } +} + +/* Thread function called in component context, on target core */ +void dp_thread_fn(void *p1, void *p2, void *p3) +{ + struct task *task = p1; + (void)p2; + (void)p3; + struct task_dp_pdata *task_pdata = task->priv_data; + struct scheduler_dp_data *dp_sch = NULL; + unsigned int lock_key; + enum task_state state; + bool task_stop; + + if (!(task->flags & K_USER)) + dp_sch = scheduler_get_data(SOF_SCHEDULE_DP); + + do { + /* + * the thread is started immediately after creation, it will stop on event. + * Event will be signalled once the task is ready to process. + */ + k_event_wait_safe(task_pdata->event, DP_TASK_EVENT_PROCESS | DP_TASK_EVENT_CANCEL, + false, K_FOREVER); + + if (task->state == SOF_TASK_STATE_RUNNING) + state = task_run(task); + else + state = task->state; /* to avoid undefined variable warning */ + + lock_key = scheduler_dp_lock(task->core); + /* + * check if task is still running, may have been canceled by external call + * if not, set the state returned by run procedure + */ + if (task->state == SOF_TASK_STATE_RUNNING) { + task->state = state; + switch (state) { + case SOF_TASK_STATE_RESCHEDULE: + /* mark to reschedule, schedule time is already calculated */ + task->state = SOF_TASK_STATE_QUEUED; + break; + + case SOF_TASK_STATE_CANCEL: + case SOF_TASK_STATE_COMPLETED: + /* remove from scheduling */ + list_item_del(&task->list); + break; + + default: + /* illegal state, serious defect, won't happen */ + k_panic(); + } + } + + /* if true exit the while loop, terminate the thread */ + task_stop = task->state == SOF_TASK_STATE_COMPLETED || + task->state == SOF_TASK_STATE_CANCEL; + /* recalculate all DP tasks readiness and deadlines + * TODO: it should be for all tasks, for all cores + * currently its limited to current core only + */ + if (dp_sch) + scheduler_dp_recalculate(dp_sch, false); + + scheduler_dp_unlock(lock_key); + } while (!task_stop); + + /* call task_complete */ + if (task->state == SOF_TASK_STATE_COMPLETED) + task_complete(task); +} + +int scheduler_dp_task_init(struct task **task, + const struct sof_uuid_entry *uid, + const struct task_ops *ops, + struct processing_module *mod, + uint16_t core, + size_t stack_size, + uint32_t options) +{ + void __sparse_cache *p_stack = NULL; + struct k_heap *const user_heap = mod->dev->drv->user_heap; + + /* memory allocation helper structure */ + struct { + struct task task; /* keep first, used for freeing below */ + struct task_dp_pdata pdata; + } *task_memory; + + int ret; + + /* must be called on the same core the task will be binded to */ + assert(cpu_get_id() == core); + + /* + * allocate memory + * to avoid multiple malloc operations allocate all required memory as a single structure + * and return pointer to task_memory->task + * As the structure contains zephyr kernel specific data, it must be located in + * shared, non cached memory + */ + task_memory = sof_heap_alloc(user_heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*task_memory), 0); + if (!task_memory) { + tr_err(&dp_tr, "memory alloc failed"); + return -ENOMEM; + } + + memset(task_memory, 0, sizeof(*task_memory)); + /* allocate stack - must be aligned and cached so a separate alloc */ + p_stack = user_stack_allocate(stack_size, options); + if (!p_stack) { + tr_err(&dp_tr, "stack alloc failed"); + ret = -ENOMEM; + goto err; + } + + /* internal SOF task init */ + ret = schedule_task_init(&task_memory->task, uid, SOF_SCHEDULE_DP, 0, ops->run, + mod, core, options); + if (ret < 0) { + tr_err(&dp_tr, "schedule_task_init failed"); + goto err; + } + + struct task_dp_pdata *pdata = &task_memory->pdata; + + /* Point to event_struct event for kernel threads synchronization */ + /* It will be overwritten for K_USER threads to dynamic ones. */ + pdata->event = &pdata->event_struct; + pdata->thread = &pdata->thread_struct; + +#ifdef CONFIG_USERSPACE + if (options & K_USER) { + pdata->event = k_object_alloc(K_OBJ_EVENT); + if (!pdata->event) { + tr_err(&dp_tr, "Event object allocation failed"); + ret = -ENOMEM; + goto err; + } + + pdata->thread = k_object_alloc(K_OBJ_THREAD); + if (!pdata->thread) { + tr_err(&dp_tr, "Thread object allocation failed"); + ret = -ENOMEM; + goto err; + } + } +#endif /* CONFIG_USERSPACE */ + + /* initialize other task structures */ + task_memory->task.ops.complete = ops->complete; + task_memory->task.ops.get_deadline = ops->get_deadline; + task_memory->task.state = SOF_TASK_STATE_INIT; + task_memory->task.core = core; + task_memory->task.priv_data = pdata; + + /* success, fill the structures */ + pdata->p_stack = p_stack; + pdata->mod = mod; + *task = &task_memory->task; + + /* create a zephyr thread for the task */ + pdata->thread_id = k_thread_create(pdata->thread, (__sparse_force void *)p_stack, + stack_size, dp_thread_fn, *task, NULL, NULL, + CONFIG_DP_THREAD_PRIORITY, (*task)->flags, K_FOREVER); + + k_thread_access_grant(pdata->thread_id, pdata->event); + scheduler_dp_grant(pdata->thread_id, cpu_get_id()); + + /* pin the thread to specific core */ + ret = k_thread_cpu_pin(pdata->thread_id, core); + if (ret < 0) { + tr_err(&dp_tr, "zephyr task pin to core failed"); + goto e_thread; + } + +#ifdef CONFIG_USERSPACE + if ((*task)->flags & K_USER) { + ret = user_memory_init_shared(pdata->thread_id, pdata->mod); + if (ret < 0) { + tr_err(&dp_tr, "user_memory_init_shared() failed"); + goto e_thread; + } + } +#endif /* CONFIG_USERSPACE */ + + /* start the thread, it should immediately stop at an event */ + k_event_init(pdata->event); + k_thread_start(pdata->thread_id); + + return 0; + +e_thread: + k_thread_abort(pdata->thread_id); +err: + /* cleanup - free all allocated resources */ + if (user_stack_free((__sparse_force void *)p_stack)) + tr_err(&dp_tr, "user_stack_free failed!"); + + /* k_object_free looks for a pointer in the list, any invalid value can be passed */ + k_object_free(task_memory->pdata.event); + k_object_free(task_memory->pdata.thread); + sof_heap_free(user_heap, task_memory); + return ret; +} + +void scheduler_dp_internal_free(struct task *task) +{ + struct task_dp_pdata *pdata = task->priv_data; + +#ifdef CONFIG_USERSPACE + if (pdata->event != &pdata->event_struct) + k_object_free(pdata->event); + if (pdata->thread != &pdata->thread_struct) + k_object_free(pdata->thread); +#endif + + /* task is the first member in task_memory above */ + sof_heap_free(pdata->mod->dev->drv->user_heap, task); +} diff --git a/src/schedule/zephyr_ll.c b/src/schedule/zephyr_ll.c index 851fd9a96a98..575a82d91dda 100644 --- a/src/schedule/zephyr_ll.c +++ b/src/schedule/zephyr_ll.c @@ -30,6 +30,10 @@ struct zephyr_ll { unsigned int n_tasks; /* task counter */ struct ll_schedule_domain *ll_domain; /* scheduling domain */ unsigned int core; /* core ID of this instance */ +#if CONFIG_SOF_USERSPACE_LL + struct k_mutex *lock; /* mutex for userspace */ +#endif + struct k_heap *heap; }; /* per-task scheduler data */ @@ -41,17 +45,26 @@ struct zephyr_ll_pdata { static void zephyr_ll_lock(struct zephyr_ll *sch, uint32_t *flags) { +#if CONFIG_SOF_USERSPACE_LL + k_mutex_lock(sch->lock, K_FOREVER); +#else irq_local_disable(*flags); +#endif } static void zephyr_ll_unlock(struct zephyr_ll *sch, uint32_t *flags) { +#if CONFIG_SOF_USERSPACE_LL + k_mutex_unlock(sch->lock); +#else irq_local_enable(*flags); +#endif } static void zephyr_ll_assert_core(const struct zephyr_ll *sch) { - assert(CONFIG_CORE_COUNT == 1 || sch->core == cpu_get_id()); + assert(CONFIG_CORE_COUNT == 1 || IS_ENABLED(CONFIG_SOF_USERSPACE_LL) || + sch->core == cpu_get_id()); } /* Locking: caller should hold the domain lock */ @@ -176,6 +189,8 @@ static void zephyr_ll_run(void *data) struct list_item *list, *tmp, task_head = LIST_INIT(task_head); uint32_t flags; + tr_dbg(&ll_tr, "entry"); + zephyr_ll_lock(sch, &flags); /* @@ -216,7 +231,7 @@ static void zephyr_ll_run(void *data) if (state != SOF_TASK_STATE_COMPLETED && state != SOF_TASK_STATE_RESCHEDULE) { tr_err(&ll_tr, - "zephyr_ll_run: invalid return state %u", + "invalid return state %u", state); state = SOF_TASK_STATE_RESCHEDULE; } @@ -248,8 +263,11 @@ static void zephyr_ll_run(void *data) zephyr_ll_unlock(sch, &flags); +#ifndef CONFIG_SOF_USERSPACE_LL + /* TODO: to be replaced with direct function calls */ notifier_event(sch, NOTIFIER_ID_LL_POST_RUN, NOTIFIER_TARGET_CORE_LOCAL, NULL, 0); +#endif } static void schedule_ll_callback(void *data) @@ -345,6 +363,15 @@ static int zephyr_ll_task_schedule_common(struct zephyr_ll *sch, struct task *ta tr_err(&ll_tr, "cannot register domain %d", ret); +#if CONFIG_SOF_USERSPACE_LL + k_thread_access_grant(zephyr_domain_thread_tid(sch->ll_domain), sch->lock); + + tr_dbg(&ll_tr, "granting access to lock %p for thread %p", sch->lock, + zephyr_domain_thread_tid(sch->ll_domain)); + tr_dbg(&ll_tr, "granting access to domain lock %p for thread %p", &sch->ll_domain->lock, + zephyr_domain_thread_tid(sch->ll_domain)); +#endif + return 0; } @@ -432,7 +459,7 @@ static int zephyr_ll_task_free(void *data, struct task *task) /* Protect against racing with schedule_task() */ zephyr_ll_lock(sch, &flags); task->priv_data = NULL; - rfree(pdata); + sof_heap_free(sch->heap, pdata); zephyr_ll_unlock(sch, &flags); return 0; @@ -493,14 +520,26 @@ static const struct scheduler_ops zephyr_ll_ops = { .scheduler_free = zephyr_ll_scheduler_free, }; +#if CONFIG_SOF_USERSPACE_LL +struct task *zephyr_ll_task_alloc(void) +{ + return sof_heap_alloc(zephyr_ll_user_heap(), SOF_MEM_FLAG_USER, + sizeof(struct task), sizeof(void *)); +} +#endif /* CONFIG_SOF_USERSPACE_LL */ + int zephyr_ll_task_init(struct task *task, const struct sof_uuid_entry *uid, uint16_t type, uint16_t priority, enum task_state (*run)(void *data), void *data, uint16_t core, uint32_t flags) { struct zephyr_ll_pdata *pdata; + struct k_heap *heap = sof_sys_heap_get(); + int alloc_flags = SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT; int ret; + tr_dbg(&ll_tr, "ll-scheduler task %p init", data); + if (task->priv_data) return -EEXIST; @@ -509,13 +548,18 @@ int zephyr_ll_task_init(struct task *task, if (ret < 0) return ret; - pdata = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT, - sizeof(*pdata)); +#if CONFIG_SOF_USERSPACE_LL + heap = zephyr_ll_user_heap(); + alloc_flags = SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT; +#endif + pdata = sof_heap_alloc(heap, alloc_flags, sizeof(*pdata), 0); if (!pdata) { tr_err(&ll_tr, "alloc failed"); return -ENOMEM; } + memset(pdata, 0, sizeof(*pdata)); + k_sem_init(&pdata->sem, 0, 1); task->priv_data = pdata; @@ -529,17 +573,43 @@ EXPORT_SYMBOL(zephyr_ll_task_init); int zephyr_ll_scheduler_init(struct ll_schedule_domain *domain) { struct zephyr_ll *sch; + int core = cpu_get_id(); + struct k_heap *heap = sof_sys_heap_get(); + int flags = SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT; + +#if CONFIG_SOF_USERSPACE_LL + heap = zephyr_ll_user_heap(); + flags = SOF_MEM_FLAG_USER; +#endif + tr_dbg(&ll_tr, "init on core %d", core); /* initialize per-core scheduler private data */ - sch = rzalloc(SOF_MEM_FLAG_KERNEL, sizeof(*sch)); + sch = sof_heap_alloc(heap, flags, sizeof(*sch), 0); if (!sch) { tr_err(&ll_tr, "allocation failed"); return -ENOMEM; } + + memset(sch, 0, sizeof(*sch)); + list_init(&sch->tasks); sch->ll_domain = domain; - sch->core = cpu_get_id(); + sch->core = core; sch->n_tasks = 0; + sch->heap = heap; + +#if CONFIG_SOF_USERSPACE_LL + /* Allocate mutex dynamically for userspace access */ + sch->lock = k_object_alloc(K_OBJ_MUTEX); + if (!sch->lock) { + tr_err(&ll_tr, "mutex allocation failed"); + sof_heap_free(sch->heap, sch); + return -ENOMEM; + } + k_mutex_init(sch->lock); + + tr_dbg(&ll_tr, "ll-scheduler init done, sch %p sch->lock %p", sch, sch->lock); +#endif scheduler_init(domain->type, &zephyr_ll_ops, sch); diff --git a/src/schedule/zephyr_ll_user.c b/src/schedule/zephyr_ll_user.c new file mode 100644 index 000000000000..aa33807b4aa3 --- /dev/null +++ b/src/schedule/zephyr_ll_user.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2026 Intel Corporation. + +#include +#include +#include + +#include + +#include + +LOG_MODULE_DECLARE(ll_schedule, CONFIG_SOF_LOG_LEVEL); + +/** + * Memory resources for userspace LL scheduler + * + * This structure encapsulates the memory management resources required for the + * low-latency (LL) scheduler in userspace mode. It provides memory isolation + * and heap management for LL scheduler threads. + */ +struct zephyr_ll_mem_resources { + struct k_mem_domain mem_domain; /**< Memory domain for LL thread isolation */ + struct k_heap *heap; /**< Heap allocator for LL scheduler memory */ +}; + +static struct zephyr_ll_mem_resources ll_mem_resources; + +static struct k_heap *zephyr_ll_heap_init(void) +{ + struct k_heap *heap = module_driver_heap_init(); + struct k_mem_partition mem_partition; + int ret; + + /* + * TODO: the size of LL heap should be independently configurable and + * not tied to CONFIG_SOF_ZEPHYR_USERSPACE_MODULE_HEAP_SIZE + */ + + if (!heap) { + tr_err(&ll_tr, "heap alloc fail"); + k_panic(); + } + + /* Create memory partition for sch_data array */ + mem_partition.start = (uintptr_t)sys_cache_cached_ptr_get(heap->heap.init_mem); + mem_partition.size = heap->heap.init_bytes; + mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB; + + ret = k_mem_domain_add_partition(&ll_mem_resources.mem_domain, &mem_partition); + tr_dbg(&ll_tr, "init ll heap %p, size %u (cached), ret %d", + (void *)mem_partition.start, heap->heap.init_bytes, ret); + if (ret) + k_panic(); + + mem_partition.start = (uintptr_t)sys_cache_uncached_ptr_get(heap->heap.init_mem); + mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW; + ret = k_mem_domain_add_partition(&ll_mem_resources.mem_domain, &mem_partition); + tr_dbg(&ll_tr, "init ll heap %p, size %u (uncached), ret %d", + (void *)mem_partition.start, heap->heap.init_bytes, ret); + if (ret) + k_panic(); + + return heap; +} + +void zephyr_ll_user_resources_init(void) +{ + k_mem_domain_init(&ll_mem_resources.mem_domain, 0, NULL); + + ll_mem_resources.heap = zephyr_ll_heap_init(); + + /* attach common partition to LL domain */ + user_memory_attach_common_partition(zephyr_ll_mem_domain()); +} + +struct k_heap *zephyr_ll_user_heap(void) +{ + return ll_mem_resources.heap; +} + +struct k_mem_domain *zephyr_ll_mem_domain(void) +{ + return &ll_mem_resources.mem_domain; +} diff --git a/src/trace/dma-trace.c b/src/trace/dma-trace.c index 8779d71582ab..0523a362e397 100644 --- a/src/trace/dma-trace.c +++ b/src/trace/dma-trace.c @@ -96,7 +96,7 @@ static enum task_state trace_work(void *data) size = dma_copy_to_host(&d->dc, config, d->posn.host_offset, buffer->r_ptr, size); if (size < 0) { - tr_err(&dt_tr, "trace_work(): dma_copy_to_host() failed"); + tr_err(&dt_tr, "dma_copy_to_host() failed"); goto out; } @@ -152,7 +152,7 @@ int dma_trace_init_early(struct sof *sof) sof->dmat = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->dmat)); if (!sof->dmat) { mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_init_early(): alloc failed"); + "alloc failed"); return -ENOMEM; } @@ -171,7 +171,7 @@ int dma_trace_init_early(struct sof *sof) err: mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_init_early() failed: %d", ret); + "failed: %d", ret); rfree(sof->dmat); sof->dmat = NULL; @@ -184,11 +184,11 @@ int dma_trace_init_complete(struct dma_trace_data *d) { int ret = 0; - tr_info(&dt_tr, "dma_trace_init_complete()"); + tr_info(&dt_tr, "entry"); if (!d) { mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_init_complete(): failed, no dma_trace_data"); + "failed, no dma_trace_data"); return -ENOMEM; } @@ -196,7 +196,7 @@ int dma_trace_init_complete(struct dma_trace_data *d) ret = dma_copy_new(&d->dc); if (ret < 0) { mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_init_complete(): dma_copy_new() failed: %d", ret); + "dma_copy_new() failed: %d", ret); goto out; } #if CONFIG_ZEPHYR_NATIVE_DRIVERS @@ -208,7 +208,7 @@ int dma_trace_init_complete(struct dma_trace_data *d) #endif if (ret < 0) { mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_init_complete(): dma_get_attribute() failed: %d", ret); + "dma_get_attribute() failed: %d", ret); goto out; } @@ -268,7 +268,7 @@ static int dma_trace_buffer_init(struct dma_trace_data *d) if (!d || !d->dc.dmac) { mtrace_printf(LOG_LEVEL_ERROR, - "dma_trace_buffer_init() failed, no DMAC! d=%p", d); + "failed, no DMAC! d=%p", d); return -ENODEV; } #if CONFIG_ZEPHYR_NATIVE_DRIVERS @@ -285,7 +285,7 @@ static int dma_trace_buffer_init(struct dma_trace_data *d) buf = rballoc_align(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, DMA_TRACE_LOCAL_SIZE, addr_align); if (!buf) { - mtrace_printf(LOG_LEVEL_ERROR, "dma_trace_buffer_init(): alloc failed"); + mtrace_printf(LOG_LEVEL_ERROR, "alloc failed"); return -ENOMEM; } @@ -378,7 +378,7 @@ int dma_trace_enable(struct dma_trace_data *d) /* validate DMA context */ if (!d->dc.dmac || !d->dc.chan) { - tr_err_atomic(&dt_tr, "dma_trace_enable(): not valid"); + tr_err_atomic(&dt_tr, "not valid"); err = -ENODEV; goto out; } @@ -544,7 +544,7 @@ static void dtrace_add_event(const char *e, uint32_t length) trace_data->dropped_entries; trace_data->dropped_entries = 0; mtrace_printf(LOG_LEVEL_WARNING, - "dtrace_add_event(): number of dropped logs = %u", + "number of dropped logs = %u", tmp_dropped_entries); } } diff --git a/src/trace/trace.c b/src/trace/trace.c index f73474404e2b..bc17c848a902 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -500,7 +500,7 @@ void trace_init(struct sof *sof) { sof->trace = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->trace)); if (!sof->trace) { - mtrace_printf(LOG_LEVEL_ERROR, "trace_init(): allocation failed"); + mtrace_printf(LOG_LEVEL_ERROR, "allocation failed"); sof_panic(SOF_IPC_PANIC_IPC); } diff --git a/test/cmocka/src/CMakeLists.txt b/test/cmocka/src/CMakeLists.txt index c69f777bf575..2c244aea9d0d 100644 --- a/test/cmocka/src/CMakeLists.txt +++ b/test/cmocka/src/CMakeLists.txt @@ -2,5 +2,4 @@ add_subdirectory(audio) add_subdirectory(lib) -add_subdirectory(list) add_subdirectory(math) diff --git a/test/cmocka/src/audio/buffer/buffer_copy.c b/test/cmocka/src/audio/buffer/buffer_copy.c index ca2c6d6bacc5..f4e958d7fe19 100644 --- a/test/cmocka/src/audio/buffer/buffer_copy.c +++ b/test/cmocka/src/audio/buffer/buffer_copy.c @@ -29,8 +29,8 @@ static void test_audio_buffer_copy_underrun(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *snk = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *src = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *snk = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(src); assert_non_null(snk); @@ -56,8 +56,8 @@ static void test_audio_buffer_copy_overrun(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *snk = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *src = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *snk = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(src); assert_non_null(snk); @@ -85,8 +85,8 @@ static void test_audio_buffer_copy_success(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *snk = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *src = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *snk = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(src); assert_non_null(snk); @@ -111,8 +111,8 @@ static void test_audio_buffer_copy_fit_space_constraint(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *snk = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *src = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *snk = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(src); assert_non_null(snk); @@ -139,8 +139,8 @@ static void test_audio_buffer_copy_fit_no_space_constraint(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *snk = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *src = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *snk = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(src); assert_non_null(snk); diff --git a/test/cmocka/src/audio/buffer/buffer_new.c b/test/cmocka/src/audio/buffer/buffer_new.c index b1e11fc1de50..1561c94ec675 100644 --- a/test/cmocka/src/audio/buffer/buffer_new.c +++ b/test/cmocka/src/audio/buffer/buffer_new.c @@ -27,7 +27,7 @@ static void test_audio_buffer_new(void **state) .size = 256 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buf = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/buffer/buffer_wrap.c b/test/cmocka/src/audio/buffer/buffer_wrap.c index 675875fe527f..a1fc37383274 100644 --- a/test/cmocka/src/audio/buffer/buffer_wrap.c +++ b/test/cmocka/src/audio/buffer/buffer_wrap.c @@ -27,7 +27,7 @@ static void test_audio_buffer_write_fill_10_bytes_and_write_5(void **state) .size = 10 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buf = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/buffer/buffer_write.c b/test/cmocka/src/audio/buffer/buffer_write.c index f6b9216cd3ef..3fd5504560d8 100644 --- a/test/cmocka/src/audio/buffer/buffer_write.c +++ b/test/cmocka/src/audio/buffer/buffer_write.c @@ -28,7 +28,7 @@ static void test_audio_buffer_write_10_bytes_out_of_256_and_read_back .size = 256 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buf = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); @@ -63,7 +63,7 @@ static void test_audio_buffer_fill_10_bytes(void **state) .size = 10 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buf = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 305a6846966c..226128b220d2 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index aa704a1af92b..b5ff8770eec2 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -40,6 +40,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index ea8cad0bd79e..c0dbb8a0a4fc 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -10,6 +10,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c diff --git a/test/cmocka/src/audio/module_adapter_test.c b/test/cmocka/src/audio/module_adapter_test.c index 29140e4581e9..81ec6cadc1b7 100644 --- a/test/cmocka/src/audio/module_adapter_test.c +++ b/test/cmocka/src/audio/module_adapter_test.c @@ -77,7 +77,7 @@ void module_adapter_test_free(struct processing_module_test_data *test_data) } for (i = 0; i < test_data->num_sources; i++) { - free_test_sink(test_data->sources[i]); + free_test_source(test_data->sources[i]); test_free(test_data->input_buffers[i]); } diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 67b10f77270d..a4a72613fd6b 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -25,6 +25,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c diff --git a/test/cmocka/src/audio/mux/demux_copy.c b/test/cmocka/src/audio/mux/demux_copy.c index 4934ab6dbdaa..8e331446bbf4 100644 --- a/test/cmocka/src/audio/mux/demux_copy.c +++ b/test/cmocka/src/audio/mux/demux_copy.c @@ -188,6 +188,9 @@ static int teardown_test_case(void **state) struct test_data *td = *((struct test_data **)state); int i; + rfree(td->mod->input_buffers); + rfree(td->mod->output_buffers); + free_test_source(td->source); for (i = 0; i < MUX_MAX_STREAMS; ++i) @@ -339,8 +342,10 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); ret = cmocka_run_group_tests(tests, setup_group, NULL); - for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) + for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) { free(tests[ti].initial_state); + free((void *)tests[ti].name); + } return ret; } diff --git a/test/cmocka/src/audio/mux/mux_copy.c b/test/cmocka/src/audio/mux/mux_copy.c index 97b7be7b9076..66b21b0df27c 100644 --- a/test/cmocka/src/audio/mux/mux_copy.c +++ b/test/cmocka/src/audio/mux/mux_copy.c @@ -211,6 +211,9 @@ static int teardown_test_case(void **state) struct test_data *td = *((struct test_data **)state); int i; + rfree(td->mod->input_buffers); + rfree(td->mod->output_buffers); + for (i = 0; i < MUX_MAX_STREAMS; ++i) free_test_source(td->sources[i]); @@ -357,8 +360,10 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); ret = cmocka_run_group_tests(tests, setup_group, NULL); - for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) + for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) { free(tests[ti].initial_state); + free((void *)tests[ti].name); + } return ret; } diff --git a/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c b/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c index dea28ce65401..e911f0238162 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c +++ b/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c @@ -24,6 +24,7 @@ static int setup(void **state) static int teardown(void **state) { + free_standard_connect_objects(*state); free(*state); return 0; } diff --git a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c index 35899b14b297..de05f8e3b284 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c +++ b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c @@ -30,7 +30,7 @@ struct pipeline_connect_data *get_standard_connect_objects(void) struct pipeline_connect_data *pipeline_connect_data = calloc (sizeof(struct pipeline_connect_data), 1); - struct pipeline *pipe = calloc(sizeof(struct pipeline), 1); + struct pipeline *pipe = &pipeline_connect_data->p; pipe->frames_per_sched = 5; pipe->pipeline_id = PIPELINE_ID_SAME; @@ -83,7 +83,14 @@ struct pipeline_connect_data *get_standard_connect_objects(void) comp_buffer_reset_source_list(buffer_2); pipeline_connect_data->b2 = buffer_2; - pipeline_connect_data->p = *pipe; - return pipeline_connect_data; } + +void free_standard_connect_objects(struct pipeline_connect_data *data) +{ + free(data->p.pipe_task); + free(data->p.sched_comp); + free(data->second); + free(data->b1); + free(data->b2); +} diff --git a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h index 6a8c0fce1a12..60eedabbd43b 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h +++ b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h @@ -32,6 +32,7 @@ struct pipeline_connect_data { }; struct pipeline_connect_data *get_standard_connect_objects(void); +void free_standard_connect_objects(struct pipeline_connect_data *data); void cleanup_test_data(struct pipeline_connect_data *data); diff --git a/test/cmocka/src/audio/pipeline/pipeline_free.c b/test/cmocka/src/audio/pipeline/pipeline_free.c index d4d441012a29..9878f4f5e42a 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_free.c +++ b/test/cmocka/src/audio/pipeline/pipeline_free.c @@ -23,7 +23,7 @@ #endif /* mock free() - dont free as we inspect contents */ -void rfree(void *ptr) +void sof_heap_free(struct k_heap *heap, void *addr) { } @@ -36,6 +36,7 @@ static int setup(void **state) static int teardown(void **state) { + free_standard_connect_objects(*state); free(*state); return 0; } diff --git a/test/cmocka/src/audio/pipeline/pipeline_new.c b/test/cmocka/src/audio/pipeline/pipeline_new.c index dda5d1a5c020..a68afe49e4be 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_new.c +++ b/test/cmocka/src/audio/pipeline/pipeline_new.c @@ -49,12 +49,18 @@ static void test_audio_pipeline_pipeline_new_creation(void **state) struct pipeline_new_setup_data *test_data = *state; /*Testing component*/ - struct pipeline *result = pipeline_new(test_data->pipe_id, + struct pipeline *result = pipeline_new(NULL, + test_data->pipe_id, test_data->priority, - test_data->comp_id); + test_data->comp_id, + NULL); /*Pipeline should have been created so pointer can't be null*/ assert_non_null(result); + + rfree(result->msg->tx_data); + rfree(result->msg); + rfree(result); } int main(void) diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index d89927578222..0385441e5878 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/volume/volume_process.c b/test/cmocka/src/audio/volume/volume_process.c index 10afdd1276a3..389a4e75a503 100644 --- a/test/cmocka/src/audio/volume/volume_process.c +++ b/test/cmocka/src/audio/volume/volume_process.c @@ -315,7 +315,7 @@ int main(void) struct vol_test_parameters *parameters; uint32_t volume_values[] = {VOL_MAX, VOL_ZERO_DB, VOL_MINUS_80DB}; int num_tests = ARRAY_SIZE(test_parameters) * ARRAY_SIZE(volume_values); - int i, j; + int i, j, ret; parameters = test_calloc(num_tests, sizeof(struct vol_test_parameters)); for (i = 0; i < ARRAY_SIZE(test_parameters); i++) { @@ -338,5 +338,9 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); + ret = cmocka_run_group_tests(tests, NULL, NULL); + + test_free(parameters); + + return ret; } diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index cb116c5f8908..60b6215c4cd5 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -63,15 +64,88 @@ void WEAK *rbrealloc_align(void *ptr, uint32_t flags, { (void)flags; (void)old_bytes; + (void)alignment; return realloc(ptr, bytes); } +void WEAK *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment) +{ + (void)flags; + (void)alignment; + + return malloc(bytes); +} + +void WEAK *rmalloc(uint32_t flags, size_t bytes) +{ + (void)flags; + + return malloc(bytes); +} + void WEAK rfree(void *ptr) { free(ptr); } +void WEAK *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment) +{ + void *ret; + (void)mod; + (void)alignment; + + ret = malloc(size); + + assert(ret); + + return ret; +} + +void WEAK *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, + size_t alignment) +{ + void *ret; + (void)mod; + (void)flags; + (void)alignment; + + ret = malloc(size); + + assert(ret); + + return ret; +} + +int WEAK mod_free(struct processing_module *mod, const void *ptr) +{ + (void)mod; + free((void *)ptr); + return 0; +} + +struct k_heap * WEAK sof_sys_heap_get(void) +{ + return NULL; +} + +void WEAK *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, + size_t alignment) +{ + (void)heap; + (void)flags; + (void)alignment; + + return malloc(bytes); +} + +void WEAK sof_heap_free(struct k_heap *heap, void *addr) +{ + (void)heap; + + free(addr); +} + int WEAK memcpy_s(void *dest, size_t dest_size, const void *src, size_t count) { diff --git a/test/cmocka/src/lib/fast-get/fast-get-tests.c b/test/cmocka/src/lib/fast-get/fast-get-tests.c index b7041abd827b..557b2c243425 100644 --- a/test/cmocka/src/lib/fast-get/fast-get-tests.c +++ b/test/cmocka/src/lib/fast-get/fast-get-tests.c @@ -72,12 +72,12 @@ static void test_simple_fast_get_put(void **state) (void)state; /* unused */ - ret = fast_get(testdata[0], sizeof(testdata[0])); + ret = fast_get(NULL, testdata[0], sizeof(testdata[0])); assert(ret); assert(!memcmp(ret, testdata[0], sizeof(testdata[0]))); - fast_put(ret); + fast_put(NULL, ret); } static void test_fast_get_size_missmatch_test(void **state) @@ -86,15 +86,15 @@ static void test_fast_get_size_missmatch_test(void **state) (void)state; /* unused */ - ret[0] = fast_get(testdata[0], sizeof(testdata[0])); + ret[0] = fast_get(NULL, testdata[0], sizeof(testdata[0])); assert(ret[0]); assert(!memcmp(ret[0], testdata[0], sizeof(testdata[0]))); - ret[1] = fast_get(testdata[0], sizeof(testdata[0]) + 1); + ret[1] = fast_get(NULL, testdata[0], sizeof(testdata[0]) + 1); assert(!ret[1]); - fast_put(ret); + fast_put(NULL, ret); } static void test_over_32_fast_gets_and_puts(void **state) @@ -105,13 +105,13 @@ static void test_over_32_fast_gets_and_puts(void **state) (void)state; /* unused */ for (i = 0; i < ARRAY_SIZE(copy); i++) - copy[i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy); i++) assert(!memcmp(copy[i], testdata[i], sizeof(testdata[0]))); for (i = 0; i < ARRAY_SIZE(copy); i++) - fast_put(copy[i]); + fast_put(NULL, copy[i]); } static void test_fast_get_refcounting(void **state) @@ -121,10 +121,10 @@ static void test_fast_get_refcounting(void **state) (void)state; /* unused */ for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - copy[0][i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[0][i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - copy[1][i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[1][i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) assert(copy[0][i] == copy[1][i]); @@ -133,13 +133,13 @@ static void test_fast_get_refcounting(void **state) assert(!memcmp(copy[0][i], testdata[i], sizeof(testdata[0]))); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - fast_put(copy[0][i]); + fast_put(NULL, copy[0][i]); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) assert(!memcmp(copy[1][i], testdata[i], sizeof(testdata[0]))); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - fast_put(copy[1][i]); + fast_put(NULL, copy[1][i]); } int main(void) diff --git a/test/cmocka/src/list/CMakeLists.txt b/test/cmocka/src/list/CMakeLists.txt deleted file mode 100644 index 5b8c5699512e..000000000000 --- a/test/cmocka/src/list/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -cmocka_test(list_init - list_init.c -) - -cmocka_test(list_is_empty - list_is_empty.c -) - -cmocka_test(list_item_append - list_item_append.c -) - -cmocka_test(list_item_del - list_item_del.c -) - -cmocka_test(list_item_is_last - list_item_is_last.c -) - -cmocka_test(list_item_prepend - list_item_prepend.c -) - -cmocka_test(list_item - list_item.c -) diff --git a/test/cmocka/src/list/list_init.c b/test/cmocka/src/list/list_init.c deleted file mode 100644 index 08ac2a9f0c4f..000000000000 --- a/test/cmocka/src/list/list_init.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include - -static void test_list_list_init_prev_equal_to_root(void **state) -{ - (void) state; /* unused */ - - struct list_item list = {.prev = NULL, .next = NULL}; - - list_init(&list); - - assert_ptr_equal(&list, list.prev); -} - -static void test_list_list_init_next_equal_to_root(void **state) -{ - (void) state; /* unused */ - - struct list_item list = {.prev = NULL, .next = NULL}; - - list_init(&list); - - assert_ptr_equal(&list, list.next); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_init_prev_equal_to_root), - cmocka_unit_test(test_list_list_init_next_equal_to_root), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/cmocka/src/list/list_is_empty.c b/test/cmocka/src/list/list_is_empty.c deleted file mode 100644 index 300967dd80ec..000000000000 --- a/test/cmocka/src/list/list_is_empty.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -static void test_list_list_is_empty_when_empty_then_true(void **state) -{ - (void) state; /* unused */ - - struct list_item list; - - list_init(&list); - - assert_true(list_is_empty(&list)); -} - -static void test_list_list_is_empty_when_not_empty_then_false(void **state) -{ - (void) state; /* unused */ - - struct list_item list, item; - - list_init(&list); - list_init(&item); - - list_item_append(&item, &list); - - assert_false(list_is_empty(&list)); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_is_empty_when_empty_then_true), - cmocka_unit_test(test_list_list_is_empty_when_not_empty_then_false), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/cmocka/src/list/list_item.c b/test/cmocka/src/list/list_item.c deleted file mode 100644 index d8d0b45ab2a8..000000000000 --- a/test/cmocka/src/list/list_item.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -struct test_list_container { - void *field1; - struct list_item list; - void *field2; -}; - -static void test_list_list_item_when_valid_offset_then_ptr_equal(void **state) -{ - (void) state; /* unused */ - - struct test_list_container container; - - list_init(&(container.list)); - - struct test_list_container *result_container = list_item( - &(container.list), struct test_list_container, list); - - assert_ptr_equal(result_container, &container); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_item_when_valid_offset_then_ptr_equal), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/cmocka/src/list/list_item_append.c b/test/cmocka/src/list/list_item_append.c deleted file mode 100644 index ff4ba2f7f68c..000000000000 --- a/test/cmocka/src/list/list_item_append.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -struct test_data { - struct list_item *head; - struct list_item *tail_minus_1; - struct list_item *tail; -}; - -static int setup(void **state) -{ - struct test_data *data = malloc(sizeof(struct test_data)); - - if (!data) - return -1; - - data->head = malloc(sizeof(struct list_item)); - data->tail_minus_1 = malloc(sizeof(struct list_item)); - data->tail = malloc(sizeof(struct list_item)); - - if (!data->head || !data->tail_minus_1 - || !data->tail) { - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - - return -1; - } - - list_init(data->head); - list_init(data->tail_minus_1); - list_init(data->tail); - - list_item_append(data->tail_minus_1, data->head); - list_item_append(data->tail, data->head); - - *state = data; - return 0; -} - -static int teardown(void **state) -{ - struct test_data *data = *state; - - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - return 0; -} - -static void test_list_list_item_append_head_prev_is_tail(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->head->prev, data->tail); -} - -static void test_list_list_item_append_head_next_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->head->next, data->tail_minus_1); -} - -static void test_list_list_item_append_tail_minus_1_prev_is_head(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail_minus_1->prev, data->head); -} - -static void test_list_list_item_append_tail_minus_1_next_is_tail(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail_minus_1->next, data->tail); -} - -static void test_list_list_item_append_tail_prev_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail->prev, data->tail_minus_1); -} - -static void test_list_list_item_append_tail_next_is_head(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail->next, data->head); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_item_append_head_prev_is_tail), - cmocka_unit_test(test_list_list_item_append_head_next_is_tail_minus_1), - cmocka_unit_test(test_list_list_item_append_tail_minus_1_prev_is_head), - cmocka_unit_test(test_list_list_item_append_tail_minus_1_next_is_tail), - cmocka_unit_test(test_list_list_item_append_tail_prev_is_tail_minus_1), - cmocka_unit_test(test_list_list_item_append_tail_next_is_head), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, setup, teardown); -} diff --git a/test/cmocka/src/list/list_item_del.c b/test/cmocka/src/list/list_item_del.c deleted file mode 100644 index ad6bb81a1237..000000000000 --- a/test/cmocka/src/list/list_item_del.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -struct test_data { - struct list_item *head; - struct list_item *tail_minus_1; - struct list_item *tail; -}; - -static int setup(void **state) -{ - struct test_data *data = malloc(sizeof(struct test_data)); - - if (!data) - return -1; - - data->head = malloc(sizeof(struct list_item)); - data->tail_minus_1 = malloc(sizeof(struct list_item)); - data->tail = malloc(sizeof(struct list_item)); - - if (!data->head || !data->tail_minus_1 - || !data->tail) { - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - - return -1; - } - - list_init(data->head); - list_init(data->tail_minus_1); - list_init(data->tail); - - list_item_append(data->tail_minus_1, data->head); - list_item_append(data->tail, data->head); - - *state = data; - return 0; -} - -static int teardown(void **state) -{ - struct test_data *data = *state; - - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - return 0; -} - -static void test_list_list_item_del_when_delete_head_then_tail_minus_1_prev_is_tail(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->head); - - assert_ptr_equal(data->tail_minus_1->prev, data->tail); -} - -static void test_list_list_item_del_when_delete_head_then_tail_minus_1_next_is_tail(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->head); - - assert_ptr_equal(data->tail_minus_1->next, data->tail); -} - -static void test_list_list_item_del_when_delete_head_then_tail_prev_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->head); - - assert_ptr_equal(data->tail->prev, data->tail_minus_1); -} - -static void test_list_list_item_del_when_delete_head_then_tail_next_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->head); - - assert_ptr_equal(data->tail->next, data->tail_minus_1); -} - -static void test_list_list_item_del_when_delete_tail_minus_1_then_head_prev_is_tail(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail_minus_1); - - assert_ptr_equal(data->head->prev, data->tail); -} - -static void test_list_list_item_del_when_delete_tail_minus_1_then_head_next_is_tail(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail_minus_1); - - assert_ptr_equal(data->head->next, data->tail); -} - -static void test_list_list_item_del_when_delete_tail_minus_1_then_tail_prev_is_head(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail_minus_1); - - assert_ptr_equal(data->tail->prev, data->head); -} - -static void test_list_list_item_del_when_delete_tail_minus_1_then_tail_next_is_head(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail_minus_1); - - assert_ptr_equal(data->tail->next, data->head); -} - -static void test_list_list_item_del_when_delete_tail_then_head_prev_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail); - - assert_ptr_equal(data->head->prev, data->tail_minus_1); -} - -static void test_list_list_item_del_when_delete_tail_then_head_next_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail); - - assert_ptr_equal(data->head->next, data->tail_minus_1); -} - -static void test_list_list_item_del_when_delete_tail_then_tail_minus_1_prev_is_head(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail); - - assert_ptr_equal(data->tail_minus_1->prev, data->head); -} - -static void test_list_list_item_del_when_delete_tail_then_tail_minus_1_next_is_head(void **state) -{ - struct test_data *data = *state; - - list_item_del(data->tail); - - assert_ptr_equal(data->tail_minus_1->next, data->head); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_head_then_tail_minus_1_prev_is_tail, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_head_then_tail_minus_1_next_is_tail, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_head_then_tail_prev_is_tail_minus_1, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_head_then_tail_next_is_tail_minus_1, setup, teardown), - - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_minus_1_then_head_prev_is_tail, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_minus_1_then_head_next_is_tail, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_minus_1_then_tail_prev_is_head, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_minus_1_then_tail_next_is_head, setup, teardown), - - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_then_head_prev_is_tail_minus_1, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_then_head_next_is_tail_minus_1, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_then_tail_minus_1_prev_is_head, setup, teardown), - cmocka_unit_test_setup_teardown(test_list_list_item_del_when_delete_tail_then_tail_minus_1_next_is_head, setup, teardown), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/cmocka/src/list/list_item_is_last.c b/test/cmocka/src/list/list_item_is_last.c deleted file mode 100644 index ffd1abee50bd..000000000000 --- a/test/cmocka/src/list/list_item_is_last.c +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -struct test_data { - struct list_item *head; - struct list_item *tail_minus_1; - struct list_item *tail; -}; - -static int setup(void **state) -{ - struct test_data *data = malloc(sizeof(struct test_data)); - - if (!data) - return -1; - - data->head = malloc(sizeof(struct list_item)); - data->tail_minus_1 = malloc(sizeof(struct list_item)); - data->tail = malloc(sizeof(struct list_item)); - - if (!data->head || !data->tail_minus_1 - || !data->tail) { - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - - return -1; - } - - list_init(data->head); - list_init(data->tail_minus_1); - list_init(data->tail); - - list_item_append(data->tail_minus_1, data->head); - list_item_append(data->tail, data->head); - - *state = data; - return 0; -} - -static int teardown(void **state) -{ - struct test_data *data = *state; - - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - return 0; -} - -static void test_list_list_item_is_last_when_head_then_false(void **state) -{ - struct test_data *data = *state; - - assert_false(list_item_is_last(data->head, data->head)); -} - -static void test_list_list_item_is_last_when_tail_minus_1_then_false(void **state) -{ - struct test_data *data = *state; - - assert_false(list_item_is_last(data->tail_minus_1, data->head)); -} - -static void test_list_list_item_is_last_when_tail_then_true(void **state) -{ - struct test_data *data = *state; - - assert_true(list_item_is_last(data->tail, data->head)); -} - -static void test_list_list_item_is_last_when_not_in_list_then_false(void **state) -{ - struct list_item other_list; - struct test_data *data = *state; - - list_init(&other_list); - - assert_false(list_item_is_last(&other_list, data->head)); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_item_is_last_when_head_then_false), - cmocka_unit_test(test_list_list_item_is_last_when_tail_minus_1_then_false), - cmocka_unit_test(test_list_list_item_is_last_when_tail_then_true), - cmocka_unit_test(test_list_list_item_is_last_when_not_in_list_then_false), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, setup, teardown); -} diff --git a/test/cmocka/src/list/list_item_prepend.c b/test/cmocka/src/list/list_item_prepend.c deleted file mode 100644 index e86fa97f8a5e..000000000000 --- a/test/cmocka/src/list/list_item_prepend.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2018 Intel Corporation. All rights reserved. -// -// Author: Janusz Jankowski - -#include - -#include -#include -#include -#include -#include -#include - -struct test_data { - struct list_item *head; - struct list_item *tail_minus_1; - struct list_item *tail; -}; - -static int setup(void **state) -{ - struct test_data *data = malloc(sizeof(struct test_data)); - - if (!data) - return -1; - - data->head = malloc(sizeof(struct list_item)); - data->tail_minus_1 = malloc(sizeof(struct list_item)); - data->tail = malloc(sizeof(struct list_item)); - - if (!data->head || !data->tail_minus_1 - || !data->tail) { - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - - return -1; - } - - list_init(data->head); - list_init(data->tail_minus_1); - list_init(data->tail); - - list_item_prepend(data->tail, data->head); - list_item_prepend(data->tail_minus_1, data->head); - - *state = data; - return 0; -} - -static int teardown(void **state) -{ - struct test_data *data = *state; - - free(data->head); - free(data->tail_minus_1); - free(data->tail); - - free(data); - return 0; -} - -static void test_list_list_item_prepend_head_prev_is_tail(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->head->prev, data->tail); -} - -static void test_list_list_item_prepend_head_next_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->head->next, data->tail_minus_1); -} - -static void test_list_list_item_prepend_tail_minus_1_prev_is_head(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail_minus_1->prev, data->head); -} - -static void test_list_list_item_prepend_tail_minus_1_next_is_tail(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail_minus_1->next, data->tail); -} - -static void test_list_list_item_prepend_tail_prev_is_tail_minus_1(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail->prev, data->tail_minus_1); -} - -static void test_list_list_item_prepend_tail_next_is_head(void **state) -{ - struct test_data *data = *state; - - assert_ptr_equal(data->tail->next, data->head); -} - -int main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_list_item_prepend_head_prev_is_tail), - cmocka_unit_test(test_list_list_item_prepend_head_next_is_tail_minus_1), - cmocka_unit_test(test_list_list_item_prepend_tail_minus_1_prev_is_head), - cmocka_unit_test(test_list_list_item_prepend_tail_minus_1_next_is_tail), - cmocka_unit_test(test_list_list_item_prepend_tail_prev_is_tail_minus_1), - cmocka_unit_test(test_list_list_item_prepend_tail_next_is_head), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - - return cmocka_run_group_tests(tests, setup, teardown); -} diff --git a/test/cmocka/src/math/auditory/auditory.c b/test/cmocka/src/math/auditory/auditory.c index 1e3e903fb5fb..2f8df53e8c6a 100644 --- a/test/cmocka/src/math/auditory/auditory.c +++ b/test/cmocka/src/math/auditory/auditory.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "ref_hz_to_mel.h" @@ -38,6 +39,8 @@ #undef DEBUGFILES /* Change this to #define to get output data files for debugging */ +struct processing_module dummy; + static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, const int16_t *ref_mel_log, int num_fft_bins, int num_mel_bins, int norm_slaney, @@ -87,7 +90,7 @@ static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, fb.scratch_data2 = (int16_t *)fft_out; fb.scratch_length1 = fft_size / sizeof(int16_t); fb.scratch_length2 = fft_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(&fb); + ret = mod_psy_get_mel_filterbank(&dummy, &fb); if (ret < 0) { fprintf(stderr, "Failed Mel filterbank\n"); goto err_get_filterbank; @@ -128,6 +131,10 @@ static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, assert_true(error_rms < MEL_FB16_MAX_ERROR_RMS); assert_true(delta_max < MEL_FB16_MAX_ERROR_ABS); + free(mel_log); + free(fft_buf); + free(fft_out); + mod_psy_free_mel_filterbank(&dummy, &fb); return; err_get_filterbank: @@ -190,7 +197,7 @@ static void filterbank_32_test(const int32_t *fft_real, const int32_t *fft_imag, fb.scratch_data2 = (int16_t *)fft_out; fb.scratch_length1 = fft_size / sizeof(int16_t); fb.scratch_length2 = fft_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(&fb); + ret = mod_psy_get_mel_filterbank(&dummy, &fb); if (ret < 0) { fprintf(stderr, "Failed Mel filterbank\n"); goto err_get_filterbank; @@ -231,6 +238,10 @@ static void filterbank_32_test(const int32_t *fft_real, const int32_t *fft_imag, assert_true(error_rms < MEL_FB32_MAX_ERROR_RMS); assert_true(delta_max < MEL_FB32_MAX_ERROR_ABS); + free(mel_log); + free(fft_buf); + free(fft_out); + mod_psy_free_mel_filterbank(&dummy, &fb); return; err_get_filterbank: diff --git a/test/cmocka/src/math/dct/dct.c b/test/cmocka/src/math/dct/dct.c index 4cfe38ef803b..ea35d170e66e 100644 --- a/test/cmocka/src/math/dct/dct.c +++ b/test/cmocka/src/math/dct/dct.c @@ -22,6 +22,8 @@ #define MATRIX_MULT_16_MAX_ERROR_ABS 2.5 #define MATRIX_MULT_16_MAX_ERROR_RMS 1.1 +struct processing_module dummy; + static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, enum dct_type type, bool ortho) { @@ -41,7 +43,7 @@ static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, dct.num_out = num_out; dct.type = type; dct.ortho = ortho; - ret = dct_initialize_16(&dct); + ret = mod_dct_initialize_16(&dummy, &dct); if (ret) { fprintf(stderr, "Failed to initialize DCT.\n"); exit(EXIT_FAILURE); @@ -69,6 +71,8 @@ static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, assert_true(error_rms < MATRIX_MULT_16_MAX_ERROR_RMS); assert_true(delta_max < MATRIX_MULT_16_MAX_ERROR_ABS); + + mod_dct_free_16(&dummy, &dct); } static void test_dct_matrix_16_test1(void **state) diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index c3d9e47e6ea5..326767ec570e 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -28,3 +28,21 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ) + +cmocka_test(dft3 + dft3.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_multi.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_common.c + ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c + ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c +) + +cmocka_test(fft_multi + fft_multi.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_multi.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_common.c + ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32.c + ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c + ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c +) diff --git a/test/cmocka/src/math/fft/dft3.c b/test/cmocka/src/math/fft/dft3.c new file mode 100644 index 000000000000..a787d8329993 --- /dev/null +++ b/test/cmocka/src/math/fft/dft3.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo + +#include +#include +#include "ref_dft3_32.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOFM_DFT3_MAX_ERROR_ABS 3.1 +#define SOFM_DFT3_MAX_ERROR_RMS 1.1 +#define DFT_SIZE 3 + +static void dft3_32_test(const int32_t *in_real, const int32_t *in_imag, + const int32_t *ref_real, const int32_t *ref_imag, int num_tests) + +{ + struct icomplex32 x[DFT_SIZE]; + struct icomplex32 y[DFT_SIZE]; + double delta; + double error_rms; + double delta_max = 0; + double sum_squares = 0; + const int32_t *p_in_real = in_real; + const int32_t *p_in_imag = in_imag; + const int32_t *p_ref_real = ref_real; + const int32_t *p_ref_imag = ref_imag; + int i, j; + + for (i = 0; i < num_tests; i++) { + for (j = 0; j < DFT_SIZE; j++) { + x[j].real = *p_in_real++; + x[j].imag = *p_in_imag++; + } + + dft3_32(x, y); + + for (j = 0; j < DFT_SIZE; j++) { + delta = (double)*p_ref_real - (double)y[j].real; + sum_squares += delta * delta; + if (delta > delta_max) + delta_max = delta; + else if (-delta > delta_max) + delta_max = -delta; + + delta = (double)*p_ref_imag - (double)y[j].imag; + sum_squares += delta * delta; + if (delta > delta_max) + delta_max = delta; + else if (-delta > delta_max) + delta_max = -delta; + + p_ref_real++; + p_ref_imag++; + } + } + + error_rms = sqrt(sum_squares / (double)(2 * DFT_SIZE * num_tests)); + printf("Max absolute error = %5.2f (max %5.2f), error RMS = %5.2f (max %5.2f)\n", + delta_max, SOFM_DFT3_MAX_ERROR_ABS, error_rms, SOFM_DFT3_MAX_ERROR_RMS); + + assert_true(error_rms < SOFM_DFT3_MAX_ERROR_RMS); + assert_true(delta_max < SOFM_DFT3_MAX_ERROR_ABS); +} + +static void dft3_32_test_1(void **state) +{ + (void)state; + + dft3_32_test(input_data_real_q31, input_data_imag_q31, + ref_data_real_q31, ref_data_imag_q31, + REF_SOFM_DFT3_NUM_TESTS); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(dft3_32_test_1), + }; + + cmocka_set_message_output(CM_OUTPUT_TAP); + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/cmocka/src/math/fft/fft.c b/test/cmocka/src/math/fft/fft.c index 34f59cc656fb..abd8977d2d62 100644 --- a/test/cmocka/src/math/fft/fft.c +++ b/test/cmocka/src/math/fft/fft.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #define MIN_SNR_512 125.0 #define MIN_SNR_1024 119.0 +struct processing_module dummy; + /** * \brief Doing Fast Fourier Transform (FFT) for mono real input buffers. * \param[in] src - pointer to input buffer. @@ -68,7 +71,7 @@ static void fft_real(struct comp_buffer *src, struct comp_buffer *dst, uint32_t if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -85,7 +88,7 @@ static void fft_real(struct comp_buffer *src, struct comp_buffer *dst, uint32_t *((int32_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -123,7 +126,7 @@ static void ifft_complex(struct comp_buffer *src, struct comp_buffer *dst, uint3 if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -140,7 +143,7 @@ static void ifft_complex(struct comp_buffer *src, struct comp_buffer *dst, uint3 *((int32_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -181,7 +184,7 @@ static void fft_real_2(struct comp_buffer *src, struct comp_buffer *dst1, if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -210,7 +213,7 @@ static void fft_real_2(struct comp_buffer *src, struct comp_buffer *dst1, (outb[size - i].real - outb[i].real) / 2; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -265,8 +268,8 @@ static void test_math_fft_256(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 256 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 256; @@ -300,6 +303,9 @@ static void test_math_fft_256(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_256, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_512(void **state) @@ -307,8 +313,8 @@ static void test_math_fft_512(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 512; @@ -342,6 +348,9 @@ static void test_math_fft_512(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_512, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024(void **state) @@ -349,8 +358,8 @@ static void test_math_fft_1024(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 1024; @@ -384,6 +393,9 @@ static void test_math_fft_1024(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_1024, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_ifft(void **state) @@ -391,9 +403,9 @@ static void test_math_fft_1024_ifft(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 4 * 2, }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *intm = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *intm = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; float db; int64_t signal = 0; @@ -425,6 +437,10 @@ static void test_math_fft_1024_ifft(void **state) db = 10 * log10((float)signal / noise); printf("%s: SNR: %6.2f dB\n", __func__, db); assert_int_equal(db < FFT_DB_TH, 0); + + buffer_free(source); + buffer_free(intm); + buffer_free(sink); } static void test_math_fft_512_2ch(void **state) @@ -432,9 +448,9 @@ static void test_math_fft_512_2ch(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 4 * 2, }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink1 = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink2 = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink1 = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink2 = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex32 *out1 = (struct icomplex32 *)sink1->stream.addr; struct icomplex32 *out2 = (struct icomplex32 *)sink2->stream.addr; uint32_t fft_size = 512; @@ -467,6 +483,10 @@ static void test_math_fft_512_2ch(void **state) /* the peak should be in range i +/-1 */ assert_in_range(r, i - 1, i + 1); + + buffer_free(source); + buffer_free(sink1); + buffer_free(sink2); } /** @@ -498,7 +518,7 @@ static void fft_real_16(struct comp_buffer *src, struct comp_buffer *dst, uint32 if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 16); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 16); if (!plan) goto err_plan; @@ -515,7 +535,7 @@ static void fft_real_16(struct comp_buffer *src, struct comp_buffer *dst, uint32 *((int16_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -553,7 +573,7 @@ static void ifft_complex_16(struct comp_buffer *src, struct comp_buffer *dst, ui if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 16); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 16); if (!plan) goto err_plan; @@ -570,7 +590,7 @@ static void ifft_complex_16(struct comp_buffer *src, struct comp_buffer *dst, ui *((int16_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -625,8 +645,8 @@ static void test_math_fft_256_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 256 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 256; @@ -660,6 +680,9 @@ static void test_math_fft_256_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_256_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_512_16(void **state) @@ -667,8 +690,8 @@ static void test_math_fft_512_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 512; @@ -702,6 +725,9 @@ static void test_math_fft_512_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_512_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_16(void **state) @@ -709,8 +735,8 @@ static void test_math_fft_1024_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 1024; @@ -744,6 +770,9 @@ static void test_math_fft_1024_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_1024_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_ifft_16(void **state) @@ -751,9 +780,9 @@ static void test_math_fft_1024_ifft_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *intm = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); - struct comp_buffer *sink = buffer_new(&test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *source = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *intm = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *sink = buffer_new(NULL, &test_buf_desc, BUFFER_USAGE_NOT_SHARED); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; float db; int64_t signal = 0; @@ -784,6 +813,10 @@ static void test_math_fft_1024_ifft_16(void **state) db = 10 * log10((float)signal / noise); printf("%s: SNR: %6.2f dB\n", __func__, db); assert_int_equal(db < FFT_DB_TH_16, 0); + + buffer_free(source); + buffer_free(intm); + buffer_free(sink); } int main(void) diff --git a/test/cmocka/src/math/fft/fft_multi.c b/test/cmocka/src/math/fft/fft_multi.c new file mode 100644 index 000000000000..6928af5807f3 --- /dev/null +++ b/test/cmocka/src/math/fft/fft_multi.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo + +#include +#include +#include "ref_fft_multi_96_32.h" +#include "ref_fft_multi_512_32.h" +#include "ref_fft_multi_768_32.h" +#include "ref_fft_multi_1024_32.h" +#include "ref_fft_multi_1536_32.h" +#include "ref_fft_multi_3072_32.h" + +#include "ref_ifft_multi_24_32.h" +#include "ref_ifft_multi_256_32.h" +#include "ref_ifft_multi_1024_32.h" +#include "ref_ifft_multi_1536_32.h" +#include "ref_ifft_multi_3072_32.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FFT_MAX_ERROR_ABS 1050.0 /* about -126 dB */ +#define FFT_MAX_ERROR_RMS 35.0 /* about -156 dB */ +#define IFFT_MAX_ERROR_ABS 2400000.0 /* about -59 dB */ +#define IFFT_MAX_ERROR_RMS 44000.0 /* about -94 dB */ + +struct processing_module dummy; + +static void fft_multi_32_test(const int32_t *in_real, const int32_t *in_imag, + const int32_t *ref_real, const int32_t *ref_imag, + int num_bins, int num_tests, double max_error_abs, + double max_error_rms, bool do_ifft) +{ + struct icomplex32 *x; + struct icomplex32 *y; + struct fft_multi_plan *plan; + double delta; + double error_rms; + double delta_max = 0; + double sum_squares = 0; + const int32_t *p_in_real = in_real; + const int32_t *p_in_imag = in_imag; + const int32_t *p_ref_real = ref_real; + const int32_t *p_ref_imag = ref_imag; + int i, j; + FILE *fh1, *fh2; + + x = malloc(num_bins * sizeof(struct icomplex32)); + if (!x) { + fprintf(stderr, "Failed to allocate input data buffer.\n"); + assert_true(false); + } + + y = malloc(num_bins * sizeof(struct icomplex32)); + if (!y) { + fprintf(stderr, "Failed to allocate output data buffer.\n"); + assert_true(false); + } + + plan = mod_fft_multi_plan_new(&dummy, x, y, num_bins, 32); + if (!plan) { + fprintf(stderr, "Failed to allocate FFT plan.\n"); + assert_true(false); + } + + fh1 = fopen("debug_fft_multi_in.txt", "w"); + fh2 = fopen("debug_fft_multi_out.txt", "w"); + + for (i = 0; i < num_tests; i++) { + for (j = 0; j < num_bins; j++) { + x[j].real = *p_in_real++; + x[j].imag = *p_in_imag++; + fprintf(fh1, "%d %d\n", x[j].real, x[j].imag); + } + + fft_multi_execute_32(plan, do_ifft); + + for (j = 0; j < num_bins; j++) { + fprintf(fh2, "%d %d %d %d\n", + y[j].real, y[j].imag, *p_ref_real, *p_ref_imag); + delta = (double)*p_ref_real - (double)y[j].real; + sum_squares += delta * delta; + if (delta > delta_max) + delta_max = delta; + else if (-delta > delta_max) + delta_max = -delta; + + delta = (double)*p_ref_imag - (double)y[j].imag; + sum_squares += delta * delta; + if (delta > delta_max) + delta_max = delta; + else if (-delta > delta_max) + delta_max = -delta; + + p_ref_real++; + p_ref_imag++; + } + + } + + mod_fft_multi_plan_free(&dummy, plan); + free(y); + free(x); + fclose(fh1); fclose(fh2); + + error_rms = sqrt(sum_squares / (double)(2 * num_bins * num_tests)); + printf("Max absolute error = %5.2f (limit %5.2f), error RMS = %5.2f (limit %5.2f)\n", + delta_max, max_error_abs, error_rms, max_error_rms); + + assert_true(error_rms < max_error_rms); + assert_true(delta_max < max_error_abs); +} + +static void fft_multi_32_test_1(void **state) +{ + (void)state; + + /* Test FFT */ + fft_multi_32_test(fft_in_real_96_q31, fft_in_imag_96_q31, + fft_ref_real_96_q31, fft_ref_imag_96_q31, + 96, REF_SOFM_FFT_MULTI_96_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_512_q31, fft_in_imag_512_q31, + fft_ref_real_512_q31, fft_ref_imag_512_q31, + 512, REF_SOFM_FFT_MULTI_512_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_768_q31, fft_in_imag_768_q31, + fft_ref_real_768_q31, fft_ref_imag_768_q31, + 768, REF_SOFM_FFT_MULTI_768_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_1024_q31, fft_in_imag_1024_q31, + fft_ref_real_1024_q31, fft_ref_imag_1024_q31, + 1024, REF_SOFM_FFT_MULTI_1024_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_1536_q31, fft_in_imag_1536_q31, + fft_ref_real_1536_q31, fft_ref_imag_1536_q31, + 1536, REF_SOFM_FFT_MULTI_1536_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_3072_q31, fft_in_imag_3072_q31, + fft_ref_real_3072_q31, fft_ref_imag_3072_q31, + 3072, REF_SOFM_FFT_MULTI_3072_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + fft_multi_32_test(fft_in_real_3072_q31, fft_in_imag_3072_q31, + fft_ref_real_3072_q31, fft_ref_imag_3072_q31, + 3072, REF_SOFM_FFT_MULTI_3072_NUM_TESTS, + FFT_MAX_ERROR_ABS, FFT_MAX_ERROR_RMS, false); + + /* Test IFFT */ + fft_multi_32_test(ifft_in_real_24_q31, ifft_in_imag_24_q31, + ifft_ref_real_24_q31, ifft_ref_imag_24_q31, + 24, REF_SOFM_IFFT_MULTI_24_NUM_TESTS, + IFFT_MAX_ERROR_ABS, IFFT_MAX_ERROR_RMS, true); + fft_multi_32_test(ifft_in_real_256_q31, ifft_in_imag_256_q31, + ifft_ref_real_256_q31, ifft_ref_imag_256_q31, + 256, REF_SOFM_IFFT_MULTI_256_NUM_TESTS, + IFFT_MAX_ERROR_ABS, IFFT_MAX_ERROR_RMS, true); + fft_multi_32_test(ifft_in_real_1024_q31, ifft_in_imag_1024_q31, + ifft_ref_real_1024_q31, ifft_ref_imag_1024_q31, + 1024, REF_SOFM_IFFT_MULTI_1024_NUM_TESTS, + IFFT_MAX_ERROR_ABS, IFFT_MAX_ERROR_RMS, true); + fft_multi_32_test(ifft_in_real_1536_q31, ifft_in_imag_1536_q31, + ifft_ref_real_1536_q31, ifft_ref_imag_1536_q31, + 1536, REF_SOFM_IFFT_MULTI_1536_NUM_TESTS, + IFFT_MAX_ERROR_ABS, IFFT_MAX_ERROR_RMS, true); + fft_multi_32_test(ifft_in_real_3072_q31, ifft_in_imag_3072_q31, + ifft_ref_real_3072_q31, ifft_ref_imag_3072_q31, + 3072, REF_SOFM_IFFT_MULTI_3072_NUM_TESTS, + IFFT_MAX_ERROR_ABS, IFFT_MAX_ERROR_RMS, true); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(fft_multi_32_test_1), + }; + + cmocka_set_message_output(CM_OUTPUT_TAP); + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/cmocka/src/math/fft/ref_dft3.m b/test/cmocka/src/math/fft/ref_dft3.m new file mode 100644 index 000000000000..c3f55d91b3e3 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_dft3.m @@ -0,0 +1,59 @@ +% ref_dft3 - Generate C header files for DFT3 function unit tests + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright(c) 2025 Intel Corporation. All rights reserved. + +function ref_dft3() + + path(path(), '../../../m'); + opt.describe = export_get_git_describe(); + + N = 3; + num_tests = 100; + scale_q31 = 2^31; + opt.bits = 32; + min_int32 = int32(-2^31); + max_int32 = int32(2^31 - 1); + + % Random values + input_data_real_q31 = int32((2 * rand(N, num_tests) - 1) * scale_q31); + input_data_imag_q31 = int32((2 * rand(N, num_tests) - 1) * scale_q31); + + % Apply max and min values to first two tests + input_data_real_q31(:,1) = [max_int32 max_int32 max_int32]; + input_data_imag_q31(:,1) = [max_int32 max_int32 max_int32]; + input_data_real_q31(:,2) = [min_int32 min_int32 min_int32]; + input_data_imag_q31(:,2) = [min_int32 min_int32 min_int32]; + + % Convert to float for reference DFT + input_data_real_f = double(input_data_real_q31) / scale_q31; + input_data_imag_f = double(input_data_imag_q31) / scale_q31; + input_data_f = complex(input_data_real_f, input_data_imag_f); + + ref_data_f = zeros(N, num_tests); + for i = 1:num_tests + ref_data_f(:,i) = fft(1/N * input_data_f(:,i)); + end + + input_data_vec_f = reshape(input_data_f, N * num_tests, 1); + input_data_real_q31 = int32(real(input_data_vec_f) * scale_q31); + input_data_imag_q31 = int32(imag(input_data_vec_f) * scale_q31); + + ref_data_vec_f = reshape(ref_data_f, N * num_tests, 1); + ref_data_real_q31 = int32(real(ref_data_vec_f) * scale_q31); + ref_data_imag_q31 = int32(imag(ref_data_vec_f) * scale_q31); + + header_fn = sprintf('ref_dft3_32.h'); + fh = export_headerfile_open(header_fn); + comment = sprintf('Created %s with script ref_dft3.m %s', ... + datestr(now, 0), opt.describe); + export_comment(fh, comment); + export_ndefine(fh, 'REF_SOFM_DFT3_NUM_TESTS', num_tests); + export_vector(fh, opt.bits, 'input_data_real_q31', input_data_real_q31); + export_vector(fh, opt.bits, 'input_data_imag_q31', input_data_imag_q31); + export_vector(fh, opt.bits, 'ref_data_real_q31', ref_data_real_q31); + export_vector(fh, opt.bits, 'ref_data_imag_q31', ref_data_imag_q31); + fclose(fh); + fprintf(1, 'Exported %s.\n', header_fn); +end diff --git a/test/cmocka/src/math/fft/ref_dft3_32.h b/test/cmocka/src/math/fft/ref_dft3_32.h new file mode 100644 index 000000000000..dc29c737e552 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_dft3_32.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 18-Nov-2025 10:04:16 with script ref_dft3.m v1.9-rc1-6866-g7082edfc2-dirty */ + +#define REF_SOFM_DFT3_NUM_TESTS 100 + +static const int32_t input_data_real_q31[300] = { + 2147483647, 2147483647, 2147483647, -2147483648, -2147483648, -2147483648, + 1162219834, 23816319, -504635601, -893753638, 2096234199, 1926797429, + -1498879994, -1344377511, -1565629944, 470700317, 1534215118, 250204116, + -1513962524, 328839298, -891150595, 1037032885, 2053083918, 214745934, + -1132393293, -684253779, 1290308737, 1492556115, 1767631432, -1476198666, + -1980706125, -152724048, 1304919915, -333340349, -945811108, 555573004, + 508704347, -91940743, -1172534471, 808237431, -864171862, -1701987975, + 667143603, 466065800, -680587634, -1210890266, -1609079348, 376693582, + -1989200673, -866348502, -1518045121, -810592170, -2014026366, 308045234, + -893653199, -71890004, 1798867597, -1165288212, -195853850, 727803849, + -827203566, -763401435, -555032730, 2049556353, -1733329582, 1857973403, + -969720479, 474304971, -118122188, -1414917124, 755553858, 512336983, + -412624469, -654030354, -673412294, -480554119, 2141467418, 982286252, + -333493549, -1792914214, -751632737, 1453631035, -567352454, -1121160722, + 1835418889, 1469373494, 1260799356, 1916321534, 1046738218, -482282675, + -1777733492, 1417780825, -1905923885, 1720942739, -1698447345, 1524731616, + -940329093, 474359626, 869280780, -1587738164, 718005895, -1275483558, + 1311357743, -1127231201, 1170568884, 351336134, 912933315, 929235364, + -1766156248, -751021719, -1575099846, -500683117, 758133192, -1000251215, + -460549792, -872077348, 1190236123, -2094039372, -97472255, 1766680277, + 1682916204, 1878420776, -1937130520, -1305433548, -2023614346, -961620965, + -1144745178, 349170968, -990207654, 2066179435, -409481891, -1640628527, + -1748672103, 1509049194, 2136386712, 749103155, 1869393346, -473447757, + 188132091, 471958830, 565514557, 24038287, 250957039, 555942787, + -1417341343, 1310588913, -1980667608, 1978973460, -1886552564, -931043047, + 240691726, 366351147, 856435514, -2100179945, 1322815981, -1993386310, + -1907183049, 1018981874, -1982669624, -392347504, 283140809, -701932511, + 827970927, 1087003102, 1539141719, 575668370, -284136687, -166908907, + 1086613743, -1578737459, 1755161659, -363056680, -972520979, 1833561918, + -691836837, 2043720743, -142353127, 1166774227, 991149245, -1806872349, + -1973652264, 1188981112, 1911685701, -968798985, 2077908949, -166982863, + 1326781679, -1986923452, -1067800528, 1854266938, 1333307796, -241964941, + -267584968, 886003675, -805272619, 1479927684, 159424368, 139369932, + -313191797, -791964593, 123256824, 1761190835, 267191061, -1066245064, + 2059356024, 983929284, -988243656, -2128354307, 1321996812, 279274571, + -958912371, 115946572, 1492522503, -1102123606, -1958076794, -1473281696, + -511493535, -162111044, -1652434912, 515681118, 1328854757, 1615582785, + 838101882, -981669826, -85699769, 826563860, -1054635732, 276608854, + -285946678, 1081455066, 1239400031, 344174895, -152045930, -1779441010, + -1443541302, -626187735, -7031089, -314268939, 575767023, -18068620, + 857747866, -1026238975, 1741588511, -825216518, -657754491, -1800153864, + 902250246, 1007864270, 1984210739, 1594306126, -365683058, -306799624, + 728125587, -1705315469, -445468326, 1860359390, 1561088340, 996962395, + 636780028, 1069385362, 49149330, -1167618105, -2051885175, 1699344213, + -450653472, 28073512, 1407413309, -1332191163, 1302508825, 589871272, + -769422448, -1945782013, -1273023036, -2144421096, -981418969, 1126299923, + -1473462655, -1468616147, 1514904515, 1873597062, 977229454, -190860952, + -1450912250, -1515509653, -1706549902, -1798566387, -1488199231, 465976855, + 1507852161, 1334015424, -1930050220, -839537711, -519449681, 1802561273, + -1686609113, -988247120, -2018183481, -1422312120, -524629977, 777771469, +}; + +static const int32_t input_data_imag_q31[300] = { + 2147483647, 2147483647, 2147483647, -2147483648, -2147483648, -2147483648, + -447071638, -710569404, -521054814, -1525984216, 1485866355, -1887906218, + 694991588, -1423316381, -526983997, 1416498079, -9059322, -1894876350, + 529729352, -1667720604, -1765426014, 1622805049, 1403298661, -56966777, + 1372247161, -989865104, 226982867, 1200666007, -1172962658, -327728731, + -1770194241, 2063801732, -1222401122, -1437089259, 7163116, -1667845557, + 699401620, -767508329, 1458191154, 2102543710, -386800992, 984597551, + -1002742709, -1568629571, -502851595, -51793840, -709663670, 1748043151, + 1096459944, 1109269442, 1991276284, 1630095127, -412134472, -1039994124, + -769839143, -2071887810, -1473927075, 143017106, 792574136, 1214806759, + -1707309285, -1546417474, 1644851668, 1369929054, -1504595449, -504861820, + 941716193, 1798841734, 1004503064, -548152154, 1433124598, 75564731, + -837059818, -1634446222, 1096996669, 760853936, 158476524, 1288109053, + -545735405, -1072909043, 1216016240, 1728999756, 1301464866, 1708661027, + 424731640, -179953738, 1829344056, -325009476, 1191455307, 1243675521, + 206426657, -785131901, 513197679, -1441381381, -1879255156, -626702268, + 1196431670, -484279907, 2027499180, 947791638, -1004082133, 1126341198, + -762028151, -776494670, -1745568389, -1969907879, 894288459, 106735650, + -272461269, -337916005, -1243196237, -395332730, 1275277656, -1472977807, + -938816844, 1834539458, 1332936891, 878083108, -45073545, -1185953597, + -717818068, -30126320, 1482293565, -1904955333, -932393894, -2110646291, + -525568699, -1934721075, -841727840, 199552072, 402812734, 545621043, + 2041424330, 636650031, 262616779, 2027512409, -1473662400, -2131440924, + 86104846, 858180945, -1162684732, -1853469689, -1511760166, -2140871371, + -16978023, 1565504329, 1807701041, 838301612, -432147051, 1812146715, + 358112650, -1258170956, 688314303, -938717727, 1479050461, -808626808, + -1801201683, -567689961, 409371332, -1131239726, -219900330, 1662293964, + -1591338732, -1898978738, -1394863666, -1673116723, -1385225905, -506268616, + 1968110246, -124595511, 1787454593, 579998873, -556710560, 1912851650, + -99737218, -2012489847, 248120965, 283176403, 1573201156, -759852424, + -1562343755, 1375885975, -1557867556, 135286679, 920363352, 1029195101, + 1429284623, 1861442578, 1690850333, -2039742677, -452522368, 94467724, + 603284320, 370872395, -1416940658, 1020409603, -181807657, -1585188066, + -131317730, 1841147202, 751515590, 1429723577, -1685642094, 1194135059, + 782914220, 1896122751, 1008900429, 937134356, 54677423, -1294082603, + -1394821557, -1413641053, -1995302037, 1412674184, -2090278821, -818075169, + 412258694, -646997248, -1371284669, -943407015, -277753547, -1009224290, + -714869328, 759608215, 1616359360, -754310245, 1178040373, -1748780178, + -283459899, 863462232, 844805157, 302181273, -1799234263, 299774378, + 902067000, 2019733716, -779964295, -1476250288, 174210071, 1848240816, + -417614345, -1449712719, -232573863, -1033791826, -1734572491, 2059952961, + 164824306, -1192574723, -794465893, -2100496663, 1966082659, 662383049, + -1724169177, 1397272869, 443158715, -1466228413, -1048441604, -721618311, + 607147167, 405920890, 1890695467, 1700845925, -861572606, -193465319, + -699440151, -1445722888, -1602829412, 2051117803, -720439151, -1947113131, + -390310420, -1650048864, 841983379, 476615869, -1467229630, 43603884, + -1704704811, -1363183779, 1599254898, 174995960, 1261823464, -2010724063, + -1013060202, 983314876, -1374232138, 2105244869, -1751771177, -2066157313, + -200819569, 997385318, 1618215010, -2057992268, 1973711259, -518966102, + 1974013954, -1632849536, -1429309305, -817476773, -724148800, -1290709464, +}; + +static const int32_t ref_data_real_q31[300] = { + 2147483647, 0, 0, -2147483648, 0, 0, + 227133517, 412835009, 522251308, 1043092663, 5501101, -1942347402, + -1469629150, -273374294, 244123449, 751706517, 403885384, -684891584, + -692091274, -382730503, -439140748, 1101620912, 389248308, -453836336, + -175446112, -829747342, -127199839, 594662960, 204948560, 692944595, + -276170086, 96377032, -1800913071, -241192818, 437459588, -529607120, + -251923622, -262190113, 1022818082, -585974135, 301217124, 1092994442, + 150873923, -49528761, 565798441, -814425344, -907711308, 511246386, + -1457864765, -520281398, -11054510, -838857767, 195380268, -167114671, + 277774798, -758330394, -413097603, -211112738, -598975796, -355199678, + -715212577, -977235544, 865244555, 724733391, 373813241, 951009721, + -204512565, -153298134, -611909779, -49008761, -291060404, -1074847959, + -580022372, -704800693, 872198596, 881066517, -1006907140, -354713496, + -959346833, -347829172, 973682456, -78294047, 648415134, 883509948, + 1521863913, -423256823, 736811799, 826925692, 529623244, 559772598, + -755292184, -886016120, -136425188, 515742337, 241019328, 964181075, + 134437104, -1262471265, 187705067, -715071942, -1051333353, 178667131, + 451565142, 709643787, 150148814, 731168271, 37430845, -417262982, + -1364092604, 60300071, -462363715, -247600380, 666811647, -919894384, + -47463672, -61742871, -351343248, -141610450, -646870758, -1305558164, + 541402153, 134159011, 1007355039, -1430222953, 402526872, -277737467, + -595260621, -590262248, 40777691, 5356339, 989186340, 1071636756, + 632254601, -1082489253, -1298437451, 715016248, 206927757, -172840850, + 408535159, 473172137, -693575205, 276979371, 55138220, -308079304, + -695806679, -430683500, -290851163, -279540717, 481385284, 1777128893, + 487826129, -685469096, 438334693, -923583425, 72097283, -1248693804, + -956956933, -757166358, -193059758, -270379735, -604326575, 482358807, + 1151371916, -307225981, -16175008, 41540925, 13330609, 520796836, + 421012648, -219160773, 884761869, 165994753, -977426920, 448375487, + 403176926, -1200089012, 105075249, 117017041, 1198373149, -148615963, + 375671516, -327760195, -2021563586, 314042367, -672837696, -610003656, + -575980767, 1000626962, 902135484, 981869931, 278296065, 594100942, + -62284637, 413447008, -618747339, 592907328, 848631206, 38389150, + -327299855, 321603581, -307495523, 320712277, -111080778, 1551559336, + 685013884, 943290093, 431052047, -175694308, -586976517, -1365683482, + 216518901, -419804573, -755626699, -1511160699, -162735014, 571772107, + -775346497, 341010250, -77157288, 1153372887, -107688469, -530003300, + -76422571, 209939474, 704584979, 16178994, 1250092749, -439707883, + 678302806, -476738909, -487510576, -529104015, -169292147, 1042571057, + -692253375, 432559237, -1183847163, 81143155, -680957097, 285545004, + 524365801, -184666690, 518048756, -1094374958, -960805926, 1229964365, + 1298108418, -312853206, -83004966, 307274481, 1019861483, 267170162, + -474219403, 876601527, 325743463, 1472803375, 99432249, 288123766, + 585104907, -402779940, 454455062, -506719689, -523315169, -137583247, + 328277783, -344112881, -434818374, 186729645, -405350128, -1113570680, + -1329409166, -439394384, 999381102, -666513381, -1175093926, -302813790, + -475724762, -1354051330, 356313437, 886655188, 1438174035, -451232161, + -1557657268, 733937711, -627192692, -940262921, -338396273, -519907193, + 303939122, 422738425, 781174615, 147857960, 225876137, -1213271808, + -1564346571, -119888274, -2374267, -389723543, -352742313, -679846265, +}; + +static const int32_t ref_data_imag_q31[300] = { + 2147483647, 0, 0, -2147483648, 0, 0, + -559565285, -96304105, 208797753, -642674693, -490566944, -392742579, + -418436263, 492843850, 620584002, -162479198, 418826590, 1160150687, + -967805755, 396586807, 1100948300, 989712311, -214136096, 847228834, + 203121641, 1154569860, 14555660, -100008461, -286075856, 1586750324, + -309597877, -309512615, -1151083749, -1032590567, 231162914, -635661607, + 463361482, -193920471, 429960609, 900113423, 359358464, 843071823, + -1024741292, -320011043, 342009626, 328861880, 382915408, -763571128, + 1399001890, -339399582, 36857636, 59322177, 1455710807, 115062143, + -1438551343, 874397302, -205685102, 716799334, -20254103, -553528124, + -536291697, -525357930, -645659658, -213176072, 1828272435, -245167310, + 1248353664, -324337725, 17700255, 320179058, -504376270, -363954942, + -458169790, -195040098, -183849930, 735813171, -322106397, 347147162, + -134209403, 94829069, -506355072, 1579708550, -85225073, 234516279, + 691373986, -193531340, -73111006, 703373784, -955581942, -72801318, + -21835855, -845339649, 1073602161, -1315779602, 867650731, -993252510, + 913216981, 255611262, 27603427, 356683568, -279916801, 871024871, + -1094697070, 829652208, -496983289, -322961257, -818767315, -828179307, + -617857837, -65192580, 410589148, -197677627, -606429407, 408774304, + 742886502, -245513054, -1436190292, -117648011, 1036000043, -40268923, + 244783059, -1582755347, 620154220, -1649331839, 178759335, -434382829, + -1100672538, -99093384, 674197223, 382661950, -446956360, 263846482, + 980230380, 711693717, 349500233, -525863638, 600368053, 1953007994, + -72799647, 106459459, 52445034, -1835367075, 78990495, -97093109, + 1118742449, -1517964155, 382243683, 739433759, 325265765, -226397912, + -70581334, 355822163, 72871822, -89431358, -1381948327, 532661958, + -653173437, -1440516273, 292488027, 103717969, -901845021, -333112674, + -1628393712, 149048666, -111993686, -1188203748, -208615742, -276297233, + 1210323109, 1341307345, -583520208, 645379988, 777355801, -842736915, + -621368700, -370249428, 891880910, 365508378, -848885248, 766553273, + -581441779, -281824144, -699077833, 694948377, -927875295, 368213597, + 1660525845, 149707323, -380948545, -799265774, -1074980521, -165496382, + -147594648, -112789928, 863668896, -248862040, 628846604, 640425039, + 820448354, -211681376, -740084708, 312738847, 173562512, 943422218, + 1229312467, -792516412, 346118166, -100756941, 217937665, 819953632, + -1601254882, 500599905, -294166579, -498559935, 1095565350, 815668770, + -535341074, 43580441, 904019327, -743461617, -17201447, -182743951, + 553699416, -375640095, -892928649, -441683350, 227983763, -540610658, + 474935830, -333603080, -424792649, -399092871, -119151422, 820425566, + 713945474, 272795891, -84674365, 182066866, -1000584161, -657732993, + -699966976, 940179287, -657826657, -236137119, -728609646, -69045061, + -607405437, 667961820, 104267923, 175989682, -1121244989, -1155241356, + 38754136, -517775113, -1245148200, -1078762776, -356581952, -30883685, + 967921175, -474903778, 114129770, 215269333, 1825674944, -340098353, + -1249330817, 673126435, -123235769, -205478160, 922577240, 1334018723, + -399458635, 198782896, -189634681, -315669959, 1004588949, -212303121, + -489544564, 253688105, -1468848352, -191301546, -154049902, 520347408, + -467992488, -327682427, -217385287, -570894540, 1902191749, 773947660, + 804926920, -1445127833, 439381345, -201082370, -258148124, -1598761774, + -362714962, 871047441, 1465681476, -944111679, 439288366, -312653460, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi.m b/test/cmocka/src/math/fft/ref_fft_multi.m new file mode 100644 index 000000000000..57b1218f64dc --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi.m @@ -0,0 +1,138 @@ +% ref_sofm_dft3 - Generate C header files for DFT3 function unit tests + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright(c) 2025 Intel Corporation. All rights reserved. + +function ref_fft_multi() + + rand('twister', 0); % Set seed to produce same test vectors every time + path(path(), '../../../m'); + opt.describe = export_get_git_describe(); + opt.bits = 32; + opt.fs = 48e3; + opt.ifft = 0; + opt.sine = 1; + opt.rand = 0; + opt.dc = 0; + opt.num_tests = 1; + + N = 96; + make_fft_multi_test_vectors(opt, N); + + N = 512; + make_fft_multi_test_vectors(opt, N); + + N = 768; + make_fft_multi_test_vectors(opt, N); + + N = 1024; + make_fft_multi_test_vectors(opt, N); + + N = 1536; + make_fft_multi_test_vectors(opt, N); + + N = 3072; + make_fft_multi_test_vectors(opt, N); + + opt.ifft = 1; + opt.dc = 0; + opt.sine = 1; + opt.rand = 0; + + N = 24; + make_fft_multi_test_vectors(opt, N); + + N = 256; + make_fft_multi_test_vectors(opt, N); + + N = 1024; + make_fft_multi_test_vectors(opt, N); + + N = 1536; + make_fft_multi_test_vectors(opt, N); + + N = 3072; + make_fft_multi_test_vectors(opt, N); + +end + +function make_fft_multi_test_vectors(opt, N) + + scale_q = 2^(opt.bits - 1); + min_int = int32(-scale_q); + max_int = int32(scale_q - 1); + n = 1; + + input_data_real_q = int32(zeros(N, opt.num_tests)); + input_data_imag_q = int32(zeros(N, opt.num_tests)); + + if opt.dc + input_data_real_q(:,n) = int32(ones(N, 1) * scale_q / N); + n = n + 1; + end + if opt.rand + input_data_real_q(:,n) = int32(2 * (rand(N, 1) - 1) * scale_q * 0.1); + input_data_imag_q(:,n) = int32(2 * (rand(N, 1) - 1) * scale_q * 0.1); + n = n + 1; + end + if opt.sine + ft = 997; + t = (0:(N - 1))'/opt.fs; + x = 10^(-1 / 20) * sin(2 * pi * ft * t) .* kaiser(N, 20); + dither = scale_q / 2^19 * (rand(N, 1) + rand(N, 1) - 1); + input_data_real_q(:,n) = int32(x * scale_q + dither); + if opt.ifft + tmp_fft = fft(double(input_data_real_q(:,n)) / scale_q) / N; + input_data_real_q(:,n) = int32(real(tmp_fft) * scale_q); + input_data_imag_q(:,n) = int32(imag(tmp_fft) * scale_q); + end + n = n + 1; + end + + if opt.ifft + N_half = N/2 + 1; + for i = 1:opt.num_tests + input_data_real_q(N_half + 1:end) = input_data_real_q(N_half - 1:-1:2); + input_data_imag_q(N_half + 1:end) = -input_data_imag_q(N_half - 1:-1:2); + end + end + + input_data_real_f = double(input_data_real_q) / scale_q; + input_data_imag_f = double(input_data_imag_q) / scale_q; + input_data_f = complex(input_data_real_f, input_data_imag_f); + + ref_data_f = zeros(N, opt.num_tests); + for i = 1:opt.num_tests + if opt.ifft + ref_data_f(:,i) = ifft(input_data_f(:,i)) * N; + test_type = 'ifft'; + else + ref_data_f(:,i) = fft(input_data_f(:,i)) / N; + test_type = 'fft'; + end + end + + input_data_vec_f = reshape(input_data_f, N * opt.num_tests, 1); + input_data_real_q = int32(real(input_data_vec_f) * scale_q); + input_data_imag_q = int32(imag(input_data_vec_f) * scale_q); + + ref_data_vec_f = reshape(ref_data_f, N * opt.num_tests, 1); + ref_data_real_q = int32(real(ref_data_vec_f) * scale_q); + ref_data_imag_q = int32(imag(ref_data_vec_f) * scale_q); + + header_fn = sprintf('ref_%s_multi_%d_%d.h', test_type, N, opt.bits); + fh = export_headerfile_open(header_fn); + comment = sprintf('Created %s with script ref_fft_multi.m %s', ... + datestr(now, 0), opt.describe); + export_comment(fh, comment); + dstr = sprintf('REF_SOFM_%s_MULTI_%d_NUM_TESTS', upper(test_type), N); + export_ndefine(fh, dstr, opt.num_tests); + qbits = opt.bits-1; + vstr = sprintf('%s_in_real_%d_q%d', test_type, N, qbits); export_vector(fh, opt.bits, vstr, input_data_real_q); + vstr = sprintf('%s_in_imag_%d_q%d', test_type, N, qbits); export_vector(fh, opt.bits, vstr, input_data_imag_q); + vstr = sprintf('%s_ref_real_%d_q%d', test_type, N, qbits); export_vector(fh, opt.bits, vstr, ref_data_real_q); + vstr = sprintf('%s_ref_imag_%d_q%d', test_type, N, qbits); export_vector(fh, opt.bits, vstr, ref_data_imag_q); + fclose(fh); + fprintf(1, 'Exported %s.\n', header_fn); +end diff --git a/test/cmocka/src/math/fft/ref_fft_multi_1024_32.h b/test/cmocka/src/math/fft/ref_fft_multi_1024_32.h new file mode 100644 index 000000000000..e9482fd88f05 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_1024_32.h @@ -0,0 +1,704 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_1024_NUM_TESTS 1 + +static const int32_t fft_in_real_1024_q31[1024] = { + -368, 399, 1137, -1510, 917, -915, + 1477, 4004, 26, -670, 19, -245, + 2071, 2623, -2126, 2311, 2688, 609, + -1461, 4166, -310, 1858, -248, -2221, + 2398, -796, -698, -2996, -2571, -2483, + -6926, -3796, -6581, -7667, -9040, -7126, + -9738, -14377, -11690, -11331, -14016, -14971, + -16347, -13087, -10581, -9389, -7947, -3776, + -2708, 3498, 9037, 13136, 16328, 23190, + 32849, 35886, 48147, 54704, 58656, 61210, + 72193, 75724, 79356, 83168, 79591, 79627, + 74772, 71013, 60544, 48856, 38174, 19894, + 7444, -19623, -39518, -64353, -90252, -120797, + -153590, -180846, -212338, -240701, -268837, -292589, + -315071, -330749, -341626, -350148, -349717, -341020, + -321991, -296385, -259725, -214521, -161010, -95406, + -24910, 56696, 146420, 244250, 343559, 452730, + 558328, 663250, 762184, 865981, 953691, 1033614, + 1102113, 1146873, 1184623, 1193892, 1178554, 1142859, + 1077203, 986336, 862134, 713246, 531955, 325661, + 92277, -163732, -444123, -741602, -1049074, -1363826, + -1673315, -1986171, -2284459, -2565083, -2814370, -3040133, + -3213891, -3347594, -3418856, -3434223, -3384851, -3262396, + -3066903, -2788032, -2437241, -2010678, -1507173, -933398, + -292175, 401186, 1147352, 1924628, 2732596, 3549354, + 4364626, 5154297, 5908401, 6604560, 7227639, 7762620, + 8187446, 8485952, 8644128, 8647068, 8487648, 8152221, + 7637666, 6938503, 6053636, 4993121, 3757798, 2362454, + 824586, -836731, -2601505, -4437764, -6320658, -8213153, + -10084097, -11885518, -13592349, -15153379, -16539412, -17701707, + -18614256, -19232046, -19532284, -19487537, -19071832, -18272835, + -17080871, -15486581, -13507411, -11145107, -8429888, -5384383, + -2046831, 1539831, 5322377, 9232369, 13214694, 17192520, + 21092853, 24835370, 28351421, 31545946, 34345883, 36680788, + 38470656, 39655664, 40177693, 39987331, 39049848, 37341196, + 34842396, 31562278, 27514832, 22737753, 17268732, 11184374, + 4553185, -2521582, -9942347, -17586988, -25318003, -33004376, + -40502110, -47661459, -54324353, -60352266, -65595404, -69912251, + -73185900, -75289166, -76129593, -75628186, -73725851, -70384308, + -65592931, -59374400, -51767812, -42836205, -32691229, -21454188, + -9277580, 3661148, 17155201, 30992883, 44929675, 58721466, + 72101400, 84812804, 96588363, 107172798, 116308292, 123771871, + 129349707, 132844569, 134111243, 133017754, 129482950, 123461622, + 114953182, 103996453, 90695125, 75177530, 57638338, 38301433, + 17446062, -4619599, -27538997, -50938883, -74412221, -97544926, + -119890697, -141021854, -160509246, -177915765, -192864953, -204975605, + -213910563, -219386073, -221174163, -219080029, -213000947, -202885489, + -188762284, -170723570, -148948541, -123686136, -95259386, -64055427, + -30526184, 4796392, 41356982, 78546374, 115716100, 152196811, + 187309768, 220376926, 250730546, 277732060, 300774553, 319307850, + 332839493, 340957166, 343321132, 339690110, 329923997, 313993109, + 291964388, 264026987, 230483360, 191744445, 148326011, 100855269, + 50040078, -3320582, -58361692, -114153996, -169724988, -224082501, + -276218832, -325139925, -369868955, -409475994, -443108525, -469982022, + -489407140, -500819525, -503770287, -497957407, -483219505, -459561117, + -427126685, -386245337, -337398907, -281210112, -218478327, -150122739, + -77193519, -857934, 77633280, 156947583, 235700971, 312486893, + 385900471, 454546040, 517078779, 572234396, 618846940, 655866323, + 682385018, 697661309, 701140616, 692455705, 671454559, 638191695, + 592953243, 536228161, 468740763, 391410722, 305371394, 211913742, + 112517115, 8779394, -97571576, -204721044, -310812944, -413944482, + -512242592, -603866176, -687055198, -760155313, -821656150, -870226938, + -904719195, -924232004, -928094286, -915902067, -887526961, -843128897, + -783147032, -708310751, -619625914, -518372450, -406053401, -284426943, + -155438894, -21198654, 116042557, 253946179, 390103902, 522103112, + 647549938, 764131222, 869639373, 962024696, 1039435602, 1100238386, + 1143082131, 1166889988, 1170916785, 1154742462, 1118300936, 1061877010, + 986124238, 892031533, 780943280, 654515630, 514699010, 363722438, + 204041308, 38296251, -130713333, -300089725, -466886857, -628155818, + -781011029, -922654557, -1050458538, -1161990550, -1255074187, -1327830448, + -1378699528, -1406489333, -1410401993, -1390048875, -1345442734, -1277046744, + -1185735381, -1072791871, -939913349, -789148010, -622904148, -443859970, + -254989459, -59453972, 139440960, 338268373, 533579021, 721939184, + 899993480, 1064547333, 1212580705, 1341356167, 1448429738, 1531710189, + 1589513254, 1620570159, 1624075071, 1599693216, 1547576100, 1468358349, + 1363160695, 1233557983, 1081585799, 909666978, 720606772, 517535787, + 303843415, 83155845, -140774037, -364089673, -582915806, -793434722, + -991929280, -1174879622, -1339004843, -1481331242, -1599239695, -1690521084, + -1753414617, -1786655673, -1789471827, -1761622946, -1703404590, -1615638103, + -1499681710, -1357368825, -1191014889, -1003370614, -797569666, -577065119, + -345612065, -107143552, 134247659, 374406599, 609174673, 834479923, + 1046391045, 1241200833, 1415476892, 1566138455, 1690498403, 1786340377, + 1851905391, 1885980406, 1887879581, 1857497280, 1795259750, 1702182967, + 1579787973, 1430138425, 1255747801, 1059596968, 845018463, 615693435, + 375556538, 128723997, -120541681, -367952127, -609245853, -840251626, + -1056983758, -1255713119, -1433002929, -1585806827, -1711487302, -1807896047, + -1873374729, -1906818169, -1907682853, -1875971972, -1812263992, -1717703065, + -1593954268, -1443193039, -1268056578, -1071600342, -857256745, -628746553, + -390033866, -145248896, 101367834, 345584281, 583192434, 810121403, + 1022514754, 1216749114, 1389559178, 1538036051, 1659720826, 1752625201, + 1815263564, 1846687542, 1846482241, 1814804568, 1752335291, 1660298657, + 1540415690, 1394895914, 1226369062, 1037859231, 832714547, 614553921, + 387208246, 154635241, -79138710, -310077686, -534233497, -747807910, + -947188843, -1129059176, -1290398152, -1428596523, -1541438634, -1627173606, + -1684538320, -1712767041, -1711595046, -1681286807, -1622597001, -1536771335, + -1425516195, -1290963285, -1135617456, -962344519, -774276536, -574780100, + -367390670, -155754790, 56472073, 265619298, 468138053, 660610367, + 839838555, 1002881515, 1147110243, 1270246183, 1370408966, 1446132923, + 1496387070, 1520594854, 1518642268, 1490871859, 1438060822, 1361413472, + 1262533951, 1143393613, 1006287680, 853798274, 688736004, 514105396, + 333012732, 148667398, -35733530, -217014467, -392110758, -558100965, + -712261129, -852105187, -975443549, -1080391668, -1165419174, -1229358286, + -1271414669, -1291210466, -1288731328, -1264359862, -1218860857, -1153341530, + -1069241701, -968310686, -852532664, -724155275, -585580585, -439357512, + -288125820, -134567565, 18641167, 168876530, 313606578, 450450547, + 577187923, 691823560, 792614885, 878071523, 947009493, 998553637, + 1032138861, 1047522337, 1044786400, 1024325396, 986827656, 933271381, + 864889514, 783149214, 689722654, 586443194, 475288458, 358321978, + 237687607, 115515445, -6047806, -124934122, -239156594, -346852125, + -446302911, -535987147, -614574458, -680951101, -734251225, -773853212, + -799381512, -810715674, -807980350, -791554564, -762030650, -720222509, + -667136883, -603952781, -532002178, -452725279, -367667954, -278430473, + -186653775, -93972100, -2008492, 87674367, 173587352, 254349650, + 328707091, 395532579, 453881657, 502968672, 542187532, 571122852, + 589545497, 597423743, 594906342, 582312760, 560132475, 529012045, + 489738788, 443207538, 390429237, 332480939, 270507669, 205698013, + 139248854, 72343880, 6161787, -58185019, -119638793, -177222667, + -230069141, -277392475, -318549855, -353017704, -380401245, -400449224, + -413034731, -418173539, -416007937, -406810636, -390947543, -368915371, + -341281976, -308709781, -271917570, -231677874, -188800752, -144107774, + -98436708, -52602612, -7411234, 36384414, 78073041, 117002200, + 152593715, 184344809, 211842274, 234752359, 252842032, 265962120, + 274065260, 277185824, 275449286, 269054677, 258286311, 243480550, + 225049447, 203437341, 179141946, 152679159, 124587493, 95420206, + 65717940, 36017421, 6836042, -21343530, -48068436, -72924828, + -95564270, -115673579, -133003852, -147361340, -158615881, -166696411, + -171587602, -173332374, -172021708, -167813897, -160892709, -151487639, + -139867533, -126332160, -111186743, -94771864, -77414398, -59468599, + -41264688, -23136882, -5393390, 11673173, 27787932, 42720560, + 56258677, 68224110, 78480457, 86924579, 93484306, 98135239, + 100882999, 101760369, 100841495, 98224064, 94030202, 88408482, + 81519998, 73548785, 64683174, 55119877, 45056490, 34697694, + 24240625, 13872761, 3766924, -5911143, -15005474, -23390680, + -30955991, -37604248, -43269353, -47895977, -51454249, -53937007, + -55362525, -55747797, -55145509, -53618025, -51236984, -48085430, + -44268219, -39886204, -35034027, -29836702, -24398794, -18829886, + -13230267, -7714345, -2360118, 2740293, 7512401, 11880497, + 15801966, 19227412, 22118471, 24467824, 26244407, 27468824, + 28135353, 28271925, 27906481, 27074587, 25818645, 24179863, + 22210583, 19974799, 17518427, 14905291, 12182096, 9415316, + 6650447, 3941996, 1322253, -1147115, -3452698, -5548001, + -7414029, -9030592, -10383149, -11471664, -12284872, -12825237, + -13105151, -13137584, -12935370, -12509734, -11898201, -11110368, + -10182305, -9134505, -7994237, -6789150, -5547559, -4288857, + -3040785, -1826870, -664203, 428580, 1435486, 2347513, + 3156311, 3844950, 4416372, 4868942, 5201790, 5414675, + 5520660, 5510424, 5404147, 5214941, 4938663, 4597616, + 4199190, 3756301, 3279832, 2777704, 2263902, 1749437, + 1241556, 754804, 295430, -138960, -532715, -883294, + -1191253, -1456374, -1673086, -1837247, -1953436, -2026864, + -2056034, -2045306, -1996661, -1918087, -1810768, -1676714, + -1527078, -1358080, -1181368, -994156, -808485, -625825, + -444558, -269900, -109532, 35633, 171250, 289167, + 391357, 477326, 547758, 597162, 631158, 651246, + 658747, 652056, 630488, 604961, 565338, 524089, + 468544, 414088, 361691, 302709, 245522, 189197, + 133521, 86065, 35459, -10093, -45678, -78284, + -107849, -127244, -147945, -159990, -166806, -172400, + -172766, -166698, -161371, -155608, -142927, -131151, + -117442, -103171, -87695, -73917, -59685, -43890, + -32345, -17413, -8851, 1262, 10615, 13688, + 22228, 26986, 33290, 32113, 31330, 36857, + 35941, 33027, 31131, 28558, 25825, 25129, + 20114, 20537, 15259, 10616, 7286, 6079, + 2197, 1142, 1303, 2290, -964, -3359, + -1473, -2972, -5153, -4402, -4875, -2764, + -2954, -2435, -6289, -2906, -1971, -1469, + -1069, -1732, -1718, -2575, -802, -2749, + 882, 1954, 1617, -292, -6, 2813, + 1640, -2041, -979, -122, -997, 1850, + 717, 1785, 1849, 1967, +}; + +static const int32_t fft_in_imag_1024_q31[1024] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +}; + +static const int32_t fft_ref_real_1024_q31[1024] = { + 28, -16, 40, -36, -11, 23, + -2, 7, 65, 28, -27, 3, + 62, -17, 36, 122, -55154, 1535502, + -13543813, 57130836, -135763827, 195823639, -176199334, 98119761, + -32279433, 5635597, -409816, 6072, -21, -83, + -21, 67, -30, -1, 1, 3, + 42, -5, 77, 67, -11, -9, + 24, -27, -78, -11, 18, -61, + -28, 16, -7, 46, -11, 10, + -8, -47, 95, 12, -3, -22, + -8, -46, 24, 59, -6, 32, + 26, 18, 35, 8, 52, -23, + -67, -17, -26, -3, -10, -47, + 32, 35, -9, 38, 14, 30, + 36, 2, -7, 63, 32, -84, + 30, 19, -9, 6, 43, 11, + -2, -5, -47, -43, 4, 8, + -22, -6, -30, -63, -43, -14, + 20, 2, 86, -5, 39, -58, + 37, -42, -4, 27, 0, -16, + -30, 20, -67, -31, 40, -74, + 57, -62, -8, -6, 23, 13, + 3, 21, -51, 10, 64, -25, + 11, -3, 12, 38, -22, 18, + -5, 0, 41, -14, 30, -16, + -11, 11, -18, 36, -29, -54, + 20, -14, -6, -28, 21, 15, + 78, -17, 48, -23, -13, 16, + 27, -22, -12, -2, -85, -4, + -23, -43, 64, 6, 1, 31, + 35, 19, 23, -1, 22, 54, + 18, 6, -25, -42, 2, 41, + -18, -40, -43, 31, -26, 37, + -34, 13, 7, -16, 9, 72, + 38, 2, 44, -54, -28, -56, + 1, -58, 51, 59, 84, -48, + 39, -80, 6, 21, -6, 21, + -25, -24, -54, -67, -1, 11, + 4, -80, 3, -12, -24, -59, + -3, 57, -9, -36, -24, -28, + -31, -19, -40, -24, 4, -9, + 5, -64, -16, 25, 19, 53, + 2, -60, 48, -25, 55, -27, + 61, 17, 43, 36, -15, 6, + -98, -38, -4, 63, -14, 57, + 7, 19, -6, 12, -18, 51, + -48, 39, 4, -63, -3, -1, + -59, -15, 16, 61, -8, 12, + 5, 29, -38, 65, 29, -10, + -25, -19, 22, 17, -53, 12, + -29, 13, 7, -8, -27, 3, + 62, -4, -29, -35, 9, 40, + -69, 9, -23, 18, 21, -92, + -42, 20, -15, 5, 26, 20, + 32, 59, -17, 25, -3, 57, + -40, 9, 8, 90, -40, 16, + -119, -32, 26, -35, 18, 21, + -22, 45, 17, 29, -24, -14, + -44, -29, -59, -6, 17, -7, + -33, -37, 14, -53, 16, -17, + -59, -20, -24, -19, -58, -21, + 11, -12, 10, -13, 22, -18, + 4, -30, 53, -46, -6, -51, + 45, -21, 46, -1, 14, -22, + -33, -25, -28, 30, 1, 45, + 78, 6, -26, -6, 17, -27, + 52, -9, 20, -40, -3, 16, + 36, -21, -60, 2, 16, -56, + 13, 0, 20, -3, 46, -8, + -65, -2, -26, -27, 38, -41, + 32, -11, 6, 12, 55, -22, + 23, 47, 56, 25, -4, -27, + -14, -26, 17, -49, -5, 49, + -16, 29, -42, 51, -14, 56, + 18, -62, -31, -10, -38, -22, + -56, -60, -39, 42, 9, 90, + 29, 79, 27, 2, -27, -60, + -20, 7, 26, -6, 86, -94, + 0, -31, 7, -22, 46, 44, + 22, -64, 25, 47, -49, -24, + 62, 5, 7, -59, 40, -3, + -27, 16, 7, -32, -20, -41, + 84, -36, 21, -81, 96, 48, + 58, 16, -48, -16, -72, 29, + 36, 21, -30, -21, -55, 68, + -20, -40, -24, -40, -20, 68, + -55, -21, -30, 21, 36, 29, + -72, -16, -48, 16, 58, 48, + 96, -81, 21, -36, 84, -41, + -20, -32, 7, 16, -27, -3, + 40, -59, 7, 5, 62, -24, + -49, 47, 25, -64, 22, 44, + 46, -22, 7, -31, 0, -94, + 86, -6, 26, 7, -20, -60, + -27, 2, 27, 79, 29, 90, + 9, 42, -39, -60, -56, -22, + -38, -10, -31, -62, 18, 56, + -14, 51, -42, 29, -16, 49, + -5, -49, 17, -26, -14, -27, + -4, 25, 56, 47, 23, -22, + 55, 12, 6, -11, 32, -41, + 38, -27, -26, -2, -65, -8, + 46, -3, 20, 0, 13, -56, + 16, 2, -60, -21, 36, 16, + -3, -40, 20, -9, 52, -27, + 17, -6, -26, 6, 78, 45, + 1, 30, -28, -25, -33, -22, + 14, -1, 46, -21, 45, -51, + -6, -46, 53, -30, 4, -18, + 22, -13, 10, -12, 11, -21, + -58, -19, -24, -20, -59, -17, + 16, -53, 14, -37, -33, -7, + 17, -6, -59, -29, -44, -14, + -24, 29, 17, 45, -22, 21, + 18, -35, 26, -32, -119, 16, + -40, 90, 8, 9, -40, 57, + -3, 25, -17, 59, 32, 20, + 26, 5, -15, 20, -42, -92, + 21, 18, -23, 9, -69, 40, + 9, -35, -29, -4, 62, 3, + -27, -8, 7, 13, -29, 12, + -53, 17, 22, -19, -25, -10, + 29, 65, -38, 29, 5, 12, + -8, 61, 16, -15, -59, -1, + -3, -63, 4, 39, -48, 51, + -18, 12, -6, 19, 7, 57, + -14, 63, -4, -38, -98, 6, + -15, 36, 43, 17, 61, -27, + 55, -25, 48, -60, 2, 53, + 19, 25, -16, -64, 5, -9, + 4, -24, -40, -19, -31, -28, + -24, -36, -9, 57, -3, -59, + -24, -12, 3, -80, 4, 11, + -1, -67, -54, -24, -25, 21, + -6, 21, 6, -80, 39, -48, + 84, 59, 51, -58, 1, -56, + -28, -54, 44, 2, 38, 72, + 9, -16, 7, 13, -34, 37, + -26, 31, -43, -40, -18, 41, + 2, -42, -25, 6, 18, 54, + 22, -1, 23, 19, 35, 31, + 1, 6, 64, -43, -23, -4, + -85, -2, -12, -22, 27, 16, + -13, -23, 48, -17, 78, 15, + 21, -28, -6, -14, 20, -54, + -29, 36, -18, 11, -11, -16, + 30, -14, 41, 0, -5, 18, + -22, 38, 12, -3, 11, -25, + 64, 10, -51, 21, 3, 13, + 23, -6, -8, -62, 57, -74, + 40, -31, -67, 20, -30, -16, + 0, 27, -4, -42, 37, -58, + 39, -5, 86, 2, 20, -14, + -43, -63, -30, -6, -22, 8, + 4, -43, -47, -5, -2, 11, + 43, 6, -9, 19, 30, -84, + 32, 63, -7, 2, 36, 30, + 14, 38, -9, 35, 32, -47, + -10, -3, -26, -17, -67, -23, + 52, 8, 35, 18, 26, 32, + -6, 59, 24, -46, -8, -22, + -3, 12, 95, -47, -8, 10, + -11, 46, -7, 16, -28, -61, + 18, -11, -78, -27, 24, -9, + -11, 67, 77, -5, 42, 3, + 1, -1, -30, 67, -21, -83, + -21, 6072, -409816, 5635597, -32279433, 98119761, + -176199334, 195823639, -135763827, 57130836, -13543813, 1535502, + -55154, 122, 36, -17, 62, 3, + -27, 28, 65, 7, -2, 23, + -11, -36, 40, -16, +}; + +static const int32_t fft_ref_imag_1024_q31[1024] = { + 0, -7, -54, 77, 13, 24, + 39, -30, 30, -28, -25, 2, + 30, -15, 23, -34, 50485, -1395758, + 12235464, -51294594, 121144577, -173660896, 155294491, -85945123, + 28099645, -4875526, 352336, -5061, -5, 10, + -18, 14, -31, -55, 65, -37, + 34, -52, -5, 56, -13, -45, + -15, -15, 11, 44, -21, 3, + 55, 54, 61, -36, -27, -47, + -44, 19, -26, -13, 12, -45, + 35, 51, -67, -9, 11, -54, + 28, 92, 15, -32, -46, 10, + -8, -15, -6, 7, 14, 68, + -19, -68, 20, 27, -51, 92, + 4, -11, 39, -15, 36, -38, + 6, -8, 11, 45, 27, 13, + 24, 48, -2, 20, 6, 3, + -9, 4, 86, 10, 11, 8, + -45, 80, 28, -23, 7, 11, + 6, -50, -66, 34, 102, 95, + 8, 36, 2, -72, -22, 55, + -21, 24, -5, 1, 35, -3, + -68, -20, -2, -7, 49, -65, + -34, -15, 19, 108, 55, 9, + 16, -24, 2, -18, -18, 37, + 67, 16, 15, -11, -7, -23, + 25, -8, 8, -20, 10, 41, + 32, -9, -81, -12, -29, 47, + 5, -31, -17, -67, -17, -32, + 16, -47, 12, -30, 18, -23, + -20, 14, 21, 27, 2, -99, + -28, 22, -11, 8, -15, -44, + -8, -2, 1, -46, 61, -16, + 30, 18, 14, 8, 29, 16, + -69, 29, -43, -33, -2, 23, + 53, -71, -51, -10, -1, -29, + 33, -7, -43, -25, 47, -49, + 44, 17, -16, 55, 53, 48, + 32, 60, -15, -15, 34, -31, + -34, 36, -11, 22, 18, 7, + 49, 48, -19, -70, 50, -15, + -91, 75, 4, -14, 36, 14, + -1, 16, 2, -3, -49, 29, + 44, 64, -74, 11, 42, 11, + -12, -64, -76, -11, 2, -35, + 22, -48, -39, -31, -33, -18, + -33, 34, 8, 66, 43, 8, + -2, 39, 29, -16, 3, 28, + 8, -50, -54, 41, 14, -34, + -2, -33, 23, -8, 21, -29, + 13, 62, 9, -21, -30, 31, + 56, 44, 14, 20, 12, -8, + -2, -7, -1, 40, 30, -1, + 22, -43, 88, 68, 36, -51, + -75, 21, -61, -40, -12, -8, + -57, 5, -1, 28, -41, -17, + 22, 34, -63, -27, 24, 57, + -86, -4, -16, -53, 15, 26, + 14, -27, -23, -48, 16, -28, + -6, -37, 38, -39, -2, 32, + -56, 40, 15, -26, -73, -21, + 28, -62, 4, 76, 23, 49, + -1, -40, 51, -29, 4, 49, + 5, -3, -36, 41, 27, -16, + -11, -47, -12, 4, 2, 32, + -79, 67, -24, 45, 23, -15, + 66, -7, 60, -76, -17, -45, + -20, 17, -3, -13, 2, 9, + 19, 16, 6, -29, 23, -15, + 98, 3, 11, 22, 38, -10, + 2, -12, 20, 32, 30, 34, + 54, 47, -25, -15, -75, 38, + -10, 49, 28, -81, -1, 21, + 6, 39, -68, -31, -11, -45, + -19, 10, -27, -11, 29, -26, + 39, 3, -53, 17, 111, 58, + -3, -27, -26, -16, 57, 19, + 5, 34, 17, 68, -22, 31, + 28, 8, 36, 10, -52, 43, + 4, 35, -34, 2, -8, 40, + 33, -68, -35, 32, 4, 38, + -27, -24, 30, -15, 1, -35, + -19, -33, 43, 9, 15, -30, + -38, -10, -4, -48, 17, -12, + 20, -20, 40, -60, 27, 12, + 47, -13, 0, 13, -47, -12, + -27, 60, -40, 20, -20, 12, + -17, 48, 4, 10, 38, 30, + -15, -9, -43, 33, 19, 35, + -1, 15, -30, 24, 27, -38, + -4, -32, 35, 68, -33, -40, + 8, -2, 34, -35, -4, -43, + 52, -10, -36, -8, -28, -31, + 22, -68, -17, -34, -5, -19, + -57, 16, 26, 27, 3, -58, + -111, -17, 53, -3, -39, 26, + -29, 11, 27, -10, 19, 45, + 11, 31, 68, -39, -6, -21, + 1, 81, -28, -49, 10, -38, + 75, 15, 25, -47, -54, -34, + -30, -32, -20, 12, -2, 10, + -38, -22, -11, -3, -98, 15, + -23, 29, -6, -16, -19, -9, + -2, 13, 3, -17, 20, 45, + 17, 76, -60, 7, -66, 15, + -23, -45, 24, -67, 79, -32, + -2, -4, 12, 47, 11, 16, + -27, -41, 36, 3, -5, -49, + -4, 29, -51, 40, 1, -49, + -23, -76, -4, 62, -28, 21, + 73, 26, -15, -40, 56, -32, + 2, 39, -38, 37, 6, 28, + -16, 48, 23, 27, -14, -26, + -15, 53, 16, 4, 86, -57, + -24, 27, 63, -34, -22, 17, + 41, -28, 1, -5, 57, 8, + 12, 40, 61, -21, 75, 51, + -36, -68, -88, 43, -22, 1, + -30, -40, 1, 7, 2, 8, + -12, -20, -14, -44, -56, -31, + 30, 21, -9, -62, -13, 29, + -21, 8, -23, 33, 2, 34, + -14, -41, 54, 50, -8, -28, + -3, 16, -29, -39, 2, -8, + -43, -66, -8, -34, 33, 18, + 33, 31, 39, 48, -22, 35, + -2, 11, 76, 64, 12, -11, + -42, -11, 74, -64, -44, -29, + 49, 3, -2, -16, 1, -14, + -36, 14, -4, -75, 91, 15, + -50, 70, 19, -48, -49, -7, + -18, -22, 11, -36, 34, 31, + -34, 15, 15, -60, -32, -48, + -53, -55, 16, -17, -44, 49, + -47, 25, 43, 7, -33, 29, + 1, 10, 51, 71, -53, -23, + 2, 33, 43, -29, 69, -16, + -29, -8, -14, -18, -30, 16, + -61, 46, -1, 2, 8, 44, + 15, -8, 11, -22, 28, 99, + -2, -27, -21, -14, 20, 23, + -18, 30, -12, 47, -16, 32, + 17, 67, 17, 31, -5, -47, + 29, 12, 81, 9, -32, -41, + -10, 20, -8, 8, -25, 23, + 7, 11, -15, -16, -67, -37, + 18, 18, -2, 24, -16, -9, + -55, -108, -19, 15, 34, 65, + -49, 7, 2, 20, 68, 3, + -35, -1, 5, -24, 21, -55, + 22, 72, -2, -36, -8, -95, + -102, -34, 66, 50, -6, -11, + -7, 23, -28, -80, 45, -8, + -11, -10, -86, -4, 9, -3, + -6, -20, 2, -48, -24, -13, + -27, -45, -11, 8, -6, 38, + -36, 15, -39, 11, -4, -92, + 51, -27, -20, 68, 19, -68, + -14, -7, 6, 15, 8, -10, + 46, 32, -15, -92, -28, 54, + -11, 9, 67, -51, -35, 45, + -12, 13, 26, -19, 44, 47, + 27, 36, -61, -54, -55, -3, + 21, -44, -11, 15, 15, 45, + 13, -56, 5, 52, -34, 37, + -65, 55, 31, -14, 18, -10, + 5, 5061, -352336, 4875526, -28099645, 85945123, + -155294491, 173660896, -121144577, 51294594, -12235464, 1395758, + -50485, 34, -23, 15, -30, -2, + 25, 28, -30, 30, -39, -24, + -13, -77, 54, 7, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi_1536_32.h b/test/cmocka/src/math/fft/ref_fft_multi_1536_32.h new file mode 100644 index 000000000000..3b80ddea426a --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_1536_32.h @@ -0,0 +1,1044 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_1536_NUM_TESTS 1 + +static const int32_t fft_in_real_1536_q31[1536] = { + -1307, -574, -1210, -1522, -1899, 1071, + 855, 2163, 1521, 2259, 1260, -2999, + 433, 1384, -1287, -2171, 1479, 1583, + -1436, 1011, 4189, 2711, -946, -195, + -2543, 1178, -1736, 772, 1522, -171, + -1454, -1564, -1958, -4470, -3253, -3927, + -4950, -5304, -4795, -3937, -4683, -5511, + -5491, -2036, -46, -2309, -4636, 183, + 1165, 889, 2769, 2573, 4187, 7141, + 10550, 8534, 13292, 12890, 13854, 14933, + 14481, 13572, 19470, 17619, 19996, 15501, + 14335, 15941, 10852, 9125, 9930, 6717, + 3435, -122, -7217, -14931, -15699, -19050, + -28226, -29840, -39221, -38444, -45330, -48565, + -53919, -51940, -56165, -59291, -56469, -54002, + -50482, -46240, -39727, -31555, -24931, -13667, + -4067, 7601, 19601, 36606, 49720, 66264, + 82262, 93798, 109492, 123549, 138328, 146587, + 153740, 163017, 163203, 163630, 160765, 157379, + 146736, 132520, 113001, 93878, 69705, 39592, + 12865, -21580, -56672, -95272, -131691, -174549, + -213209, -248628, -283486, -320449, -346051, -370771, + -392071, -407380, -415127, -415461, -403141, -387183, + -367199, -327447, -286189, -235079, -175686, -108377, + -31956, 45401, 128250, 217821, 312206, 403171, + 493176, 576281, 661962, 734196, 802037, 857666, + 899782, 931826, 947158, 943468, 922552, 883848, + 826153, 747513, 653458, 535042, 402552, 250199, + 86048, -86449, -277634, -465706, -659677, -859066, + -1050155, -1237367, -1413054, -1568939, -1705530, -1823177, + -1913070, -1972205, -1997013, -1988742, -1939559, -1853061, + -1727260, -1564661, -1362612, -1120399, -846100, -538521, + -204309, 151603, 528919, 922290, 1315125, 1706894, + 2090470, 2458389, 2799972, 3109863, 3382597, 3609505, + 3778017, 3891544, 3933694, 3912353, 3813931, 3643198, + 3393850, 3071142, 2677376, 2209600, 1677941, 1084818, + 444967, -243363, -962452, -1701393, -2442824, -3187052, + -3905129, -4595717, -5232588, -5810315, -6311599, -6728312, + -7036669, -7235070, -7315570, -7261861, -7076599, -6757898, + -6294514, -5696302, -4963545, -4110784, -3133421, -2057740, + -890886, 352251, 1643641, 2971293, 4311667, 5637297, + 6922700, 8146290, 9279509, 10298347, 11182888, 11906619, + 12445720, 12792796, 12920677, 12821426, 12487235, 11917145, + 11098463, 10047806, 8770879, 7274529, 5582694, 3712279, + 1694100, -446673, -2678418, -4957743, -7246818, -9512063, + -11705023, -13778294, -15700344, -17427663, -18912276, -20124761, + -21027320, -21598948, -21801191, -21628479, -21056400, -20085908, + -18714238, -16955159, -14813766, -12321078, -9504162, -6399966, + -3054231, 482872, 4154302, 7905278, 11666569, 15378054, + 18958123, 22345534, 25474375, 28277167, 30683302, 32642235, + 34096393, 35003550, 35319949, 35025915, 34092432, 32521600, + 30307717, 27471468, 24039684, 20045508, 15546072, 10598856, + 5269966, -350481, -6180026, -12114692, -18059248, -23906672, + -29549875, -34871747, -39782448, -44161036, -47925834, -50975328, + -53235322, -54634944, -55118776, -54647517, -53185173, -50739616, + -47302385, -42904835, -37598374, -31437470, -24504539, -16886940, + -8713803, -96592, 8822281, 17893277, 26962568, 35868287, + 44446216, 52535664, 59974374, 66609968, 72289304, 76896286, + 80294207, 82394351, 83111692, 82389627, 80191979, 76513564, + 71358551, 64784668, 56848569, 47656194, 37330198, 26009511, + 13864615, 1086171, -12123873, -25537363, -38932152, -52068869, + -64704797, -76601691, -87525849, -97258037, -105582362, -112312248, + -117278944, -120341163, -121382694, -120326971, -117128187, -111776250, + -104303150, -94772849, -83295810, -70008000, -55097092, -38780459, + -21296115, -2915789, 16048887, 35294650, 54490243, 73286361, + 91346168, 108333722, 123911975, 137767211, 149615571, 159177154, + 166229885, 170578636, 172063686, 170577539, 166068796, 158531146, + 148010324, 134608279, 118482912, 99845751, 78943021, 56093794, + 31643166, 5972435, -20501213, -47329173, -74051124, -100196883, + -125294427, -148870026, -170477108, -189679210, -206075759, -219304043, + -229055107, -235069748, -237136842, -235122812, -228956016, -218642090, + -204251958, -185931479, -163914657, -138473803, -109988389, -78864741, + -45593192, -10699983, 25253171, 61650957, 97869663, 133278383, + 167232254, 199106861, 228282653, 254196068, 276312161, 294146665, + 307294652, 315410249, 318234645, 315590297, 307394443, 293664335, + 274509339, 250133892, 220842123, 187039901, 149209960, 107922433, + 63810361, 17587760, -29985506, -78117921, -125968455, -172708192, + -217493625, -259497359, -297927725, -332031196, -361123362, -384588415, + -401886494, -412588709, -416366237, -413004376, -402403545, -384595162, + -359740975, -328120781, -290142483, -246340640, -197348989, -143910091, + -86867351, -27143103, 34285708, 96376993, 158069138, 218280055, + 275929446, 329963897, 379373709, 423197160, 460572512, 490705168, + 512948401, 526747189, 531695512, 527540747, 514177226, 491657698, + 460188457, 420160343, 372096220, 316680397, 254738394, 187222293, + 115197014, 39828687, -37626355, -115870108, -193554390, -269321025, + -341820450, -409733063, -471798151, -526831940, -573748345, -611594031, + -639544543, -656949500, -663308649, -658325717, -641880896, -614068050, + -575168915, -525665290, -466238167, -397738580, -321208417, -237834108, + -148957438, -56007249, 39465483, 135841047, 231468773, 324681365, + 413821307, 497283182, 573521157, 641095651, 698712130, 745197774, + 779567711, 801049388, 809057254, 803237808, 783489679, 749925411, + 702911733, 643063728, 571208755, 488423234, 395954144, 295275675, + 187993978, 75865718, -39236308, -155364925, -270531450, -382717564, + -489957676, -590312404, -681949986, -763163139, -832392865, -888277334, + -929664966, -955628349, -965507939, -958906225, -935713724, -896099293, + -840526616, -769729759, -684734549, -586814614, -477494414, -358504690, + -231768214, -99384696, 36447617, 173415519, 309178420, 441371753, + 567666025, 685811530, 793656966, 889216942, 970688561, 1036488980, + 1085290370, 1116036006, 1127980589, 1120686956, 1094053945, 1048302464, + 983994405, 902020613, 803589058, 690200491, 563631899, 425926519, + 279325343, 126250979, -30724886, -188948326, -345694846, -498252679, + -643944275, -780184780, -904516055, -1014670896, -1108601825, -1184506299, + -1240890909, -1276581824, -1290734322, -1282895863, -1252960854, -1201218312, + -1128343320, -1035375507, -923712972, -795088635, -651552657, -495428590, + -329277266, -155868968, 21884630, 200961971, 378296024, 550818202, + 715513308, 869463796, 1009937937, 1134384860, 1240514038, 1326341350, + 1390206244, 1430809681, 1447252889, 1439042709, 1406104903, 1348787986, + 1267878591, 1164563795, 1040427150, 897443541, 737906293, 564423186, + 379869427, 187329491, -9955718, -208626909, -405282321, -596523018, + -779023314, -949576746, -1105159690, -1242989351, -1360560433, -1455708690, + -1526631531, -1571933920, -1590652703, -1582289863, -1546784045, -1484564044, + -1396513095, -1283969795, -1148697739, -992870821, -819029807, -630048695, + -429062628, -219454929, -4764302, 211344971, 425177867, 633047097, + 831343127, 1016615527, 1185591113, 1335287179, 1463017725, 1566460527, + 1643703210, 1693272282, 1714173828, 1705879519, 1668383535, 1602171121, + 1508225260, 1388013119, 1243466543, 1076941063, 891185548, 689291733, + 474640802, 250860397, 21738447, -208811879, -436851181, -658444086, + -869778675, -1067171636, -1247182880, -1406650050, -1542754248, -1653063285, + -1735584343, -1788792418, -1811656971, -1803674070, -1764855225, -1695756123, + -1597458692, -1471529123, -1320042483, -1145495192, -950811122, -739251472, + -514387884, -280038811, -40182539, 201082127, 439625474, 671360194, + 892281969, 1098593058, 1286704310, 1453353848, 1595632929, 1711032396, + 1797519314, 1853535499, 1878057863, 1870596072, 1831203976, 1760492969, + 1659601101, 1530204850, 1374462215, 1194990025, 994815702, 777344707, + 546257874, 305494569, 59165380, -188527365, -433343031, -671080193, + -897665887, -1109212583, -1302074592, -1472935050, -1618847731, -1737293175, + -1826220505, -1884077847, -1909862809, -1903102016, -1863908084, -1792915406, + -1691338340, -1560892199, -1403810772, -1222762623, -1020844224, -801519269, + -568521705, -325842895, -77639026, 171850260, 418354109, 657652397, + 885658006, 1098483323, 1292482492, 1464354264, 1611173802, 1730447918, + 1820147456, 1878774327, 1905345015, 1899436591, 1861181614, 1791269880, + 1690931416, 1561918192, 1406474208, 1227285856, 1027453891, 810423456, + 579930851, 339935975, 94561541, -151995804, -395519520, -631846220, + -856955512, -1067023060, -1258484983, -1428107906, -1573047808, -1690881207, + -1779650546, -1837917712, -1864752691, -1859784222, -1823172826, -1755627369, + -1658388705, -1533199617, -1382280092, -1208279946, -1014241857, -803543612, + -579832950, -346972564, -108975262, 130084072, 366112543, 595091308, + 813135881, 1016560268, 1201935283, 1366175566, 1506546319, 1620740341, + 1706921440, 1763716202, 1790274256, 1786276435, 1751905466, 1687886894, + 1595436847, 1476262351, 1332506505, 1166743251, 981898453, 781224629, + 568212339, 346559921, 120100320, -107291665, -331716427, -549356988, + -756537606, -949779759, -1125851662, -1281839136, -1415194341, -1523750226, + -1605799171, -1660093788, -1685848027, -1682799447, -1651157876, -1591635572, + -1505409467, -1394110995, -1259788475, -1104878691, -932150993, -744662067, + -545708117, -338757382, -127388767, 84763881, 294067482, 496979529, + 690070737, 870117589, 1034133585, 1179439215, 1303678090, 1404887501, + 1481492441, 1532367900, 1556837967, 1554669622, 1526102357, 1471816788, + 1392929409, 1290979584, 1167883699, 1025898547, 867595552, 695801640, + 513558015, 324055197, 130580019, -63531828, -254957837, -440470852, + -616936670, -781439126, -931257387, -1063973979, -1177469886, -1269969396, + -1340089214, -1386823818, -1409580111, -1408192311, -1382898809, -1334344278, + -1263571363, -1172000225, -1061372669, -933760932, -791499808, -637157868, + -473474442, -303337763, -129705392, 44420335, 216069365, 382339648, + 540447254, 687781491, 821934079, 940760571, 1042387135, 1125252799, + 1188147208, 1230201006, 1250924236, 1250187783, 1228227566, 1185647619, + 1123398884, 1042759518, 945299898, 832870179, 707547821, 571626092, + 427527543, 277810041, 125085057, -28010600, -178853506, -324906192, + -463733638, -593048340, -710768042, -815013616, -904172591, -976908539, + -1032173782, -1069239365, -1087698933, -1087470671, -1068778489, -1032179008, + -978515150, -908919940, -824775378, -727706611, -619535673, -502243121, + -377946135, -248861178, -117246162, 14621362, 144491857, 270172298, + 389581420, 500764993, 601939427, 691515419, 768128879, 830643528, + 878195038, 910177424, 926258719, 926396266, 910805964, 879977667, + 834650965, 775805529, 704649184, 622560430, 531100567, 431974140, + 326968596, 217974337, 106897439, -4331905, -113811517, -219713043, + -320271090, -413863122, -498997138, -574345705, -638786489, -691378723, + -731416804, -758409004, -772102118, -772476516, -759734475, -734294552, + -696804594, -648094824, -589172646, -521212233, -445517032, -363502236, + -276673232, -186591246, -94842458, -3022754, 87303105, 174620285, + 257495934, 334583680, 404667701, 466682288, 519703658, 562979891, + 595946616, 618221526, 629610881, 630106942, 619907159, 599363749, + 569010853, 529543975, 481805921, 426750078, 365456250, 299075520, + 228840090, 156015660, 81893049, 7755186, -65128851, -135537978, + -202321503, -264404090, -320822061, -370714643, -413359634, -448173767, + -474696651, -492653799, -501893571, -502433588, -494432932, -478193313, + -454161674, -422891283, -385068437, -341460613, -292938082, -240419450, + -184880948, -127332930, -68805082, -10308903, 47162165, 102642618, + 155226699, 204081975, 248446611, 287663437, 321164632, 348507085, + 369349845, 383472440, 390780777, 391301244, 385159596, 372608714, + 354002348, 329792757, 300514176, 266772038, 229250923, 188660171, + 145771607, 101362438, 56230870, 11158037, -33089190, -75767489, + -116186499, -153708843, -187764622, -217840328, -243526598, -264475454, + -280442868, -291277471, -296907101, -297359175, -292750056, -283273727, + -269212330, -250907995, -228786222, -203299441, -174980678, -144370836, + -112054125, -78619334, -44674297, -10796779, 22429621, 54448874, + 84741856, 112850180, 138327885, 160816025, 180007793, 195653700, + 207572067, 215662380, 219880160, 220249673, 216865158, 209879430, + 199507426, 186012659, 169709832, 150948749, 130113527, 107611242, + 83879355, 59352318, 34467719, 9665911, -14642108, -38040824, + -60157016, -80654418, -99219264, -115589797, -129545820, -140913863, + -149571739, -155444700, -158505797, -158792334, -156363817, -151338055, + -143887461, -134194341, -122498799, -109046102, -94123508, -78025128, + -61059747, -43545883, -25796815, -8129513, 9163546, 25792880, + 41498590, 56033059, 69187641, 80767050, 90630249, 98658995, + 104762234, 108902079, 111059757, 111263586, 109562557, 106046746, + 100833173, 94061670, 85895528, 76519048, 66130807, 54934736, + 43153781, 31007416, 18709409, 6487602, -5465933, -16946274, + -27770029, -37775509, -46814982, -54771683, -61533641, -67030347, + -71205626, -74023788, -75495830, -75627969, -74470032, -72077681, + -68529180, -63937739, -58408135, -52062371, -45042063, -37490140, + -29555197, -21385211, -13122625, -4921524, 3085357, 10759723, + 17992582, 24666389, 30683196, 35971842, 40458997, 44099420, + 46855760, 48721212, 49685704, 49765688, 48994777, 47411331, + 45075651, 42054087, 38424158, 34268812, 29672938, 24740687, + 19571693, 14248378, 8884824, 3562881, -1621239, -6586647, + -11253090, -15555599, -19428913, -22821406, -25700820, -28024865, + -29783485, -30965398, -31574032, -31615670, -31114544, -30104441, + -28614173, -26690187, -24393033, -21759693, -18857738, -15751354, + -12492477, -9153261, -5783717, -2459634, 778698, 3875964, + 6776702, 9449232, 11845786, 13948370, 15720788, 17149101, + 18231430, 18949799, 19315305, 19335514, 19020327, 18395826, + 17478205, 16296941, 14893212, 13283979, 11522416, 9639711, + 7663000, 5644053, 3617443, 1615060, -332168, -2184038, + -3918720, -5508362, -6936545, -8183325, -9232830, -10074356, + -10703608, -11126458, -11331077, -11339686, -11148104, -10770979, + -10228871, -9536383, -8710109, -7770585, -6742184, -5643349, + -4500541, -3328458, -2159579, -1004392, 110110, 1173423, + 2159647, 3069460, 3876884, 4586498, 5177693, 5646960, + 5999906, 6233787, 6347370, 6346598, 6231484, 6021809, + 5711125, 5320225, 4855551, 4327752, 3755975, 3148939, + 2514295, 1870100, 1224054, 591479, -19842, -595926, + -1136695, -1623514, -2058527, -2441755, -2759699, -3009118, + -3195895, -3315318, -3372391, -3367899, -3304971, -3188264, + -3019838, -2809759, -2565867, -2288243, -1979646, -1665042, + -1328619, -993474, -657631, -327993, -16430, 284913, + 562503, 810232, 1034553, 1226932, 1381838, 1513025, + 1599447, 1662854, 1686316, 1682092, 1651127, 1587146, + 1503496, 1397927, 1269542, 1131369, 982502, 824625, + 660881, 493354, 326771, 168908, 16066, -125971, + -261297, -378974, -483268, -576163, -647622, -708224, + -748436, -777452, -785947, -779909, -768879, -735235, + -693141, -644311, -585366, -522056, -451398, -378281, + -301901, -228634, -154426, -81830, -10134, 47735, + 111082, 163294, 207447, 247956, 282325, 307949, + 324908, 333180, 335597, 335296, 325667, 311552, + 293582, 271780, 245119, 219071, 189774, 158232, + 126724, 93564, 64134, 34822, 6228, -19584, + -41721, -63726, -82340, -98638, -109326, -117337, + -126201, -127991, -132091, -130369, -124920, -119589, + -111608, -103992, -92468, -82123, -67954, -61380, + -46424, -35967, -21111, -11739, -5029, 5679, + 13330, 22276, 26343, 35218, 34648, 39078, + 41053, 41092, 46268, 44252, 41586, 40964, + 33470, 36946, 29670, 27351, 23384, 20595, + 14255, 8620, 6966, 7402, 2342, -3982, + -3662, -6609, -4254, -9826, -11984, -13311, + -11772, -11570, -11066, -9660, -9629, -8766, + -9862, -6981, -8621, -6396, -5888, -4708, + -1464, -3442, -1834, -1918, -3426, 1074, + 2306, 544, 72, 3496, 3495, -1310, + 1331, 2847, 5980, 2827, 3263, 1499, + 2773, 1854, 1693, 3452, 2877, -1854, + 724, -2026, -2173, -141, -640, 1167, + 2129, -1066, 1932, -806, -690, -1960, + -506, -1528, -1399, -333, -2033, -851, + -1057, -321, -3212, 2295, -24, -2239, +}; + +static const int32_t fft_in_imag_1536_q31[1536] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; + +static const int32_t fft_ref_real_1536_q31[1536] = { + 36, 4, -4, -16, 8, 47, + -34, 30, -82, -15, 32, -63, + -77, -44, 12, -13, 1, -15, + -7, -13, 58, -10, 19, -16, + -13, 92, -848, 92278, -1546050, 10045551, + -33641357, 65657099, -78882771, 59164075, -27128397, 7128059, + -930416, 42760, -189, 12, -18, 9, + -9, -43, -37, 25, -6, 36, + -13, -15, -64, 43, -7, 3, + 16, -4, 46, 43, 15, -30, + 46, -7, 15, -9, 8, -14, + 29, -1, -53, 49, -19, -15, + -29, -11, -10, -29, -25, -11, + -36, 36, -29, -6, 28, 8, + 49, 23, -32, -27, -28, -25, + 14, 28, -6, 8, -39, 10, + 21, -4, -22, 52, 22, -11, + -27, 17, -1, 10, 30, -40, + -5, 5, 0, -18, 28, -29, + 30, 27, -1, -16, 42, -51, + -84, -14, -24, -26, -4, -4, + -36, -57, -39, 22, -4, -36, + 1, -53, 52, -17, -45, -6, + -22, 20, -19, 21, -12, -3, + -18, 38, -43, -24, -32, 48, + 47, 17, -25, -4, 22, 9, + -25, 15, -7, -22, -33, 20, + 19, 37, 36, 42, 39, -20, + 28, 25, -5, -5, 20, 42, + 30, -15, 1, -19, 33, -48, + -4, 24, -38, -18, -30, 44, + 14, 42, 3, 44, -85, 25, + 33, 27, -16, -7, 14, -48, + 35, -12, 1, 18, -37, -82, + 4, 24, -52, -57, 21, -2, + -37, -51, 23, 35, 60, 2, + 19, 32, -23, 3, 54, 7, + -49, 26, -37, 39, 48, 19, + 29, -3, 5, -22, 6, 26, + -5, -11, 13, -16, -38, 38, + -23, 55, -4, 30, -12, 59, + -26, -25, 27, -21, 4, -18, + -24, -17, -41, -56, 39, 22, + -1, -6, -38, -18, -3, 25, + -66, 52, 3, 29, -17, -2, + -36, -23, -8, 20, 21, -41, + -22, -15, 31, -6, 11, 26, + -1, 36, -29, -4, -11, 12, + 47, -8, -5, 0, 35, 8, + -13, -3, -47, -15, 14, -38, + 40, 34, -55, -38, -51, -17, + -13, 9, -33, -10, 9, 56, + 12, 4, 12, -1, -11, 3, + 55, 31, -5, 36, -14, -26, + -4, 10, -12, 8, 5, -70, + 37, -31, -55, -17, -26, -45, + -5, -13, -1, 27, 42, 31, + -5, -39, -57, -22, 14, 9, + 4, -20, -29, 31, -45, 16, + 4, 38, 27, -39, 5, 23, + 36, 39, 36, 51, -3, -4, + -19, -44, -9, -53, -14, 46, + -46, 5, 4, -24, 13, -21, + 2, 40, -26, 31, 21, 41, + -13, 9, -39, -33, -4, -22, + 10, 18, 0, 16, 42, 20, + -8, 12, -18, 11, 8, -30, + -22, 35, -29, 8, 47, -29, + -36, 2, -10, -57, -21, 23, + 9, -91, -49, 6, 14, 3, + 50, -59, -56, -3, 4, -4, + -71, -10, -55, 13, 28, -37, + -6, -50, 17, 4, 52, 7, + -53, 19, 33, -19, 12, -8, + -52, 30, -8, -5, 53, -3, + -13, 10, 2, -25, -14, -43, + 35, -22, 5, 68, -8, -8, + 3, 46, -2, -16, -5, 40, + -14, -28, 6, 65, -22, -5, + -9, -13, -27, 11, 16, -39, + 28, 24, 54, 37, -31, 39, + -15, 68, -3, -42, 8, 40, + 11, -3, -47, 33, -19, 24, + -6, -6, -9, -61, 55, 9, + 24, 11, -35, 19, -1, 5, + 63, -10, -24, -6, -8, -12, + 20, 17, 0, 31, -34, -3, + 32, 66, -38, 0, 7, 32, + 11, 0, 2, -8, -22, -46, + 11, -3, -25, -36, -2, 41, + -19, -17, -29, 30, -1, 70, + 25, 16, -25, -15, 12, 18, + -13, 20, 13, -44, -42, -21, + 4, -39, 32, 21, 60, -11, + -31, 10, -9, 1, 19, -45, + -4, -16, -21, 26, 35, 11, + 18, 38, 1, 6, 51, 13, + -70, 7, 55, 35, -10, -13, + -14, -56, -12, 26, 18, 51, + -24, 4, -35, 16, -1, -45, + 40, 48, 50, 15, 1, -19, + 1, -21, 67, -46, -20, -8, + -7, -2, -24, 16, -39, -1, + 26, 72, 3, -16, -3, 14, + 28, 9, -40, 34, -3, 18, + -8, -41, -51, 45, 28, -37, + 4, 24, 21, -38, 90, -29, + 9, 9, 47, -10, 35, -1, + -30, -11, 11, 38, -24, 10, + -40, 43, -3, -52, 23, 3, + -9, 14, 1, 20, 44, 13, + -35, -9, 36, -39, 37, 4, + 20, -18, 42, 39, -19, 20, + 26, -3, 38, -11, 20, -2, + 29, -60, -22, -23, 37, -30, + 44, -23, 7, -30, 39, -14, + -18, -26, 13, 23, -40, -45, + 3, -2, -14, 35, -10, -33, + 3, -40, -42, -38, 3, -5, + 18, -44, -36, 24, 40, 33, + 37, 18, -13, 19, -5, -13, + -7, -8, -1, -41, -18, -14, + -46, -49, 22, 8, -1, -14, + 0, 40, -15, 65, -35, -29, + 14, 25, -19, 13, -27, -12, + -37, -42, 4, -14, -58, 0, + 62, -16, 26, 19, -29, 23, + -17, 24, -61, 30, 24, 9, + -52, 9, 24, 30, -61, 24, + -17, 23, -29, 19, 26, -16, + 62, 0, -58, -14, 4, -42, + -37, -12, -27, 13, -19, 25, + 14, -29, -35, 65, -15, 40, + 0, -14, -1, 8, 22, -49, + -46, -14, -18, -41, -1, -8, + -7, -13, -5, 19, -13, 18, + 37, 33, 40, 24, -36, -44, + 18, -5, 3, -38, -42, -40, + 3, -33, -10, 35, -14, -2, + 3, -45, -40, 23, 13, -26, + -18, -14, 39, -30, 7, -23, + 44, -30, 37, -23, -22, -60, + 29, -2, 20, -11, 38, -3, + 26, 20, -19, 39, 42, -18, + 20, 4, 37, -39, 36, -9, + -35, 13, 44, 20, 1, 14, + -9, 3, 23, -52, -3, 43, + -40, 10, -24, 38, 11, -11, + -30, -1, 35, -10, 47, 9, + 9, -29, 90, -38, 21, 24, + 4, -37, 28, 45, -51, -41, + -8, 18, -3, 34, -40, 9, + 28, 14, -3, -16, 3, 72, + 26, -1, -39, 16, -24, -2, + -7, -8, -20, -46, 67, -21, + 1, -19, 1, 15, 50, 48, + 40, -45, -1, 16, -35, 4, + -24, 51, 18, 26, -12, -56, + -14, -13, -10, 35, 55, 7, + -70, 13, 51, 6, 1, 38, + 18, 11, 35, 26, -21, -16, + -4, -45, 19, 1, -9, 10, + -31, -11, 60, 21, 32, -39, + 4, -21, -42, -44, 13, 20, + -13, 18, 12, -15, -25, 16, + 25, 70, -1, 30, -29, -17, + -19, 41, -2, -36, -25, -3, + 11, -46, -22, -8, 2, 0, + 11, 32, 7, 0, -38, 66, + 32, -3, -34, 31, 0, 17, + 20, -12, -8, -6, -24, -10, + 63, 5, -1, 19, -35, 11, + 24, 9, 55, -61, -9, -6, + -6, 24, -19, 33, -47, -3, + 11, 40, 8, -42, -3, 68, + -15, 39, -31, 37, 54, 24, + 28, -39, 16, 11, -27, -13, + -9, -5, -22, 65, 6, -28, + -14, 40, -5, -16, -2, 46, + 3, -8, -8, 68, 5, -22, + 35, -43, -14, -25, 2, 10, + -13, -3, 53, -5, -8, 30, + -52, -8, 12, -19, 33, 19, + -53, 7, 52, 4, 17, -50, + -6, -37, 28, 13, -55, -10, + -71, -4, 4, -3, -56, -59, + 50, 3, 14, 6, -49, -91, + 9, 23, -21, -57, -10, 2, + -36, -29, 47, 8, -29, 35, + -22, -30, 8, 11, -18, 12, + -8, 20, 42, 16, 0, 18, + 10, -22, -4, -33, -39, 9, + -13, 41, 21, 31, -26, 40, + 2, -21, 13, -24, 4, 5, + -46, 46, -14, -53, -9, -44, + -19, -4, -3, 51, 36, 39, + 36, 23, 5, -39, 27, 38, + 4, 16, -45, 31, -29, -20, + 4, 9, 14, -22, -57, -39, + -5, 31, 42, 27, -1, -13, + -5, -45, -26, -17, -55, -31, + 37, -70, 5, 8, -12, 10, + -4, -26, -14, 36, -5, 31, + 55, 3, -11, -1, 12, 4, + 12, 56, 9, -10, -33, 9, + -13, -17, -51, -38, -55, 34, + 40, -38, 14, -15, -47, -3, + -13, 8, 35, 0, -5, -8, + 47, 12, -11, -4, -29, 36, + -1, 26, 11, -6, 31, -15, + -22, -41, 21, 20, -8, -23, + -36, -2, -17, 29, 3, 52, + -66, 25, -3, -18, -38, -6, + -1, 22, 39, -56, -41, -17, + -24, -18, 4, -21, 27, -25, + -26, 59, -12, 30, -4, 55, + -23, 38, -38, -16, 13, -11, + -5, 26, 6, -22, 5, -3, + 29, 19, 48, 39, -37, 26, + -49, 7, 54, 3, -23, 32, + 19, 2, 60, 35, 23, -51, + -37, -2, 21, -57, -52, 24, + 4, -82, -37, 18, 1, -12, + 35, -48, 14, -7, -16, 27, + 33, 25, -85, 44, 3, 42, + 14, 44, -30, -18, -38, 24, + -4, -48, 33, -19, 1, -15, + 30, 42, 20, -5, -5, 25, + 28, -20, 39, 42, 36, 37, + 19, 20, -33, -22, -7, 15, + -25, 9, 22, -4, -25, 17, + 47, 48, -32, -24, -43, 38, + -18, -3, -12, 21, -19, 20, + -22, -6, -45, -17, 52, -53, + 1, -36, -4, 22, -39, -57, + -36, -4, -4, -26, -24, -14, + -84, -51, 42, -16, -1, 27, + 30, -29, 28, -18, 0, 5, + -5, -40, 30, 10, -1, 17, + -27, -11, 22, 52, -22, -4, + 21, 10, -39, 8, -6, 28, + 14, -25, -28, -27, -32, 23, + 49, 8, 28, -6, -29, 36, + -36, -11, -25, -29, -10, -11, + -29, -15, -19, 49, -53, -1, + 29, -14, 8, -9, 15, -7, + 46, -30, 15, 43, 46, -4, + 16, 3, -7, 43, -64, -15, + -13, 36, -6, 25, -37, -43, + -9, 9, -18, 12, -189, 42760, + -930416, 7128059, -27128397, 59164075, -78882771, 65657099, + -33641357, 10045551, -1546050, 92278, -848, 92, + -13, -16, 19, -10, 58, -13, + -7, -15, 1, -13, 12, -44, + -77, -63, 32, -15, -82, 30, + -34, 47, 8, -16, -4, 4, +}; + +static const int32_t fft_ref_imag_1536_q31[1536] = { + 0, -51, -47, -1, -37, 43, + 28, -75, -11, -5, 22, -19, + 34, 22, -2, 47, 5, -17, + -59, 34, 2, -3, -6, 15, + -23, -10, -2528, 286363, -4833320, 31628670, + -106676515, 209692355, -253750691, 191701755, -88543033, 23436068, + -3081512, 142772, -625, 11, 6, -13, + 4, -7, -42, 19, -6, -5, + 11, -28, 39, -47, 29, 60, + 39, -3, -48, 25, -47, 5, + -27, 14, -37, 42, 54, 24, + -11, -60, -22, -14, 51, -36, + 53, -48, -50, -5, -52, -23, + -18, -23, -16, -22, 23, 34, + 33, -6, -11, -62, -45, 11, + 19, -2, -39, -18, 20, 4, + 2, 24, 24, 13, -9, -2, + -4, 32, -2, 10, 15, 6, + -29, -7, 45, -29, 18, 26, + 1, -19, -20, 0, 32, 16, + -1, 32, 72, -48, -27, -4, + 69, 22, -7, 6, 22, 56, + -14, 32, -34, -39, 31, -18, + 30, 19, -4, 71, 10, 28, + -23, 22, 13, 12, -2, 21, + 38, -33, 1, -37, -32, 19, + 13, 23, -43, 10, 7, -28, + 65, 25, 4, -24, 13, 17, + 0, -23, 14, 13, -18, -16, + 21, -47, 19, -20, 15, 1, + -50, -2, -21, -33, 9, 44, + 25, 28, 20, -31, 13, 4, + -4, 83, -1, 46, 10, 16, + -14, 17, 16, 15, 32, 24, + -11, -44, 45, -68, 36, -32, + 66, 23, 12, 42, -12, -6, + 50, -68, -14, -46, -36, -9, + 71, -41, -28, -33, 5, -61, + -10, 54, 0, 40, 0, 17, + 3, 4, 6, -20, 6, -7, + 1, -17, 3, -26, -29, 23, + -4, 17, -15, 8, 6, 8, + -23, -20, -3, 38, 13, -32, + 18, -3, -45, -47, -44, -26, + -29, 23, 28, -3, 58, -40, + 53, -9, 5, 35, 8, -1, + -25, 36, -6, -56, -1, 35, + -3, -7, -23, -12, 31, -51, + 5, 77, -38, -42, 49, -1, + -23, -3, 8, 0, 2, 11, + 27, -35, 8, 58, -46, -27, + 14, -10, -15, -45, -16, 2, + 20, 8, 10, 9, 29, -30, + -15, 68, -8, 16, -63, -23, + -5, -37, 7, -31, -25, 44, + -17, -34, 14, 10, 7, 16, + 18, 26, 44, 12, -13, 4, + 25, 6, 29, -47, 24, 8, + -14, 6, 21, -39, -2, -73, + -11, -7, -7, -14, -34, 11, + 74, 43, 17, -28, 18, -49, + 27, 3, -7, -13, 39, 20, + -39, 9, -10, 38, -15, -14, + 3, -43, 12, -31, 18, 44, + -24, -22, -52, -26, 15, -20, + -52, -28, 10, -18, -13, -17, + -16, -77, 16, -59, -102, 15, + 31, -75, -24, 42, 9, 19, + -3, 10, 4, 4, -25, 33, + 18, 22, 2, 34, -32, -18, + -1, 12, -3, -12, -6, 20, + -63, 3, -4, 18, 46, 40, + -15, -30, -4, 26, -31, -1, + -15, 19, -49, -11, 20, 1, + 2, 37, 54, 13, -2, -7, + -19, 9, -5, 4, 101, -42, + -45, 17, 14, -35, -56, 30, + -19, 86, -10, -46, -50, -7, + -22, -6, 0, -15, -6, 9, + -46, 54, -14, -7, 2, 27, + -54, 74, 29, 58, -39, 2, + -78, -8, -65, 47, 17, -40, + -15, 6, 3, 13, 7, -26, + -65, -26, -37, 18, -34, -10, + 11, -44, 3, 4, -28, -16, + 8, -88, -3, 8, 27, 18, + -9, 60, 30, 45, -53, -1, + -11, -1, 31, -4, 18, -5, + -13, -5, 9, -40, 22, 6, + -20, 23, 6, 32, -13, 25, + -5, 25, 12, 29, 8, -5, + -53, 45, 7, -24, -3, -12, + 3, 31, -1, -43, -9, -47, + -14, -38, -34, 57, 22, 45, + -20, -5, -30, -18, -17, -2, + 43, -28, 2, 59, -80, -5, + -16, -51, 39, -21, -21, 24, + 47, -29, 15, -22, 71, 77, + -34, 38, -9, -24, 23, -2, + 17, 33, -23, 52, 2, -25, + -55, -2, -34, 64, 59, 1, + 17, 11, 17, 11, -41, -15, + 13, 9, 32, 21, 17, 30, + -32, -49, 10, 11, 31, -1, + -48, 41, 28, -42, -47, 6, + -6, 2, -71, -44, -27, 51, + -3, 38, -66, -36, 34, -41, + 43, 38, 15, 32, -29, 11, + 3, -20, 23, 20, -54, -10, + 6, 7, -4, -12, 26, -14, + 22, 45, -5, 64, 22, -6, + -41, -30, -14, -8, -100, -26, + 28, 57, -5, -9, 42, -20, + 39, 9, 18, 14, 52, 6, + 2, 7, -93, -29, -15, -20, + 25, 18, 2, -20, -7, 15, + 67, -29, -20, -43, 3, 38, + 16, -32, 20, 43, -2, 41, + 16, -3, -8, -21, 1, -12, + 25, 1, 63, 12, -43, -2, + -23, 8, -7, -14, 24, 24, + 32, -19, 33, 13, -9, 1, + 24, 37, -24, 9, -46, -19, + 38, 71, 32, -26, 5, -66, + -5, 8, -5, 13, -43, -24, + -24, -26, 5, -28, 26, 0, + -20, -20, 2, -14, 60, -8, + -57, -34, 13, 12, 14, -1, + 0, 1, -14, -12, -13, 34, + 57, 8, -60, 14, -2, 20, + 20, 0, -26, 28, -5, 26, + 24, 24, 43, -13, 5, -8, + 5, 66, -5, 26, -32, -71, + -38, 19, 46, -9, 24, -37, + -24, -1, 9, -13, -33, 19, + -32, -24, -24, 14, 7, -8, + 23, 2, 43, -12, -63, -1, + -25, 12, -1, 21, 8, 3, + -16, -41, 2, -43, -20, 32, + -16, -38, -3, 43, 20, 29, + -67, -15, 7, 20, -2, -18, + -25, 20, 15, 29, 93, -7, + -2, -6, -52, -14, -18, -9, + -39, 20, -42, 9, 5, -57, + -28, 26, 100, 8, 14, 30, + 41, 6, -22, -64, 5, -45, + -22, 14, -26, 12, 4, -7, + -6, 10, 54, -20, -23, 20, + -3, -11, 29, -32, -15, -38, + -43, 41, -34, 36, 66, -38, + 3, -51, 27, 44, 71, -2, + 6, -6, 47, 42, -28, -41, + 48, 1, -31, -11, -10, 49, + 32, -30, -17, -21, -32, -9, + -13, 15, 41, -11, -17, -11, + -17, -1, -59, -64, 34, 2, + 55, 25, -2, -52, 23, -33, + -17, 2, -23, 24, 9, -38, + 34, -77, -71, 22, -15, 29, + -47, -24, 21, 21, -39, 51, + 16, 5, 80, -59, -2, 28, + -43, 2, 17, 18, 30, 5, + 20, -45, -22, -57, 34, 38, + 14, 47, 9, 43, 1, -31, + -3, 12, 3, 24, -7, -45, + 53, 5, -8, -29, -12, -25, + 5, -25, 13, -32, -6, -23, + 20, -6, -22, 40, -9, 5, + 13, 5, -18, 4, -31, 1, + 11, 1, 53, -45, -30, -60, + 9, -18, -27, -8, 3, 88, + -8, 16, 28, -4, -3, 44, + -11, 10, 34, -18, 37, 26, + 65, 26, -7, -13, -3, -6, + 15, 40, -17, -47, 65, 8, + 78, -2, 39, -58, -29, -74, + 54, -27, -2, 7, 14, -54, + 46, -9, 6, 15, 0, 6, + 22, 7, 50, 46, 10, -86, + 19, -30, 56, 35, -14, -17, + 45, 42, -101, -4, 5, -9, + 19, 7, 2, -13, -54, -37, + -2, -1, -20, 11, 49, -19, + 15, 1, 31, -26, 4, 30, + 15, -40, -46, -18, 4, -3, + 63, -20, 6, 12, 3, -12, + 1, 18, 32, -34, -2, -22, + -18, -33, 25, -4, -4, -10, + 3, -19, -9, -42, 24, 75, + -31, -15, 102, 59, -16, 77, + 16, 17, 13, 18, -10, 28, + 52, 20, -15, 26, 52, 22, + 24, -44, -18, 31, -12, 43, + -3, 14, 15, -38, 10, -9, + 39, -20, -39, 13, 7, -3, + -27, 49, -18, 28, -17, -43, + -74, -11, 34, 14, 7, 7, + 11, 73, 2, 39, -21, -6, + 14, -8, -24, 47, -29, -6, + -25, -4, 13, -12, -44, -26, + -18, -16, -7, -10, -14, 34, + 17, -44, 25, 31, -7, 37, + 5, 23, 63, -16, 8, -68, + 15, 30, -29, -9, -10, -8, + -20, -2, 16, 45, 15, 10, + -14, 27, 46, -58, -8, 35, + -27, -11, -2, 0, -8, 3, + 23, 1, -49, 42, 38, -77, + -5, 51, -31, 12, 23, 7, + 3, -35, 1, 56, 6, -36, + 25, 1, -8, -35, -5, 9, + -53, 40, -58, 3, -28, -23, + 29, 26, 44, 47, 45, 3, + -18, 32, -13, -38, 3, 20, + 23, -8, -6, -8, 15, -17, + 4, -23, 29, 26, -3, 17, + -1, 7, -6, 20, -6, -4, + -3, -17, 0, -40, 0, -54, + 10, 61, -5, 33, 28, 41, + -71, 9, 36, 46, 14, 68, + -50, 6, 12, -42, -12, -23, + -66, 32, -36, 68, -45, 44, + 11, -24, -32, -15, -16, -17, + 14, -16, -10, -46, 1, -83, + 4, -4, -13, 31, -20, -28, + -25, -44, -9, 33, 21, 2, + 50, -1, -15, 20, -19, 47, + -21, 16, 18, -13, -14, 23, + 0, -17, -13, 24, -4, -25, + -65, 28, -7, -10, 43, -23, + -13, -19, 32, 37, -1, 33, + -38, -21, 2, -12, -13, -22, + 23, -28, -10, -71, 4, -19, + -30, 18, -31, 39, 34, -32, + 14, -56, -22, -6, 7, -22, + -69, 4, 27, 48, -72, -32, + 1, -16, -32, 0, 20, 19, + -1, -26, -18, 29, -45, 7, + 29, -6, -15, -10, 2, -32, + 4, 2, 9, -13, -24, -24, + -2, -4, -20, 18, 39, 2, + -19, -11, 45, 62, 11, 6, + -33, -34, -23, 22, 16, 23, + 18, 23, 52, 5, 50, 48, + -53, 36, -51, 14, 22, 60, + 11, -24, -54, -42, 37, -14, + 27, -5, 47, -25, 48, 3, + -39, -60, -29, 47, -39, 28, + -11, 5, 6, -19, 42, 7, + -4, 13, -6, -11, 625, -142772, + 3081512, -23436068, 88543033, -191701755, 253750691, -209692355, + 106676515, -31628670, 4833320, -286363, 2528, 10, + 23, -15, 6, 3, -2, -34, + 59, 17, -5, -47, 2, -22, + -34, 19, -22, 5, 11, 75, + -28, -43, 37, 1, 47, 51, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi_3072_32.h b/test/cmocka/src/math/fft/ref_fft_multi_3072_32.h new file mode 100644 index 000000000000..25e70400ccf6 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_3072_32.h @@ -0,0 +1,2068 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_3072_NUM_TESTS 1 + +static const int32_t fft_in_real_3072_q31[3072] = { + 372, -3573, -1008, 217, -780, 436, + -1549, -852, -2495, 1920, -990, 2031, + -1837, -1265, 107, -2253, 2173, -458, + 3792, -194, 423, 799, 701, 1111, + -2804, -608, 1177, -1518, 168, 1765, + 705, -254, -3040, 1816, -2288, -285, + -1613, -1936, 688, -3208, -4065, -349, + -966, -1253, -1, 817, 111, -3848, + 205, 1017, -2528, 2877, 174, -1019, + 2896, 307, 1621, 520, 3704, 931, + 823, 2510, 3310, 1172, 4812, 931, + 1606, 2074, 2256, -1087, 2452, 758, + 589, 2385, 1960, -2318, -2127, -4529, + -4734, 105, -4991, -7191, -4860, -5616, + -2791, -5424, -4297, -5662, -8319, -6945, + -5017, -2177, -4699, -1601, 604, -43, + 1878, 3462, 1152, 1164, 2308, 5171, + 8093, 6337, 9436, 9868, 12643, 11458, + 11732, 12804, 8785, 10229, 11049, 12522, + 10680, 5304, 6307, 3106, 6523, 1343, + 258, -3209, -4227, -5295, -7664, -10933, + -9853, -13973, -18784, -16492, -20604, -22894, + -19663, -21716, -19330, -19486, -20742, -19535, + -16630, -15494, -14231, -10701, -8950, -5354, + -2341, 157, 6564, 11704, 18055, 14585, + 21646, 28327, 29665, 32553, 35738, 35431, + 38650, 39954, 38001, 43701, 38676, 35777, + 37697, 30835, 28715, 23077, 16120, 10116, + 1842, -2231, -12878, -19231, -23871, -33268, + -39644, -46730, -52379, -58782, -59834, -67902, + -68580, -70729, -72311, -70437, -71116, -65100, + -62389, -52520, -45857, -39326, -26646, -17904, + -5812, 7728, 15285, 31013, 43597, 56440, + 68135, 76812, 89464, 101782, 109968, 113335, + 121569, 117890, 122090, 118167, 117262, 109348, + 104021, 95523, 81365, 63317, 50309, 32668, + 13461, -7822, -28259, -51658, -72664, -91775, + -115036, -131884, -148209, -161626, -176665, -186642, + -198422, -201251, -204468, -199154, -194769, -184574, + -170630, -155814, -133647, -111067, -82874, -53815, + -23251, 8690, 45733, 77325, 109576, 147709, + 178113, 208648, 234279, 261877, 284629, 296896, + 312298, 317591, 320982, 318739, 305377, 291686, + 270019, 245901, 215298, 175604, 137830, 90294, + 41554, -10071, -62629, -117838, -169306, -223248, + -270854, -323501, -368270, -403786, -438021, -462004, + -483065, -495690, -501584, -494599, -479802, -453999, + -421113, -384132, -333536, -274847, -214043, -141020, + -68871, 9322, 93150, 174657, 257553, 338309, + 414683, 487699, 555110, 613887, 662617, 705407, + 734778, 750029, 756904, 750785, 728812, 693681, + 641368, 582598, 505227, 422816, 325847, 224093, + 111558, -5393, -128174, -253153, -371497, -497447, + -611885, -720876, -818284, -911629, -982314, -1042069, + -1089267, -1113410, -1121889, -1111498, -1080988, -1028361, + -955932, -867286, -759764, -631297, -494221, -341335, + -174492, -1266, 175797, 353877, 535388, 712596, + 885107, 1043835, 1190169, 1319079, 1429815, 1519748, + 1579473, 1619092, 1633179, 1618264, 1574576, 1499577, + 1397206, 1267140, 1106626, 928445, 727130, 507505, + 271402, 21420, -236596, -495465, -757620, -1006830, + -1249141, -1479683, -1690633, -1879331, -2034859, -2165655, + -2256619, -2315157, -2332427, -2310891, -2246487, -2143264, + -1999884, -1816213, -1596280, -1342502, -1052822, -742495, + -407978, -57316, 304579, 672838, 1038655, 1398459, + 1742918, 2065247, 2365675, 2631021, 2853345, 3036470, + 3167820, 3249898, 3281470, 3252625, 3164310, 3019310, + 2822626, 2564728, 2259683, 1900120, 1508700, 1070684, + 603408, 110951, -392666, -903614, -1414802, -1912902, + -2392206, -2845130, -3258570, -3627149, -3940690, -4191313, + -4381803, -4499619, -4541815, -4504007, -4388011, -4192289, + -3919064, -3569292, -3147477, -2658923, -2113464, -1518547, + -874826, -209524, 487728, 1191134, 1892304, 2573893, + 3234254, 3855470, 4423871, 4927377, 5359814, 5713992, + 5972621, 6140505, 6199387, 6153667, 5998277, 5738563, + 5368890, 4896998, 4329184, 3671418, 2930085, 2121158, + 1254388, 347574, -591983, -1544910, -2490043, -3420032, + -4315360, -5152121, -5921191, -6611696, -7199706, -7679390, + -8034751, -8257121, -8346135, -8290828, -8093048, -7744783, + -7254418, -6630540, -5870181, -4992728, -4006965, -2925017, + -1770290, -553992, 701532, 1972732, 3243885, 4485736, + 5676566, 6798847, 7830355, 8753293, 9542274, 10185538, + 10668092, 10977869, 11100656, 11039240, 10778861, 10326862, + 9684417, 8861605, 7863637, 6708489, 5407284, 3980889, + 2454492, 851943, -806049, -2488656, -4160522, -5801884, + -7381535, -8865301, -10234725, -11457830, -12501687, -13359571, + -14004580, -14421804, -14594932, -14515706, -14190718, -13607659, + -12780027, -11711622, -10410644, -8902247, -7209085, -5351692, + -3360190, -1266353, 892180, 3085982, 5277651, 7423286, + 9487880, 11431794, 13220058, 14818486, 16199378, 17322667, + 18173106, 18731015, 18968208, 18891463, 18480248, 17738440, + 16674383, 15296941, 13630301, 11690888, 9508065, 7111137, + 4541597, 1838855, -953433, -3788691, -6620413, -9392119, + -12060485, -14576464, -16894758, -18969314, -20757213, -22224208, + -23337383, -24068281, -24396675, -24314555, -23807617, -22876611, + -21528574, -19784004, -17663705, -15191458, -12403961, -9347173, + -6060577, -2608229, 959950, 4586727, 8204034, 11755744, + 15172504, 18397037, 21372442, 24033132, 26334534, 28221481, + 29661590, 30621139, 31064526, 30984600, 30361616, 29206481, + 27520780, 25328643, 22655207, 19532705, 16011679, 12149179, + 7998202, 3629080, -886601, -5477122, -10060474, -14562086, + -18899133, -22989928, -26765395, -30151720, -33079322, -35496765, + -37343077, -38580863, -39174876, -39103667, -38354970, -36935358, + -34846029, -32114319, -28772721, -24876871, -20476549, -15641187, + -10440364, -4966127, 700841, 6459485, 12215659, 17866676, + 23313028, 28458228, 33210198, 37478907, 41172064, 44232678, + 46576561, 48163284, 48945603, 48900048, 48012912, 46278450, + 43710721, 40344152, 36215687, 31392482, 25936258, 19939304, + 13485840, 6683808, -355573, -7517128, -14679416, -21710106, + -28499406, -34910051, -40834645, -46165701, -50790443, -54626140, + -57579532, -59598013, -60619069, -60618781, -59567039, -57473025, + -54351412, -50233342, -45186383, -39261858, -32564132, -25185248, + -17241901, -8866923, -191879, 8633665, 17460936, 26143204, + 34521609, 42447110, 49780242, 56379237, 62120194, 66881659, + 70575603, 73119678, 74443740, 74499636, 73282198, 70781179, + 67012890, 62026148, 55887344, 48687496, 40526263, 31529575, + 21836507, 11612109, 1012091, -9779981, -20582181, -31204035, + -41466004, -51182619, -60176524, -68284491, -75345078, -81225915, + -85799183, -88971434, -90663991, -90821930, -89419903, -86450743, + -81949463, -75956415, -68564796, -59875217, -50011014, -39129949, + -27400942, -15013360, -2168850, 10917793, 24023847, 36925822, + 49394121, 61211286, 72157333, 82036329, 90656560, 97852309, + 103475793, 107411172, 109549870, 109844745, 108245148, 104766008, + 99424144, 92289308, 83453912, 73051237, 61227750, 48165694, + 34079160, 19189890, 3741027, -12005929, -27789733, -43333372, + -58369825, -72626480, -85852717, -97799740, -108240568, -116984834, + -123841326, -128673829, -131365348, -131830251, -130042187, -125987529, + -119708342, -111271729, -100800507, -88439340, -74371460, -58820447, + -42024813, -24265428, -5823474, 12987814, 31851444, 50439832, + 68434255, 85515447, 101367399, 115712690, 128275627, 138809813, + 147111488, 153005021, 156352343, 157056501, 155072568, 150396562, + 143063101, 133170013, 120845814, 106268769, 89657765, 71271888, + 51399185, 30366381, 8513394, -13791446, -36175759, -58247278, + -79630509, -99940520, -118815593, -135911795, -150904974, -163518047, + -173494300, -180628604, -184757144, -185767143, -183596719, -178244443, + -169749533, -158227572, -143833336, -126769181, -107293920, -85709208, + -62364441, -37631290, -11919266, 14347827, 40716579, 66739386, + 91969993, 115952914, 138266858, 158500447, 176282916, 191272406, + 203177017, 211746908, 216794498, 218182573, 215846442, 209774794, + 200015892, 186692556, 169994049, 150152492, 127483522, 102323384, + 75084856, 46201855, 16153098, -14559068, -45419047, -75892600, + -105455486, -133589527, -159788255, -183572055, -204512930, -222207105, + -236312548, -246537938, -252661829, -254527285, -252044844, -245204000, + -234070892, -218777349, -199540150, -176640610, -150422459, -121292087, + -89721942, -56221556, -21340285, 14334216, 50205554, 85654350, + 120069924, 152846317, 183399211, 211180614, 235673463, 256424814, + 273019784, 285138036, 292514936, 294953678, 292364878, 284724191, + 272110317, 254679055, 232666741, 206401006, 176282044, 142782930, + 106435316, 67827972, 27606004, -13567407, -54989891, -95960432, + -135762579, -173703133, -209109185, -241342374, -269808493, -293980021, + -313386899, -327646179, -336453636, -339592042, -336942587, -328480069, + -314289983, -294549465, -269535128, -239608257, -205233219, -166948378, + -125366856, -81167440, -35076509, 12137668, 59676374, 106721077, + 152465978, 196107885, 236879838, 274040630, 306911433, 334892873, + 357441507, 374108431, 384553642, 388516901, 385863592, 376571435, + 360716345, 338509581, 310254184, 276376144, 237395341, 193917688, + 146647470, 96356984, 43868781, -9933526, -64145444, -117835189, + -170084338, -219972544, -266627410, -309204586, -346936289, -379122173, + -405155218, -424514827, -436810151, -441744679, -439162883, -429030505, + -411439631, -386617413, -354911037, -316798931, -272863878, -223795489, + -170394207, -113517117, -54112101, 6829649, 68271983, 129181249, + 188492354, 245177826, 298242279, 346730695, 389776661, 426578154, + 456438915, 478787617, 493156906, 499218782, 496797130, 485840086, + 466453824, 438883546, 403526720, 360909157, 311693565, 256651431, + 196672699, 132738813, 65908364, -2703538, -71935942, -140613095, + -207543775, -271573069, -331567032, -386461954, -435270224, -477095415, + -511150801, -536776982, -553457499, -560821589, -558658317, -546905800, + -525675660, -495251147, -456064122, -408695891, -353884464, -292507426, + -225550806, -154103971, -79358011, -2561945, 74990922, 151974456, + 227067781, 298963701, 366402727, 428187197, 483209074, 530460127, + 569065103, 598275256, 617513188, 626357580, 624559602, 612058838, + 588971043, 555592552, 512412748, 460076790, 399404508, 331355368, + 257033083, 177659157, 94542334, 9080697, -77291728, -163095921, + -246863323, -327129624, -402505892, -471643480, -533307653, -586384181, + -629887100, -662983451, -685030545, -695536926, -694237467, -681049278, + -656096022, -619710506, -572410016, -514922467, -448143694, -373128295, + -291109814, -203423941, -111523060, -16946439, 78702051, 173797563, + 266709385, 355818638, 439585563, 516517252, 585239763, 644525256, + 693261354, 730544741, 755634274, 768002388, 767333019, 753544351, + 726750519, 687313547, 635808270, 573021365, 499930935, 417715763, + 327699155, 231373047, 130330697, 26255704, -79077473, -183883762, + -286364208, -384749243, -477322091, -562450927, -638620614, -704458584, + -758759964, -800505747, -828885262, -843307676, -843428140, -829125298, + -800541387, -758052984, -702291149, -634095686, -554553702, -464934785, + -366695229, -261454617, -150966943, -37076378, 78289104, 193169085, + 305591559, 413616449, 515365690, 609043518, 692999321, 765716588, + 825874492, 872350263, 904253049, 920935675, 921993322, 907300938, + 876995158, 831492911, 771451746, 697804425, 611711609, 514553983, + 407924116, 293581677, 173416032, 49451086, -76220456, -201456944, + -324120836, -442096257, -553320447, -655855947, -747885861, -827768799, + -894049560, -945498889, -981150629, -1000271847, -1002432788, -987484122, + -955566735, -907106665, -842823854, -763720833, -671044190, -566294105, + -451177423, -327601471, -197612754, -63402956, 72760120, 208568511, + 341689943, 469838167, 590782890, 702408508, 802758269, 890034724, + 962657597, 1019303575, 1058896759, 1080652859, 1084088210, 1069029598, + 1035618264, 984312724, 915867520, 831363489, 732141019, 619797883, + 496179013, 363327875, 223462244, 78928184, -67831872, -214319471, + -358035612, -496500520, -627323350, -748214481, -857046183, -951889165, + -1031049603, -1093062609, -1136780159, -1161344249, -1166220616, -1151212846, + -1116462912, -1062447094, -989978191, -900185174, -794510265, -674662535, + -542611316, -400546431, -250829785, -95990652, 61366328, 218558108, + 372901738, 521744570, 662502854, 792737450, 910165194, 1012696160, + 1098503418, 1166031146, 1214025412, 1241556119, 1248038839, 1233252312, + 1197338095, 1140793802, 1064472412, 969574944, 857621750, 730435938, + 590107881, 438968868, 279545499, 114515179, -53332932, -221139123, + -386045481, -545210951, -695893623, -835474544, -961505113, -1071770327, + -1164307836, -1237438055, -1289820122, -1320452961, -1328709383, -1314332855, + -1277452999, -1218591232, -1138644358, -1038871318, -920887278, -786611045, + -638256294, -478293717, -309395514, -134403655, 43716046, 221948477, + 397235398, 566578363, 727061393, 875885710, 1010467343, 1128436049, + 1227704280, 1306480900, 1363339414, 1397194675, 1407372472, 1393581163, + 1355953850, 1295026075, 1211729278, 1107379980, 983679487, 842642384, + 686602223, 518156042, 340129235, 155518548, -32551931, -220890139, + -406278195, -585537160, -755583489, -913469206, -1056447718, -1182017615, + -1287952094, -1372373602, -1433740315, -1470904340, -1483138314, -1470125229, + -1431990546, -1369269446, -1282934208, -1174373193, -1045338593, -897949621, + -734659284, -558177505, -371469791, -177689875, 19897308, 217914039, + 413000387, 601804247, 781081356, 947739871, 1098873275, 1231848458, + 1344327873, 1434310884, 1500178253, 1540716776, 1555129431, 1543082456, + 1504676705, 1440471424, 1351471197, 1239098180, 1105185347, 951941327, + 781912112, 597936823, 403109189, 200711702, -5827201, -212996516, + -417263748, -615131936, -803202303, -978233490, -1137186723, -1277303294, + -1396118945, -1491537327, -1561856292, -1605781912, -1622476857, -1611576361, + -1573161776, -1507803264, -1416525319, -1300803759, -1162529626, -1003997711, + -827837307, -637004368, -434709124, -224359341, -9529003, 206138691, + 418964803, 625310311, 821624595, 1004540605, 1170892708, 1317790091, + 1442669662, 1543328211, 1617988707, 1665290217, 1684351248, 1674761398, + 1636600581, 1570429050, 1477314812, 1358748196, 1216694357, 1053500806, + 871896317, 674924682, 465908519, 248377622, 26015600, -197400277, + -418050818, -632173339, -836090410, -1026306638, -1199532255, -1352774350, + -1483362532, -1589011002, -1667857340, -1718486144, -1739962335, -1731840810, + -1694189001, -1627581900, -1533073579, -1412215425, -1266999164, -1099845212, + -913551939, -711244528, -496342110, -272477568, -43447743, 186853426, + 414497132, 635604535, 846382113, 1043217377, 1222716978, 1381788493, + 1517666640, 1627985742, 1710809548, 1764671488, 1788582982, 1782076477, + 1745200236, 1678510858, 1583099752, 1460517021, 1312810748, 1142441329, + 952273264, 745504463, 525629176, 296376863, 61629633, -174618632, + -408342794, -635547128, -852353972, -1055045659, -1240135324, -1404435561, + -1545115420, -1659730825, -1746277289, -1803232403, -1829574223, -1824802377, + -1788944079, -1722556598, -1626725028, -1503023090, -1353527120, -1180736052, + -987563716, -777264704, -553397694, -319761871, -80318116, 160854501, + 399645250, 631985939, 853909923, 1061611331, 1251535092, 1420412831, + 1565341387, 1683811150, 1773776008, 1833654782, 1862391453, 1859458840, + 1824851861, 1759129786, 1663371340, 1539171366, 1388613977, 1214226218, + 1018956327, 806101706, 579277790, 342327686, 99281607, -145729280, + -388524088, -624973189, -851026538, -1062835803, -1256769433, -1429499244, + -1578069680, -1699911201, -1792938289, -1855528096, -1886587771, -1885558778, + -1852429664, -1787734857, -1692550025, -1568466400, -1417586538, -1242447341, + -1046019000, -831624085, -602913005, -363765229, -118251153, 129457667, + 375134811, 614592317, 843748087, 1058698271, 1255758464, 1431568802, + 1583117023, 1707808398, 1803500889, 1868550498, 1901833106, 1902758600, + 1871299790, 1807979837, 1713850848, 1590514279, 1440046976, 1265017072, + 1068378419, 853480525, 623981978, 383772466, 136960898, -112268288, + -359659896, -601003283, -832179172, -1049261809, -1248533101, -1426603183, + -1580432180, -1707395953, -1805328349, -1872549473, -1907910206, -1910814775, + -1881202917, -1819574231, -1726982026, -1604991549, -1455688417, -1281609582, + -1085722448, -871357291, -642173873, -402075571, -155147588, 94400620, + 342321129, 584394446, 816488006, 1034659652, 1235193836, 1414674308, + 1570050564, 1698682278, 1798381561, 1867461880, 1904745928, 1909621460, + 1882002289, 1822370756, 1731752675, 1611705013, 1464279579, 1291998030, + 1097801079, 885007491, 657247751, 418407719, 172550487, -76118746, + -323372208, -565006313, -796894006, -1015107018, -1215927812, -1395948753, + -1552119395, -1681790895, -1782774050, -1853366552, -1892385206, -1899187777, + -1873679839, -1816317016, -1728099817, -1610555232, -1465702231, -1296030798, + -1104443064, -894224213, -668970217, -432524377, -188922860, 57680630, + 303083765, 543111971, 773679620, 990878213, 1191015166, 1370695312, + 1526895364, 1656961023, 1758718736, 1830458745, 1870990611, 1879657894, + 1856353863, 1801500924, 1716067064, 1601550638, 1459926812, 1293641207, + 1105551152, 898884149, 677182586, 444237696, 204031857, -39343627, + -281736298, -519024737, -747172550, -962310633, -1160791510, -1339271328, + -1494719175, -1624541086, -1726550849, -1799056437, -1840866215, -1851310975, + -1830256497, -1778117519, -1695817922, -1584815664, -1447032134, -1284862167, + -1101102449, -898911555, -681766646, -453381107, -217659996, 21366015, + 259627334, 493072531, 717731912, 929796840, 1125686578, 1302092995, + 1456042960, 1584965877, 1686703884, 1759582038, 1802411351, 1814517128, + 1795746957, 1746490037, 1667630110, 1560571974, 1427195337, 1269816814, + 1091157415, 894309346, 682655783, 459821541, 229631191, -3993204, + -237059049, -465606052, -685758770, -893780837, -1086166235, -1259671231, + -1411385009, -1538774911, -1639722862, -1712573317, -1756151511, -1769778723, + -1753291016, -1707044018, -1631880689, -1529156784, -1400686108, -1248703573, + -1075859349, -885148396, -679846603, -463496048, -239788111, -12560535, + 214318802, 436987939, 651666136, 854732389, 1042749336, 1212562328, + 1361331574, 1486573736, 1586227826, 1658651760, 1702702242, 1717695626, + 1703457825, 1660303465, 1589051490, 1490989763, 1367859974, 1221822045, + 1055420110, 871556095, 673397091, 464356944, 248014359, 28080829, + -191693218, -407572184, -615900079, -813149545, -995996567, -1161375920, + -1306531882, -1429044334, -1526907572, -1598523621, -1642761569, -1658943247, + -1646894744, -1606892066, -1539710329, -1446580159, -1329162799, -1189527590, + -1030127747, -853735167, -663407611, -462418808, -254229501, -42399820, + 169456638, 377724875, 578889840, 769552187, 946493762, 1106754813, + 1247677619, 1366914015, 1462520817, 1532951923, 1577094138, 1594286405, + 1584336159, 1547503054, 1484508014, 1396513358, 1285105867, 1152266026, + 1000323211, 831943670, 650031253, 457742924, 258379751, 55360097, + -147846433, -347791305, -541082791, -724454616, -894833732, -1049361614, + -1185484687, -1300948925, -1393867554, -1462752654, -1506521824, -1524533384, + -1516574802, -1482884630, -1424136518, -1341432851, -1236268049, -1110524433, + -966418198, -806474656, -633479500, -450427103, -260466143, -66854834, + 127098863, 318089721, 502893013, 678382955, 841619455, 989876004, + 1120697339, 1231931272, 1321770079, 1388772538, 1431906568, 1450534876, + 1444442644, 1413845056, 1359367791, 1282042512, 1183277772, 1064854075, + 928867553, 777701643, 614003268, 440609784, 260505083, 76790900, + -107401371, -288931568, -464730053, -631836635, -787442491, -928965186, + -1054051161, -1160657065, -1247066123, -1311885917, -1354123223, -1373168202, + -1368802284, -1341216760, -1290982804, -1219066595, -1126792942, -1015826842, + -888151193, -746007399, -591889851, -428465269, -258572080, -85121742, + 88920688, 260585671, 426981992, 585294900, 732878617, 867277717, + 986273316, 1087923620, 1170580702, 1232948145, 1274057596, 1293321664, + 1290530992, 1265838308, 1219781089, 1153257231, 1067495900, 964056608, + 844792140, 711809082, 567448255, 414212554, 254760785, 91832000, + -71785113, -233304073, -389994059, -539215391, -678473322, -805453139, + -918071312, -1014479841, -1093139146, -1152809828, -1192574868, -1211869926, + -1210493120, -1188564867, -1146588764, -1085378215, -1006085479, -910161450, + -799328092, -675557523, -541026496, -398078579, -249185492, -96927040, + 56100459, 207288881, 354080272, 494009592, 624733114, 744082407, + 850101449, 941069115, 1015518946, 1072290089, 1110517423, 1129670265, + 1129533115, 1110223700, 1072184544, 1016169922, 943250152, 854763597, + 752304762, 637705517, 512980046, 380314890, 242012700, 100457755, + -41929112, -182717458, -319523659, -450054681, -572124060, -683719153, + -783001820, -868369330, -938460454, -992171022, -1028698784, -1047540077, + -1048477478, -1031607491, -997345635, -946379405, -879674816, -798478560, + -704259631, -598699131, -483675841, -361200006, -233396979, -102482690, + 29303374, 159718607, 286551799, 407675562, 521064808, 624853955, + 717339406, 797022340, 862641000, 913174146, 947865519, 966232390, + 968081056, 953484359, 922809892, 876682824, 816002928, 741894612, + 655708808, 559003777, 453484070, 341012181, 223536838, 103102585, + -18231207, -138395994, -255358187, -367155417, -471922910, -567935035, + -653617482, -727595050, -788689017, -835957241, -868699728, -886469086, + -889064437, -876548172, -849255973, -807751705, -752850349, -685578717, + -607173529, -519046712, -422764499, -320025539, -212631771, -102431653, + 8679050, 118808590, 226088922, 328724742, 424998537, 513330924, + 592282938, 660578068, 717148585, 761116085, 791826700, 808868239, + 812060341, 801441718, 777312861, 740179100, 690781536, 630052357, + 559110226, 479237115, 391866261, 298532311, 200875179, 100588108, + -610935, -100984350, -198848126, -292555400, -380546365, -461371121, + -533714162, -596419791, -648495691, -689153805, -717786679, -734004557, + -737643044, -728735072, -707539194, -674510633, -630315927, -575794155, + -511962755, -439967668, -361115320, -276796807, -188485656, -97721711, + -6063325, 84929152, 173707386, 258789883, 338754416, 412300822, + 478218897, 535461035, 583136381, 620504801, 647030016, 662347093, + 666298302, 658915851, 640421042, 611217389, 571909299, 523236434, + 466118540, 401593676, 330829977, 255074713, 175659977, 93973455, + 11414720, -70601436, -150685191, -227503101, -299773173, -366307069, + -426034100, -477991736, -521372745, -555521252, -579940444, -594295661, + -598442639, -592398963, -576367295, -550703332, -515942267, -472744367, + -421927480, -364422131, -301274182, -233603649, -162596392, -89494303, + -15558951, 57945069, 129779304, 198738559, 263672984, 323523850, + 377322092, 424207594, 463456672, 494471834, 516803451, 530158177, + 534393266, 529522630, 515724338, 493304606, 462743275, 424626320, + 379680922, 328730698, 272703820, 212598528, 149477147, 84438014, + 18611869, -46890812, -110948255, -172487905, -230496546, -284018556, + -332192437, -374254634, -409548650, -437541760, -457837031, -470164722, + -474394574, -470538855, -458739378, -439284058, -412572405, -379141514, + -339620640, -294741156, -245331348, -192260455, -136472440, -78951410, + -20681431, 37338334, 94122301, 148721185, 200232600, 247810779, + 290690901, 328188337, 359735133, 384848064, 403172538, 414463652, + 418610740, 415613591, 405605607, 388825120, 365626134, 336479343, + 301938434, 262645580, 219323579, 172743491, 123741607, 73166108, + 21901695, -29183784, -79217342, -127361553, -172827260, -214863245, + -252797135, -286027063, -314046252, -336431187, -352861785, -363131190, + -367130392, -364860806, -356427781, -342050458, -322027327, -296771219, + -266766470, -232577223, -194827396, -154198752, -111414668, -67220706, + -22389838, 22307679, 66124103, 108321476, 148198106, 185107523, + 218456075, 247717969, 272443667, 292266337, 306907078, 316173250, + 319972907, 318303699, 311259083, 299016458, 281848796, 260101048, + 234203589, 204633082, 171949718, 136725579, 99604730, 61231692, + 22273999, -16596878, -54722051, -91473029, -126228497, -158429158, + -187562194, -213164905, -234846275, -252286330, -265238700, -273536116, + -277094400, -275914375, -270072015, -259723698, -245095661, -226492133, + -204280400, -178876569, -150746899, -120409997, -88411434, -55305328, + -21667576, 11918194, 44883235, 76677980, 106780616, 134691029, + 159972434, 182226557, 201111853, 216348627, 227724715, 235098889, + 238395584, 237611210, 232806177, 224118037, 211737832, 195926515, + 176998172, 155309580, 131268918, 105312714, 77901800, 49526741, + 20677629, -8152943, -36463737, -63797045, -89689774, -113724824, + -135517472, -154731255, -171066319, -184289182, -194215635, -200718014, + -203729844, -203249948, -199333372, -192088472, -181686292, -168339828, + -152317100, -133929642, -113514481, -91450898, -68133602, -43973447, + -19397877, 5181202, 29338391, 52668207, 74790435, 95343031, + 114004002, 130473256, 144509701, 155902177, 164494452, 170183422, + 172913199, 172664116, 169497118, 163505317, 154823158, 143635522, + 130168501, 114678360, 97469233, 78842181, 59141556, 38714750, + 17918761, -2890580, -23352359, -43134629, -61902442, -79359178, + -95219793, -109241655, -121213199, -130959126, -138341127, -143279885, + -145714907, -145650458, -143112905, -138187337, -130992820, -121679590, + -110437544, -97489588, -83076189, -67465699, -50939873, -33792500, + -16322159, 1168621, 18385872, 35036145, 50842116, 65557638, + 78945236, 90795089, 100928151, 109206567, 115506792, 119754384, + 121907623, 121965051, 119953463, 115936809, 110018616, 102324285, + 93009785, 82258499, 70282778, 57293087, 43527865, 29239498, + 14664699, 70861, -14299001, -28213778, -41434394, -53740906, + -64954354, -74898839, -83413372, -90382889, -95713352, -99339509, + -101224772, -101365811, -99785822, -96538276, -91706578, -85398224, + -77737953, -68883543, -59001121, -48272419, -36897641, -25072795, + -13015236, -928046, 10981346, 22514261, 33483859, 43710738, + 53031141, 61298934, 68403208, 74226528, 78703859, 81766293, + 83402166, 83593718, 82365139, 79763031, 75844981, 70710156, + 64464541, 57223854, 49132714, 40341451, 31011508, 21310849, + 11407368, 1476260, -8314581, -17806980, -26836240, -35256930, + -42939854, -49774817, -55645608, -60473208, -64195712, -66770589, + -68169750, -68386355, -67439994, -65369396, -62224639, -58081970, + -53024988, -47151459, -40577074, -33432655, -25843582, -17943272, + -9879653, -1786795, 6204057, 13943017, 21315103, 28198305, + 34483247, 40076675, 44890339, 48859763, 51930920, 54068789, + 55255655, 55479959, 54760676, 53131015, 50625910, 47308295, + 43244014, 38521353, 33230411, 27468337, 21346443, 14969441, + 8451097, 1911594, -4546380, -10811070, -16777372, -22352502, + -27448560, -31988943, -35903458, -39138144, -41648387, -43410944, + -44400727, -44621343, -44081728, -42808165, -40830393, -38198108, + -34962490, -31195794, -26971588, -22366339, -17469059, -12364939, + -7146798, -1904260, 3270688, 8291813, 13081852, 17556488, + 21651104, 25302659, 28458917, 31067904, 33104793, 34537546, + 35361975, 35568405, 35171243, 34183205, 32633364, 30558842, + 28008752, 25031682, 21689735, 18045101, 14159915, 10112948, + 5974900, 1811564, -2298588, -6289153, -10097187, -13660268, + -16919025, -19831526, -22344434, -24432003, -26066684, -27225918, + -27897027, -28086260, -27792985, -27036877, -25834713, -24221524, + -22225205, -19892344, -17274057, -14413387, -11365046, -8183432, + -4931257, -1661870, 1574892, 4716073, 7715537, 10517058, + 13094848, 15384977, 17377333, 19030984, 20328238, 21250991, + 21798830, 21964593, 21748393, 21175692, 20254116, 19005897, + 17462773, 15654865, 13621029, 11397319, 9026624, 6554408, + 4021974, 1473276, -1045124, -3494283, -5828872, -8019481, + -10025125, -11819321, -13375815, -14668543, -15689994, -16418956, + -16857296, -16995023, -16846583, -16415125, -15716033, -14759735, + -13579195, -12195213, -10628145, -8917589, -7096262, -5190286, + -3236944, -1276058, 664754, 2555441, 4356032, 6042109, + 7595282, 8978157, 10184344, 11185233, 11977764, 12548965, + 12893033, 13012020, 12907487, 12584782, 12058266, 11340230, + 10442126, 9390046, 8200237, 6899404, 5512572, 4061687, + 2576181, 1082059, -399648, -1840723, -3216302, -4503358, + -5687931, -6747557, -7663720, -8435769, -9042960, -9483154, + -9751663, -9850907, -9778461, -9539916, -9147874, -8613425, + -7936567, -7146604, -6254913, -5277446, -4230376, -3136291, + -2020988, -890678, 223543, 1308679, 2340192, 3311287, + 4208466, 5007097, 5699297, 6284284, 6744247, 7081498, + 7287208, 7366198, 7318562, 7141633, 6855926, 6457825, + 5963094, 5371511, 4712336, 3985065, 3203226, 2395092, + 1563689, 724529, -106180, -913239, -1684731, -2407744, + -3072538, -3667103, -4189285, -4623149, -4965217, -5220752, + -5374082, -5440210, -5406704, -5282249, -5070729, -4783594, + -4415459, -3989230, -3500736, -2970824, -2398253, -1803663, + -1193152, -574547, 34052, 628024, 1193352, 1723345, + 2216278, 2654349, 3031779, 3355709, 3608106, 3794901, + 3913643, 3960671, 3940274, 3855545, 3701699, 3492897, + 3230771, 2919037, 2567523, 2182907, 1769008, 1336204, + 894476, 450016, 4193, -419198, -833301, -1219488, + -1571324, -1888273, -2167536, -2401825, -2582554, -2722866, + -2806550, -2845009, -2831941, -2765462, -2661468, -2513744, + -2323485, -2105147, -1854412, -1580356, -1286629, -975301, + -656393, -339857, -25917, 279482, 571766, 848201, + 1100367, 1327317, 1524758, 1690162, 1819819, 1918854, + 1980841, 2008787, 1998777, 1955867, 1882817, 1780155, + 1648781, 1489634, 1319263, 1122357, 915235, 703731, + 481879, 255745, 35727, -179285, -387338, -576268, + -757789, -914450, -1054956, -1171327, -1261362, -1329783, + -1378263, -1393224, -1392519, -1361178, -1306723, -1240796, + -1149249, -1040253, -919112, -788188, -644100, -491012, + -342989, -186968, -35569, 111048, 254402, 388767, + 509286, 617211, 714449, 793277, 860190, 907067, + 935048, 948515, 946097, 928525, 896936, 846039, + 783146, 710400, 630008, 540362, 441121, 340845, + 239764, 133643, 30048, -71439, -166063, -251751, + -336514, -413690, -476442, -527614, -569975, -607659, + -628455, -633038, -634976, -620199, -598848, -564510, + -525244, -476398, -419249, -365706, -299017, -231986, + -163672, -92415, -26440, 38907, 105485, 163003, + 216292, 267479, 308792, 345665, 374432, 397776, + 404976, 414881, 412461, 405962, 388957, 369428, + 345535, 309636, 276555, 239076, 192795, 150978, + 104505, 65702, 20859, -25024, -65606, -102706, + -135673, -165912, -198790, -220192, -234479, -251306, + -260362, -266001, -259886, -260002, -248657, -234334, + -217503, -202297, -179055, -150768, -125468, -98832, + -72894, -42018, -16516, 10166, 39386, 62450, + 82544, 102115, 120459, 135598, 149235, 157042, + 158816, 163383, 162876, 159670, 151270, 148796, + 135741, 125439, 109131, 94537, 77595, 61876, + 45016, 28294, 13536, -6488, -22571, -33842, + -48832, -63638, -72140, -79993, -87569, -91387, + -95105, -99573, -95906, -97510, -90434, -89172, + -80757, -73767, -68179, -54591, -49098, -38081, + -30096, -17678, -7483, 5124, 12679, 18818, + 30341, 33042, 42717, 49133, 51057, 55150, + 58448, 56577, 55508, 55179, 54289, 49140, + 48421, 43652, 34986, 33365, 29958, 21943, + 13434, 9563, 6068, -2185, -7641, -11314, + -14491, -18527, -21375, -25536, -28757, -27068, + -31902, -32247, -31210, -32378, -28844, -28972, + -26917, -25630, -19653, -19191, -12051, -13582, + -4826, -5962, -4862, 33, 4819, 6114, + 9049, 8981, 14172, 14118, 15072, 15034, + 13362, 14617, 16282, 17865, 16105, 14323, + 10499, 14625, 9801, 12096, 5293, 8147, + 4763, 1429, -173, 295, 161, -2375, + -3393, -8030, -6053, -7764, -7193, -6627, + -9527, -5178, -9881, -4584, -6991, -9292, + -4680, -4957, -5201, -6648, -1473, -1584, + -1987, -2221, 2201, 2720, -1950, 3637, + 2274, 2021, -940, 2507, 2115, 4251, + 1166, 6089, 4628, 2775, 1047, 4879, + 3630, 4012, 4345, 3681, -266, 1657, + 2323, 829, 3660, 1100, -605, 876, + -165, -2762, 1204, -1477, 1170, 1144, + -1294, 1092, -473, -2287, 641, -3627, + 953, -4014, -3664, 1544, -1398, -3629, + 880, -264, 338, 1087, 1064, 578, + 1306, 2399, 218, -903, 3089, 1797, + 434, 3576, 2306, 1934, 3420, 2750, + 373, -2829, -1670, 851, 1698, 227, + 3297, -3177, -2034, 108, -559, 2858, + -1395, -1436, -3109, 2556, -1476, -899, + 232, -2557, -1521, -2150, 1048, -826, +}; + +static const int32_t fft_in_imag_3072_q31[3072] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; + +static const int32_t fft_ref_real_3072_q31[3072] = { + -45, 22, 19, -6, 19, -10, + 21, 10, -22, 11, -4, -26, + -5, -42, 5, 6, 9, -28, + -19, 5, 4, 13, -6, -24, + -4, -32, -14, -5, -21, -19, + -14, 5, 1, 12, 17, -4, + 17, 6, -31, -49, 6, -14, + -10, 43, -3, -29, -20, -4, + 1, -37, 37, -25, 21, -56, + -6, 6, -12, 10, -2790, 237344, + -3579960, 21781560, -69391869, 129763729, -149772245, 107836740, + -47262115, 11753740, -1421223, 57093, -178, -10, + 16, -20, 6, -4, -33, -18, + -22, -12, -20, -5, -33, -9, + 0, 2, -36, 15, 11, 36, + 45, 16, 26, -15, 15, -13, + -4, 17, 24, 17, -4, 0, + 13, -19, 17, -3, 20, 11, + -26, -11, 3, 0, -12, 26, + 20, 10, 42, -8, -16, -56, + 4, -8, 11, 8, 40, -9, + 5, -40, 20, -4, 19, -17, + 11, -9, -21, -16, 31, 31, + 0, 36, -14, 0, 2, -9, + -35, -37, -37, 37, -6, -2, + -35, 3, -19, -11, 11, -3, + -5, -15, -4, 34, 0, 5, + -27, 10, 28, -14, 26, -20, + -27, 2, -4, 32, 12, 13, + -4, -19, 25, 30, 0, 2, + 7, 21, -28, -10, -21, 10, + -4, -8, 8, -1, -8, 35, + -18, -8, -20, 5, -17, 3, + 2, 11, -22, -13, 3, 27, + 8, 34, 6, -17, 31, -17, + 31, -34, -8, 0, 9, 5, + -22, 2, 19, -19, 8, 5, + 16, -8, 26, 6, 4, 21, + 25, -7, 11, -34, -4, 17, + 11, -1, -20, -28, -6, -38, + -7, 17, 15, -11, 32, -1, + 8, 21, -8, 30, -55, -19, + -14, -10, 8, 8, -14, -21, + 15, 27, 5, -12, 9, -24, + -7, -3, -8, -20, -14, -7, + 6, -28, -3, 1, -6, -21, + -21, 2, -22, 44, -5, -25, + -34, 18, 19, 5, 9, 23, + 7, 6, -20, 22, 0, -13, + 51, 11, 2, -16, -6, 0, + 8, -6, 0, 18, 16, 22, + 10, -7, -54, -11, -18, -8, + 5, 27, 12, -17, -24, 13, + 11, 9, 2, -12, 23, 0, + 12, 31, -14, 12, 9, 24, + 2, -1, 32, -8, 11, -9, + 26, 6, -1, -3, 7, 57, + -20, 10, 8, 13, -24, 3, + -7, -29, 46, 30, 0, 22, + -2, -20, 39, 24, -15, -2, + -2, 7, -16, -50, 29, -7, + -22, 23, 19, -21, -29, -22, + 32, -4, 9, -14, -20, -17, + -12, 2, -19, -24, 10, 22, + 10, 14, -15, -3, -41, -20, + 3, 6, 20, 10, 8, -11, + -4, 10, 2, -19, -10, 41, + -8, -6, -36, -35, -11, 0, + -11, 1, -3, -16, 12, -14, + -28, 2, 6, -10, -14, -2, + 14, 10, -7, -13, 37, 17, + -1, 12, 9, -37, 34, -36, + 7, 8, 4, -13, 22, 24, + 19, 0, 24, 26, -33, -30, + 28, 19, -26, 20, -29, -12, + -2, -25, -26, 1, 3, 43, + -4, -12, -23, 4, -19, 21, + -34, -3, 55, -20, -29, -23, + 30, 51, 13, -15, 10, 9, + 17, -28, -23, -16, 64, -1, + 5, 10, -4, 29, 26, -7, + 18, -37, -24, 49, -18, 11, + -15, -29, 34, -2, -15, -17, + -6, 16, -15, 7, 29, -9, + 23, 18, 10, -10, 23, -33, + 28, -19, -1, 31, -13, 5, + -5, -47, -21, 29, 4, 13, + -7, -19, 2, 9, -31, 3, + 3, -3, 4, -1, -32, -34, + -11, -29, 11, -7, 44, 13, + -25, -12, -21, 6, 5, -6, + 71, -5, -4, 25, -4, -6, + -39, 16, -26, 9, -2, -14, + -3, -7, -5, -8, -21, -20, + -25, 9, 10, 2, -44, 2, + 16, 3, 31, 8, -16, -5, + 6, -7, 9, 7, 3, -15, + -13, 11, -44, 11, -4, 14, + 15, 6, -39, -2, -23, 9, + 13, -48, 19, 9, 7, -24, + 15, 43, -17, 40, 6, -26, + -36, 2, -30, 28, 8, -5, + -16, -20, 25, 48, -17, -6, + -45, 31, 7, 5, 27, 21, + 19, 36, -25, 18, 4, 3, + -20, -23, 8, -27, 27, -8, + -20, 23, -18, -13, -12, 13, + 2, 1, 15, 23, -10, 24, + -42, -46, 54, 18, -13, -11, + 5, 24, 12, 12, -19, 6, + -52, -10, 0, -2, -4, -10, + -14, 12, 12, -15, -17, 46, + 26, 20, 38, 16, -9, -12, + 0, -28, -8, -6, 4, -13, + 5, 7, 5, 0, 2, 10, + -15, 9, -2, 39, -13, 9, + 7, 11, -7, 26, 9, -11, + -20, -26, 42, 32, -22, -13, + 10, 39, 10, 6, -15, 25, + -17, -9, 14, -9, -5, -33, + 5, -23, -30, 0, 1, -6, + 3, 37, -15, 7, -4, 17, + 29, 14, 20, 11, -5, -14, + 35, 12, -13, -12, 8, -27, + 0, -8, -7, -8, 30, 23, + -41, 8, -28, 35, 53, 21, + 27, -17, -32, -5, -48, 4, + -8, 19, -2, -29, 17, 6, + -11, 2, -7, 0, 0, 1, + -34, -22, 22, -13, 10, 2, + -15, 22, 0, -47, 9, -1, + -42, -7, -10, 10, -21, -55, + 25, -27, -15, -21, -23, 10, + 2, -35, 20, -20, -3, 2, + -28, 9, 12, 40, 3, 25, + -9, -19, 15, 7, 8, -11, + 19, 10, -1, -15, -11, 32, + -32, -50, 29, -12, 13, 11, + -6, 30, 4, -26, 9, 3, + -4, 13, -32, -16, -9, 10, + 33, 26, 27, -23, -35, 10, + 15, -5, 53, 8, -25, -10, + -5, 7, 9, 11, -4, -34, + -7, 2, -5, 11, -13, -61, + -24, 18, -16, 13, 9, -45, + 10, 31, -9, 13, -3, 11, + 31, -30, 38, -14, -3, 18, + 26, 10, 10, 17, -16, -3, + -6, 37, -36, -17, -3, 30, + 14, 6, -31, -1, 8, -39, + 18, 20, 17, 22, -35, -12, + 0, -5, -6, -2, -37, 20, + -10, -16, -2, -5, 21, -8, + -5, 18, -12, -17, -5, 4, + -33, -8, -33, -23, -25, -14, + -15, 4, 53, -61, -6, 34, + -3, 11, -53, -7, -6, -11, + 28, 4, -16, -6, -13, -3, + 35, 3, -15, -16, 24, 16, + 25, 45, 5, -18, 2, 15, + 19, 42, 33, 17, 39, 8, + 3, 0, -12, -19, -9, 31, + 15, 40, 19, 8, 7, 5, + 14, -33, 8, -3, 16, -33, + -31, -13, -31, 37, -28, -19, + 6, 0, -46, 29, -22, -10, + -8, -2, -42, 29, -35, 10, + 40, 20, 8, 19, -13, 8, + 6, -2, 20, -15, 27, -42, + -11, 13, -1, 30, 31, 29, + 36, -27, 11, 36, 0, 3, + -9, 12, 1, -26, -8, 17, + -18, -9, -44, 23, -8, -36, + 2, 36, 41, 33, -28, -25, + 7, -8, 29, 43, 13, 19, + -7, 19, -19, -6, 34, -3, + 25, 40, 1, 3, -4, 5, + -16, -11, 36, 3, -17, -31, + 13, 3, -13, 3, -5, 6, + -6, -19, 1, -4, -7, 13, + -25, 26, -1, 26, -40, 0, + -1, -34, 21, 31, -22, 23, + 14, -19, 25, -7, 21, 31, + -6, 16, -16, 10, 28, 7, + -28, 7, -33, -6, 8, -31, + -16, -11, -3, -6, -7, 18, + -18, 24, 31, -24, 32, -43, + 9, -8, 12, 25, -21, 13, + -7, -5, -18, -48, -4, -33, + 15, 11, 7, 26, -10, -28, + -20, 8, 40, 15, 56, -35, + -42, 16, 3, -36, -25, 6, + 11, 24, -35, 10, -4, 5, + 17, 25, 73, -2, 72, -20, + -5, 19, 13, -8, -27, -18, + -11, 2, -15, 12, 16, -20, + -23, -12, -5, 47, 12, 9, + -14, 1, -10, 15, -4, -9, + -8, -5, -18, 28, -49, 18, + 35, 11, -8, 12, -10, -13, + 13, -4, -7, 4, 1, -13, + 13, 21, 28, 15, 19, -3, + 15, -8, 38, 31, -15, 21, + -8, -4, -10, 34, 3, -18, + -1, -20, -18, 16, -41, -3, + -10, -4, 15, -25, 2, -11, + -4, -14, 6, -14, -10, -17, + 10, -27, 51, -51, 30, 13, + -15, 4, -12, -55, -3, 17, + -7, -4, 0, -15, -28, -29, + -12, -29, 12, 6, -12, -46, + 9, 4, 9, -21, 10, 4, + 7, -9, -22, 4, -3, -8, + -15, 53, 26, 5, -19, -24, + 13, 16, -16, -26, 20, -35, + -26, 25, -15, 4, -23, 30, + -18, 11, -31, -2, -13, 24, + 3, 9, -1, 1, -1, -7, + 10, 29, -4, -1, 5, 12, + 5, 6, 3, 22, -18, 11, + -26, -4, -10, 10, -13, 7, + 13, 1, 36, -9, 35, 32, + 2, 7, -20, 19, -6, -18, + 15, -8, 33, 20, -9, -18, + 25, 29, 40, -23, -6, 34, + -21, 5, 21, -7, -2, 7, + -16, -3, 2, -18, 23, 9, + 62, 21, 32, 2, 6, -16, + 25, -9, -8, 31, 6, 37, + 14, 30, -36, -15, 4, 16, + 25, -13, 23, 26, 38, -5, + -27, 20, 27, -2, 9, -22, + 47, -3, 6, 42, 12, 17, + 8, -7, 47, 43, 2, 3, + -24, 9, -3, -11, 5, 42, + 13, 7, -23, -36, 22, 26, + -6, 18, -11, -15, -17, 18, + 2, 36, -40, -1, -18, -42, + 33, 56, 10, -1, 16, -2, + 6, -23, 16, 7, -35, -5, + -13, -11, -4, 10, 5, 5, + 33, 0, 8, 23, -19, 31, + -23, 2, -51, -30, -24, -28, + 13, -10, 8, -19, 14, -23, + -8, 3, -14, 17, -36, -21, + 12, 41, -5, 26, -4, -10, + 25, 40, -21, -4, 17, 8, + -22, -3, -38, 22, 5, 28, + 38, 0, -3, 1, 20, -11, + -3, -6, 28, -26, 9, -21, + 5, -14, -2, -42, -14, 23, + -21, -24, -13, 20, -19, -13, + -3, -7, 20, 13, -16, 18, + -14, -2, 14, 31, -1, -12, + -25, -2, 1, -9, -32, 37, + -5, -3, 30, -13, -7, 12, + 31, 12, -7, -13, 30, -3, + -5, 37, -32, -9, 1, -2, + -25, -12, -1, 31, 14, -2, + -14, 18, -16, 13, 20, -7, + -3, -13, -19, 20, -13, -24, + -21, 23, -14, -42, -2, -14, + 5, -21, 9, -26, 28, -6, + -3, -11, 20, 1, -3, 0, + 38, 28, 5, 22, -38, -3, + -22, 8, 17, -4, -21, 40, + 25, -10, -4, 26, -5, 41, + 12, -21, -36, 17, -14, 3, + -8, -23, 14, -19, 8, -10, + 13, -28, -24, -30, -51, 2, + -23, 31, -19, 23, 8, 0, + 33, 5, 5, 10, -4, -11, + -13, -5, -35, 7, 16, -23, + 6, -2, 16, -1, 10, 56, + 33, -42, -18, -1, -40, 36, + 2, 18, -17, -15, -11, 18, + -6, 26, 22, -36, -23, 7, + 13, 42, 5, -11, -3, 9, + -24, 3, 2, 43, 47, -7, + 8, 17, 12, 42, 6, -3, + 47, -22, 9, -2, 27, 20, + -27, -5, 38, 26, 23, -13, + 25, 16, 4, -15, -36, 30, + 14, 37, 6, 31, -8, -9, + 25, -16, 6, 2, 32, 21, + 62, 9, 23, -18, 2, -3, + -16, 7, -2, -7, 21, 5, + -21, 34, -6, -23, 40, 29, + 25, -18, -9, 20, 33, -8, + 15, -18, -6, 19, -20, 7, + 2, 32, 35, -9, 36, 1, + 13, 7, -13, 10, -10, -4, + -26, 11, -18, 22, 3, 6, + 5, 12, 5, -1, -4, 29, + 10, -7, -1, 1, -1, 9, + 3, 24, -13, -2, -31, 11, + -18, 30, -23, 4, -15, 25, + -26, -35, 20, -26, -16, 16, + 13, -24, -19, 5, 26, 53, + -15, -8, -3, 4, -22, -9, + 7, 4, 10, -21, 9, 4, + 9, -46, -12, 6, 12, -29, + -12, -29, -28, -15, 0, -4, + -7, 17, -3, -55, -12, 4, + -15, 13, 30, -51, 51, -27, + 10, -17, -10, -14, 6, -14, + -4, -11, 2, -25, 15, -4, + -10, -3, -41, 16, -18, -20, + -1, -18, 3, 34, -10, -4, + -8, 21, -15, 31, 38, -8, + 15, -3, 19, 15, 28, 21, + 13, -13, 1, 4, -7, -4, + 13, -13, -10, 12, -8, 11, + 35, 18, -49, 28, -18, -5, + -8, -9, -4, 15, -10, 1, + -14, 9, 12, 47, -5, -12, + -23, -20, 16, 12, -15, 2, + -11, -18, -27, -8, 13, 19, + -5, -20, 72, -2, 73, 25, + 17, 5, -4, 10, -35, 24, + 11, 6, -25, -36, 3, 16, + -42, -35, 56, 15, 40, 8, + -20, -28, -10, 26, 7, 11, + 15, -33, -4, -48, -18, -5, + -7, 13, -21, 25, 12, -8, + 9, -43, 32, -24, 31, 24, + -18, 18, -7, -6, -3, -11, + -16, -31, 8, -6, -33, 7, + -28, 7, 28, 10, -16, 16, + -6, 31, 21, -7, 25, -19, + 14, 23, -22, 31, 21, -34, + -1, 0, -40, 26, -1, 26, + -25, 13, -7, -4, 1, -19, + -6, 6, -5, 3, -13, 3, + 13, -31, -17, 3, 36, -11, + -16, 5, -4, 3, 1, 40, + 25, -3, 34, -6, -19, 19, + -7, 19, 13, 43, 29, -8, + 7, -25, -28, 33, 41, 36, + 2, -36, -8, 23, -44, -9, + -18, 17, -8, -26, 1, 12, + -9, 3, 0, 36, 11, -27, + 36, 29, 31, 30, -1, 13, + -11, -42, 27, -15, 20, -2, + 6, 8, -13, 19, 8, 20, + 40, 10, -35, 29, -42, -2, + -8, -10, -22, 29, -46, 0, + 6, -19, -28, 37, -31, -13, + -31, -33, 16, -3, 8, -33, + 14, 5, 7, 8, 19, 40, + 15, 31, -9, -19, -12, 0, + 3, 8, 39, 17, 33, 42, + 19, 15, 2, -18, 5, 45, + 25, 16, 24, -16, -15, 3, + 35, -3, -13, -6, -16, 4, + 28, -11, -6, -7, -53, 11, + -3, 34, -6, -61, 53, 4, + -15, -14, -25, -23, -33, -8, + -33, 4, -5, -17, -12, 18, + -5, -8, 21, -5, -2, -16, + -10, 20, -37, -2, -6, -5, + 0, -12, -35, 22, 17, 20, + 18, -39, 8, -1, -31, 6, + 14, 30, -3, -17, -36, 37, + -6, -3, -16, 17, 10, 10, + 26, 18, -3, -14, 38, -30, + 31, 11, -3, 13, -9, 31, + 10, -45, 9, 13, -16, 18, + -24, -61, -13, 11, -5, 2, + -7, -34, -4, 11, 9, 7, + -5, -10, -25, 8, 53, -5, + 15, 10, -35, -23, 27, 26, + 33, 10, -9, -16, -32, 13, + -4, 3, 9, -26, 4, 30, + -6, 11, 13, -12, 29, -50, + -32, 32, -11, -15, -1, 10, + 19, -11, 8, 7, 15, -19, + -9, 25, 3, 40, 12, 9, + -28, 2, -3, -20, 20, -35, + 2, 10, -23, -21, -15, -27, + 25, -55, -21, 10, -10, -7, + -42, -1, 9, -47, 0, 22, + -15, 2, 10, -13, 22, -22, + -34, 1, 0, 0, -7, 2, + -11, 6, 17, -29, -2, 19, + -8, 4, -48, -5, -32, -17, + 27, 21, 53, 35, -28, 8, + -41, 23, 30, -8, -7, -8, + 0, -27, 8, -12, -13, 12, + 35, -14, -5, 11, 20, 14, + 29, 17, -4, 7, -15, 37, + 3, -6, 1, 0, -30, -23, + 5, -33, -5, -9, 14, -9, + -17, 25, -15, 6, 10, 39, + 10, -13, -22, 32, 42, -26, + -20, -11, 9, 26, -7, 11, + 7, 9, -13, 39, -2, 9, + -15, 10, 2, 0, 5, 7, + 5, -13, 4, -6, -8, -28, + 0, -12, -9, 16, 38, 20, + 26, 46, -17, -15, 12, 12, + -14, -10, -4, -2, 0, -10, + -52, 6, -19, 12, 12, 24, + 5, -11, -13, 18, 54, -46, + -42, 24, -10, 23, 15, 1, + 2, 13, -12, -13, -18, 23, + -20, -8, 27, -27, 8, -23, + -20, 3, 4, 18, -25, 36, + 19, 21, 27, 5, 7, 31, + -45, -6, -17, 48, 25, -20, + -16, -5, 8, 28, -30, 2, + -36, -26, 6, 40, -17, 43, + 15, -24, 7, 9, 19, -48, + 13, 9, -23, -2, -39, 6, + 15, 14, -4, 11, -44, 11, + -13, -15, 3, 7, 9, -7, + 6, -5, -16, 8, 31, 3, + 16, 2, -44, 2, 10, 9, + -25, -20, -21, -8, -5, -7, + -3, -14, -2, 9, -26, 16, + -39, -6, -4, 25, -4, -5, + 71, -6, 5, 6, -21, -12, + -25, 13, 44, -7, 11, -29, + -11, -34, -32, -1, 4, -3, + 3, 3, -31, 9, 2, -19, + -7, 13, 4, 29, -21, -47, + -5, 5, -13, 31, -1, -19, + 28, -33, 23, -10, 10, 18, + 23, -9, 29, 7, -15, 16, + -6, -17, -15, -2, 34, -29, + -15, 11, -18, 49, -24, -37, + 18, -7, 26, 29, -4, 10, + 5, -1, 64, -16, -23, -28, + 17, 9, 10, -15, 13, 51, + 30, -23, -29, -20, 55, -3, + -34, 21, -19, 4, -23, -12, + -4, 43, 3, 1, -26, -25, + -2, -12, -29, 20, -26, 19, + 28, -30, -33, 26, 24, 0, + 19, 24, 22, -13, 4, 8, + 7, -36, 34, -37, 9, 12, + -1, 17, 37, -13, -7, 10, + 14, -2, -14, -10, 6, 2, + -28, -14, 12, -16, -3, 1, + -11, 0, -11, -35, -36, -6, + -8, 41, -10, -19, 2, 10, + -4, -11, 8, 10, 20, 6, + 3, -20, -41, -3, -15, 14, + 10, 22, 10, -24, -19, 2, + -12, -17, -20, -14, 9, -4, + 32, -22, -29, -21, 19, 23, + -22, -7, 29, -50, -16, 7, + -2, -2, -15, 24, 39, -20, + -2, 22, 0, 30, 46, -29, + -7, 3, -24, 13, 8, 10, + -20, 57, 7, -3, -1, 6, + 26, -9, 11, -8, 32, -1, + 2, 24, 9, 12, -14, 31, + 12, 0, 23, -12, 2, 9, + 11, 13, -24, -17, 12, 27, + 5, -8, -18, -11, -54, -7, + 10, 22, 16, 18, 0, -6, + 8, 0, -6, -16, 2, 11, + 51, -13, 0, 22, -20, 6, + 7, 23, 9, 5, 19, 18, + -34, -25, -5, 44, -22, 2, + -21, -21, -6, 1, -3, -28, + 6, -7, -14, -20, -8, -3, + -7, -24, 9, -12, 5, 27, + 15, -21, -14, 8, 8, -10, + -14, -19, -55, 30, -8, 21, + 8, -1, 32, -11, 15, 17, + -7, -38, -6, -28, -20, -1, + 11, 17, -4, -34, 11, -7, + 25, 21, 4, 6, 26, -8, + 16, 5, 8, -19, 19, 2, + -22, 5, 9, 0, -8, -34, + 31, -17, 31, -17, 6, 34, + 8, 27, 3, -13, -22, 11, + 2, 3, -17, 5, -20, -8, + -18, 35, -8, -1, 8, -8, + -4, 10, -21, -10, -28, 21, + 7, 2, 0, 30, 25, -19, + -4, 13, 12, 32, -4, 2, + -27, -20, 26, -14, 28, 10, + -27, 5, 0, 34, -4, -15, + -5, -3, 11, -11, -19, 3, + -35, -2, -6, 37, -37, -37, + -35, -9, 2, 0, -14, 36, + 0, 31, 31, -16, -21, -9, + 11, -17, 19, -4, 20, -40, + 5, -9, 40, 8, 11, -8, + 4, -56, -16, -8, 42, 10, + 20, 26, -12, 0, 3, -11, + -26, 11, 20, -3, 17, -19, + 13, 0, -4, 17, 24, 17, + -4, -13, 15, -15, 26, 16, + 45, 36, 11, 15, -36, 2, + 0, -9, -33, -5, -20, -12, + -22, -18, -33, -4, 6, -20, + 16, -10, -178, 57093, -1421223, 11753740, + -47262115, 107836740, -149772245, 129763729, -69391869, 21781560, + -3579960, 237344, -2790, 10, -12, 6, + -6, -56, 21, -25, 37, -37, + 1, -4, -20, -29, -3, 43, + -10, -14, 6, -49, -31, 6, + 17, -4, 17, 12, 1, 5, + -14, -19, -21, -5, -14, -32, + -4, -24, -6, 13, 4, 5, + -19, -28, 9, 6, 5, -42, + -5, -26, -4, 11, -22, 10, + 21, -10, 19, -6, 19, 22, +}; + +static const int32_t fft_ref_imag_3072_q31[3072] = { + 0, -1, -4, -15, -6, 19, + 1, 14, 47, -16, 15, 7, + 11, -9, -21, 4, 30, 43, + 16, 41, -11, 34, -26, 1, + 5, -11, -9, 45, -15, -18, + 18, -1, -6, 47, 25, -24, + -21, -56, 19, -1, 2, -12, + -15, 28, -26, 5, 15, 0, + 3, -17, 33, 0, -32, -16, + 10, 21, -16, -2, -3984, 340956, + -5154182, 31427830, -100341944, 188051672, -217523306, 156961255, + -68943044, 17183326, -2082337, 83868, -223, -19, + -32, -29, 1, 20, -16, 53, + 22, 26, -19, 7, -22, -18, + 4, 3, -20, 25, -23, 5, + -23, 17, -26, 23, -25, 7, + -19, -41, 14, -20, -1, 11, + 3, -12, -4, 11, 23, 8, + 15, 4, 2, 23, 26, 9, + 30, 31, -20, -17, -38, 39, + -23, 7, 10, 18, 17, 0, + 23, -15, 12, 25, -9, -28, + 34, -19, -23, 6, 11, 1, + -13, -3, 19, 23, -10, -19, + 25, 5, -3, -7, -22, 17, + 43, -32, 10, -10, -43, -34, + 25, 1, 7, -26, 4, 21, + -2, 5, 2, -15, -1, 19, + -19, -1, 37, -18, -44, 15, + -14, 1, 24, -11, -14, 6, + -20, -14, 16, -11, 31, 35, + 14, -4, 3, 17, -22, -21, + 24, -32, 26, 43, -9, -20, + -13, -21, 15, -25, 30, -11, + -14, -2, -28, -23, -21, 8, + 24, -9, -36, -29, 1, 6, + -6, 0, -11, -19, 22, 15, + 29, -28, -12, 18, 18, 4, + 10, -56, 7, -21, -32, 11, + -20, -18, -35, 19, -15, 4, + 42, -7, 43, 2, 9, -11, + 14, 9, -2, 25, 14, -4, + 0, 7, 19, 7, 21, 20, + -9, 20, 22, -22, -18, 21, + -19, 16, 0, 2, -8, -24, + 20, 13, -6, 15, -20, -19, + -35, -21, -1, 0, 22, 11, + 20, 14, -14, 41, 36, -2, + -4, 1, 35, 4, 19, -12, + 3, -5, -26, -26, -33, 12, + 13, -21, -20, 18, -23, -14, + -13, -23, -14, 20, -20, 12, + 16, 7, 7, 12, -9, 15, + -17, 20, 29, 12, -7, -11, + 17, -35, -18, 6, -3, 22, + -10, -12, -21, 21, 12, -4, + -28, 27, -8, -5, -8, 21, + -9, 16, 19, -13, -1, 0, + -40, 34, 1, -22, -7, 5, + 25, 15, -5, -38, 17, 35, + -11, 19, -8, -9, -19, 42, + 10, 10, -63, 3, -39, 18, + -7, 32, -2, 0, 7, 18, + 20, 11, -57, -22, -1, 18, + -13, 13, -11, 5, -32, 16, + -11, 40, 3, 8, -7, -62, + -5, 22, -16, -6, 15, 34, + 20, -55, 16, 36, 19, 30, + 8, 31, -2, 19, -46, -12, + -20, -7, -13, -15, -5, 6, + 9, -12, -6, 23, -7, 7, + -33, -23, -1, -17, -2, 0, + -1, 9, 11, 42, -3, -57, + -42, 3, -13, -30, 26, -13, + 26, -28, 17, -36, -32, 12, + 17, 8, -33, 27, 18, -13, + 3, 24, 3, 47, -8, 7, + 11, -17, 0, -12, -20, 12, + -15, -18, -6, -20, -6, 9, + 19, 20, -13, 4, 18, 3, + 11, -6, 37, 27, 18, -2, + -13, -8, 43, 33, -7, -11, + 7, 30, 3, 9, 17, 20, + -40, 25, 48, 8, 8, 29, + -23, 19, -13, -4, 30, -13, + 27, 18, 43, -1, 35, 28, + -38, -14, -32, 14, 14, -7, + 26, 4, -18, 37, -26, 5, + 18, 38, 6, 20, 15, 13, + 17, 27, 23, 21, 9, 7, + 37, 28, 35, -12, 11, -11, + -26, -5, 18, -56, 11, -31, + -20, 28, -21, 2, 35, -17, + -26, 30, -28, -4, 40, 6, + 19, -6, 11, 0, -1, 17, + 4, 0, -33, -4, 3, 17, + 18, 15, -15, 31, -14, -3, + -19, -8, 2, -50, 2, -5, + -12, 14, 18, -20, -2, 30, + -10, -50, -23, -7, -12, 8, + 6, -1, 39, 6, 0, -58, + 14, 20, 16, -14, -35, 0, + -19, 27, -11, -7, -19, 14, + 10, 0, 43, -18, 33, 5, + -10, 72, 4, -1, -7, -22, + -25, -24, 1, -8, 3, 1, + 45, 3, 22, 5, -12, -23, + -46, 11, 8, -19, 8, 39, + 4, 2, -31, 4, -8, 20, + 17, 33, -11, 4, -23, 8, + 10, -5, -4, 5, 25, -34, + -1, 18, -19, -8, -27, 8, + 5, -39, 48, -20, -13, 32, + 27, -31, 17, -21, 13, -9, + 11, 9, 33, -8, -26, 16, + -38, -1, -19, 6, 1, 2, + -2, 21, 42, -14, 27, 5, + -16, 22, -55, 18, -23, 74, + -14, 15, 2, 16, -8, -28, + -36, 27, 15, 1, 20, -6, + 15, 11, -56, 29, 10, 24, + 31, 13, -38, 24, -18, -16, + 16, 13, 4, -9, -6, 7, + 11, -1, -11, -28, -23, 24, + -4, -4, 22, 29, 10, -41, + -2, -24, -14, 13, -42, -20, + 26, 34, -5, -19, 15, 7, + -44, -15, -44, 21, -2, -37, + 25, 33, 8, 22, 30, -3, + 10, -13, 1, 13, 13, 26, + -26, 20, 37, 17, 22, 21, + 25, 1, 0, -17, -1, -5, + 6, -17, 5, -28, 29, 13, + 6, -32, -5, -30, 4, -3, + -13, -14, 35, 19, 31, 34, + 66, 11, -28, 31, 13, 2, + -6, 2, 52, -22, 5, -6, + 1, -21, 22, -46, -28, -10, + 42, 16, -26, 6, -21, -17, + -18, 5, 18, 11, -53, -3, + -9, 2, -3, 8, -7, 32, + 14, -26, 25, 5, 19, 1, + -3, 4, -10, 20, -12, -19, + -11, -35, 3, 11, -27, -10, + -15, -40, -10, 19, -1, -20, + -30, 2, 49, 21, 32, 16, + -43, -3, -34, -26, 4, -23, + 41, 6, 35, 25, 28, 20, + 3, 14, -12, -3, -14, -9, + 10, 26, 6, -42, 10, 21, + 18, 13, -23, 27, -5, -28, + 11, -2, -5, -19, 19, 12, + 32, -1, -12, -24, -11, -11, + -15, 8, 6, 38, 21, 29, + -17, -4, -40, 2, 11, -10, + 1, 10, -16, -12, -65, -5, + 23, 39, -40, -10, 23, -14, + 2, 38, -5, 3, 15, 19, + -1, 25, -20, -22, -24, -17, + 11, -9, -16, 4, 18, -10, + -5, -14, -24, -13, -20, 38, + -31, 17, -33, -15, -9, -25, + 9, -9, 8, -23, -5, 14, + 45, 10, -11, 9, -2, 2, + -17, -8, 11, -13, -24, -3, + 8, -4, -13, 22, 11, 28, + 4, 14, 28, 10, 16, -35, + 5, -8, -3, -24, 9, -22, + -32, 10, 24, -1, 27, 10, + 0, 13, -26, -3, 2, -13, + 24, 23, -20, -38, 13, 21, + -20, -11, -16, -24, -5, 4, + 21, 35, 9, 12, -2, 1, + 16, 15, -31, 47, 7, -3, + 18, -22, -7, 28, -7, -6, + 18, -6, -5, 6, -35, 11, + 18, 3, 9, 4, -4, 5, + -3, -26, 35, 22, 34, 42, + -24, 9, -24, 10, -23, 34, + -32, 30, -1, 32, 17, 13, + -26, 10, 0, -1, 23, 3, + -14, 59, -49, -35, 3, 1, + -17, -5, 0, 5, -5, 18, + 10, 4, -4, 18, -4, -19, + -33, -4, -5, 26, -9, -18, + 53, -30, 19, 23, 39, -9, + -6, 38, -10, 22, 13, -21, + 8, 1, 17, -21, 1, -18, + 34, 25, -4, -3, 32, 0, + -23, -2, -9, -13, 1, -5, + -2, 31, -29, -11, -16, 2, + -8, -29, -34, -44, -51, -28, + 7, -13, 9, -44, -3, 30, + -15, -33, 25, -26, 7, -21, + 40, 31, -5, 42, -18, -21, + 5, -17, 24, -7, 29, 5, + 17, 15, 3, 23, 19, -6, + -33, 12, -10, -31, 38, 6, + 26, 26, 6, 20, 18, 39, + 30, -6, -17, -13, 22, -49, + 10, -13, -16, 15, 12, 14, + -31, -17, -1, 17, 8, -32, + -28, -15, 9, -30, 23, -12, + 17, -22, -21, -60, -33, -16, + 13, -14, -7, 18, 20, -8, + -11, 3, -6, -35, -15, 27, + 24, 67, 10, -18, 8, -14, + 3, 11, -38, -1, -18, 26, + -21, 39, 3, -3, 34, -45, + 11, 0, 11, -2, -16, -7, + 34, -7, 22, 16, -22, -14, + 17, -15, -32, 9, 37, 5, + 27, -15, 24, 2, -9, -17, + -17, -11, -26, 8, 29, 9, + 21, -41, -3, 36, 8, 43, + 14, -6, 9, 5, -1, -3, + -38, -27, 9, 1, 13, 7, + -6, 54, 20, -18, 9, 0, + 10, 6, -8, 30, -17, -28, + -22, 7, 16, -42, 12, 14, + 29, -2, 21, 19, 0, -23, + 19, -16, -31, -3, -32, -45, + -52, -24, -27, 2, 15, -28, + -11, 24, -14, 9, -4, 6, + 3, 1, -22, 21, 5, 37, + 24, 33, 21, 14, -56, -20, + -12, -26, -20, -12, -42, -17, + -12, 0, 0, -7, -6, 14, + 37, -37, -6, -8, 18, -20, + 24, 12, 11, 14, 20, -24, + 6, -6, -1, -19, -7, 4, + 4, -11, -29, 6, -3, 18, + -37, -37, -26, -24, 17, -17, + -3, -21, 19, -2, 15, -5, + -14, 0, 6, 4, 9, -19, + 8, -13, 15, -14, -14, -28, + 19, -24, 40, 6, -10, -20, + -21, -38, -14, -11, 14, 12, + 31, 30, -1, 9, -5, -4, + -29, -20, 43, -7, -33, -10, + -31, 0, 9, 2, 15, 18, + -11, -11, -3, 12, 32, 31, + -9, -8, 19, -5, -2, -8, + -19, 7, 13, -10, -1, -4, + -38, -6, 6, -34, -14, -4, + -11, 6, 12, -18, 28, 73, + -21, 54, -16, 32, -17, 13, + -3, 5, -2, -5, -1, 22, + 8, 29, 15, -9, -26, -29, + 1, 28, -27, 15, 0, 26, + -28, 17, 7, -7, -4, 4, + -3, -22, -3, -25, -6, 10, + -26, -11, -19, -23, -14, 22, + 0, -10, 22, -5, -3, -11, + 27, -6, 27, -8, 19, -8, + -2, 12, 2, 53, 11, -46, + 0, 46, -11, -53, -2, -12, + 2, 8, -19, 8, -27, 6, + -27, 11, 3, 5, -22, 10, + 0, -22, 14, 23, 19, 11, + 26, -10, 6, 25, 3, 22, + 3, -4, 4, 7, -7, -17, + 28, -26, 0, -15, 27, -28, + -1, 29, 26, 9, -15, -29, + -8, -22, 1, 5, 2, -5, + 3, -13, 17, -32, 16, -54, + 21, -73, -28, 18, -12, -6, + 11, 4, 14, 34, -6, 6, + 38, 4, 1, 10, -13, -7, + 19, 8, 2, 5, -19, 8, + 9, -31, -32, -12, 3, 11, + 11, -18, -15, -2, -9, 0, + 31, 10, 33, 7, -43, 20, + 29, 4, 5, -9, 1, -30, + -31, -12, -14, 11, 14, 38, + 21, 20, 10, -6, -40, 24, + -19, 28, 14, 14, -15, 13, + -8, 19, -9, -4, -6, 0, + 14, 5, -15, 2, -19, 21, + 3, 17, -17, 24, 26, 37, + 37, -18, 3, -6, 29, 11, + -4, -4, 7, 19, 1, 6, + -6, 24, -20, -14, -11, -12, + -24, 20, -18, 8, 6, 37, + -37, -14, 6, 7, 0, 0, + 12, 17, 42, 12, 20, 26, + 12, 20, 56, -14, -21, -33, + -24, -37, -5, -21, 22, -1, + -3, -6, 4, -9, 14, -24, + 11, 28, -15, -2, 27, 24, + 52, 45, 32, 3, 31, 16, + -19, 23, 0, -19, -21, 2, + -29, -14, -12, 42, -16, -7, + 22, 28, 17, -30, 8, -6, + -10, 0, -9, 18, -20, -54, + 6, -7, -13, -1, -9, 27, + 38, 3, 1, -5, -9, 6, + -14, -43, -8, -36, 3, 41, + -21, -9, -29, -8, 26, 11, + 17, 17, 9, -2, -24, 15, + -27, -5, -37, -9, 32, 15, + -17, 14, 22, -16, -22, 7, + -34, 7, 16, 2, -11, 0, + -11, 45, -34, 3, -3, -39, + 21, -26, 18, 1, 38, -11, + -3, 14, -8, 18, -10, -67, + -24, -27, 15, 35, 6, -3, + 11, 8, -20, -18, 7, 14, + -13, 16, 33, 60, 21, 22, + -17, 12, -23, 30, -9, 15, + 28, 32, -8, -17, 1, 17, + 31, -14, -12, -15, 16, 13, + -10, 49, -22, 13, 17, 6, + -30, -39, -18, -20, -6, -26, + -26, -6, -38, 31, 10, -12, + 33, 6, -19, -23, -3, -15, + -17, -5, -29, 7, -24, 17, + -5, 21, 18, -42, 5, -31, + -40, 21, -7, 26, -25, 33, + 15, -30, 3, 44, -9, 13, + -7, 28, 51, 44, 34, 29, + 8, -2, 16, 11, 29, -31, + 2, 5, -1, 13, 9, 2, + 23, 0, -32, 3, 4, -25, + -34, 18, -1, 21, -17, -1, + -8, 21, -13, -22, 10, -38, + 6, 9, -39, -23, -19, 30, + -53, 18, 9, -26, 5, 4, + 33, 19, 4, -18, 4, -4, + -10, -18, 5, -5, 0, 5, + 17, -1, -3, 35, 49, -59, + 14, -3, -23, 1, 0, -10, + 26, -13, -17, -32, 1, -30, + 32, -34, 23, -10, 24, -9, + 24, -42, -34, -22, -35, 26, + 3, -5, 4, -4, -9, -3, + -18, -11, 35, -6, 5, 6, + -18, 6, 7, -28, 7, 22, + -18, 3, -7, -47, 31, -15, + -16, -1, 2, -12, -9, -35, + -21, -4, 5, 24, 16, 11, + 20, -21, -13, 38, 20, -23, + -24, 13, -2, 3, 26, -13, + 0, -10, -27, 1, -24, -10, + 32, 22, -9, 24, 3, 8, + -5, 35, -16, -10, -28, -14, + -4, -28, -11, -22, 13, 4, + -8, 3, 24, 13, -11, 8, + 17, -2, 2, -9, 11, -10, + -45, -14, 5, 23, -8, 9, + -9, 25, 9, 15, 33, -17, + 31, -38, 20, 13, 24, 14, + 5, 10, -18, -4, 16, 9, + -11, 17, 24, 22, 20, -25, + 1, -19, -15, -3, 5, -38, + -2, 14, -23, 10, 40, -39, + -23, 5, 65, 12, 16, -10, + -1, 10, -11, -2, 40, 4, + 17, -29, -21, -38, -6, -8, + 15, 11, 11, 24, 12, 1, + -32, -12, -19, 19, 5, 2, + -11, 28, 5, -27, 23, -13, + -18, -21, -10, 42, -6, -26, + -10, 9, 14, 3, 12, -14, + -3, -20, -28, -25, -35, -6, + -41, 23, -4, 26, 34, 3, + 43, -16, -32, -21, -49, -2, + 30, 20, 1, -19, 10, 40, + 15, 10, 27, -11, -3, 35, + 11, 19, 12, -20, 10, -4, + 3, -1, -19, -5, -25, 26, + -14, -32, 7, -8, 3, -2, + 9, 3, 53, -11, -18, -5, + 18, 17, 21, -6, 26, -16, + -42, 10, 28, 46, -22, 21, + -1, 6, -5, 22, -52, -2, + 6, -2, -13, -31, 28, -11, + -66, -34, -31, -19, -35, 14, + 13, 3, -4, 30, 5, 32, + -6, -13, -29, 28, -5, 17, + -6, 5, 1, 17, 0, -1, + -25, -21, -22, -17, -37, -20, + 26, -26, -13, -13, -1, 13, + -10, 3, -30, -22, -8, -33, + -25, 37, 2, -21, 44, 15, + 44, -7, -15, 19, 5, -34, + -26, 20, 42, -13, 14, 24, + 2, 41, -10, -29, -22, 4, + 4, -24, 23, 28, 11, 1, + -11, -7, 6, 9, -4, -13, + -16, 16, 18, -24, 38, -13, + -31, -24, -10, -29, 56, -11, + -15, 6, -20, -1, -15, -27, + 36, 28, 8, -16, -2, -15, + 14, -74, 23, -18, 55, -22, + 16, -5, -27, 14, -42, -21, + 2, -2, -1, -6, 19, 1, + 38, -16, 26, 8, -33, -9, + -11, 9, -13, 21, -17, 31, + -27, -32, 13, 20, -48, 39, + -5, -8, 27, 8, 19, -18, + 1, 34, -25, -5, 4, 5, + -10, -8, 23, -4, 11, -33, + -17, -20, 8, -4, 31, -2, + -4, -39, -8, 19, -8, -11, + 46, 23, 12, -5, -22, -3, + -45, -1, -3, 8, -1, 24, + 25, 22, 7, 1, -4, -72, + 10, -5, -33, 18, -43, 0, + -10, -14, 19, 7, 11, -27, + 19, 0, 35, 14, -16, -20, + -14, 58, 0, -6, -39, 1, + -6, -8, 12, 7, 23, 50, + 10, -30, 2, 20, -18, -14, + 12, 5, -2, 50, -2, 8, + 19, 3, 14, -31, 15, -15, + -18, -17, -3, 4, 33, 0, + -4, -17, 1, 0, -11, 6, + -19, -6, -40, 4, 28, -30, + 26, 17, -35, -2, 21, -28, + 20, 31, -11, 56, -18, 5, + 26, 11, -11, 12, -35, -28, + -37, -7, -9, -21, -23, -27, + -17, -13, -15, -20, -6, -38, + -18, -5, 26, -37, 18, -4, + -26, 7, -14, -14, 32, 14, + 38, -28, -35, 1, -43, -18, + -27, 13, -30, 4, 13, -19, + 23, -29, -8, -8, -48, -25, + 40, -20, -17, -9, -3, -30, + -7, 11, 7, -33, -43, 8, + 13, 2, -18, -27, -37, 6, + -11, -3, -18, -4, 13, -20, + -19, -9, 6, 20, 6, 18, + 15, -12, 20, 12, 0, 17, + -11, -7, 8, -47, -3, -24, + -3, 13, -18, -27, 33, -8, + -17, -12, 32, 36, -17, 28, + -26, 13, -26, 30, 13, -3, + 42, 57, 3, -42, -11, -9, + 1, 0, 2, 17, 1, 23, + 33, -7, 7, -23, 6, 12, + -9, -6, 5, 15, 13, 7, + 20, 12, 46, -19, 2, -31, + -8, -30, -19, -36, -16, 55, + -20, -34, -15, 6, 16, -22, + 5, 62, 7, -8, -3, -40, + 11, -16, 32, -5, 11, -13, + 13, -18, 1, 22, 57, -11, + -20, -18, -7, 0, 2, -32, + 7, -18, 39, -3, 63, -10, + -10, -42, 19, 9, 8, -19, + 11, -35, -17, 38, 5, -15, + -25, -5, 7, 22, -1, -34, + 40, 0, 1, 13, -19, -16, + 9, -21, 8, 5, 8, -27, + 28, 4, -12, -21, 21, 12, + 10, -22, 3, -6, 18, 35, + -17, 11, 7, -12, -29, -20, + 17, -15, 9, -12, -7, -7, + -16, -12, 20, -20, 14, 23, + 13, 14, 23, -18, 20, 21, + -13, -12, 33, 26, 26, 5, + -3, 12, -19, -4, -35, -1, + 4, 2, -36, -41, 14, -14, + -20, -11, -22, 0, 1, 21, + 35, 19, 20, -15, 6, -13, + -20, 24, 8, -2, 0, -16, + 19, -21, 18, 22, -22, -20, + 9, -20, -21, -7, -19, -7, + 0, 4, -14, -25, 2, -9, + -14, 11, -9, -2, -43, 7, + -42, -4, 15, -19, 35, 18, + 20, -11, 32, 21, -7, 56, + -10, -4, -18, -18, 12, 28, + -29, -15, -22, 19, 11, 0, + 6, -6, -1, 29, 36, 9, + -24, -8, 21, 23, 28, 2, + 14, 11, -30, 25, -15, 21, + 13, 20, 9, -43, -26, 32, + -24, 21, 22, -17, -3, 4, + -14, -35, -31, 11, -16, 14, + 20, -6, 14, 11, -24, -1, + 14, -15, 44, 18, -37, 1, + 19, -19, 1, 15, -2, -5, + 2, -21, -4, 26, -7, -1, + -25, 34, 43, 10, -10, 32, + -43, -17, 22, 7, 3, -5, + -25, 19, 10, -23, -19, 3, + 13, -1, -11, -6, 23, 19, + -34, 28, 9, -25, -12, 15, + -23, 0, -17, -18, -10, -7, + 23, -39, 38, 17, 20, -31, + -30, -9, -26, -23, -2, -4, + -15, -8, -23, -11, 4, 12, + -3, -11, 1, 20, -14, 41, + 19, -7, 25, -23, 26, -17, + 23, -5, 23, -25, 20, -3, + -4, 18, 22, -7, 19, -26, + -22, -53, 16, -20, -1, 29, + 32, 19, 223, -83868, 2082337, -17183326, + 68943044, -156961255, 217523306, -188051672, 100341944, -31427830, + 5154182, -340956, 3984, 2, 16, -21, + -10, 16, 32, 0, -33, 17, + -3, 0, -15, -5, 26, -28, + 15, 12, -2, 1, -19, 56, + 21, 24, -25, -47, 6, 1, + -18, 18, 15, -45, 9, 11, + -5, -1, 26, -34, 11, -41, + -16, -43, -30, -4, 21, 9, + -11, -7, -15, 16, -47, -14, + -1, -19, 6, 15, 4, 1, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi_512_32.h b/test/cmocka/src/math/fft/ref_fft_multi_512_32.h new file mode 100644 index 000000000000..2f66b1943af0 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_512_32.h @@ -0,0 +1,364 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_512_NUM_TESTS 1 + +static const int32_t fft_in_real_512_q31[512] = { + 2377, 340, -1196, 1231, 390, -220, + 1663, -1097, 2649, 2272, 2236, 4342, + 3392, 4062, 6525, 5862, 5260, 4298, + 5946, 6952, 9757, 6742, 5507, 6233, + 2746, -6220, -7167, -15262, -27034, -37541, + -48308, -63366, -79216, -99095, -114978, -136892, + -158310, -176123, -192474, -205758, -221510, -225664, + -228096, -217668, -204746, -176198, -137635, -82142, + -9371, 74606, 179015, 298476, 439502, 594979, + 765297, 950034, 1143794, 1342066, 1544951, 1741581, + 1929492, 2099900, 2239228, 2342857, 2403695, 2406952, + 2348372, 2215760, 1999224, 1685659, 1277296, 767477, + 145652, -576843, -1412213, -2348478, -3374059, -4478609, + -5650739, -6865398, -8098727, -9324264, -10504916, -11605125, + -12596267, -13427768, -14058251, -14447678, -14546148, -14324532, + -13731373, -12741029, -11318240, -9445464, -7106292, -4298630, + -1028803, 2685749, 6812826, 11306975, 16107663, 21145964, + 26323168, 31551295, 36709825, 41672460, 46306375, 50477948, + 54028871, 56821040, 58704348, 59538514, 59202251, 57564674, + 54532854, 50034062, 44008837, 36428878, 27312638, 16697669, + 4668381, -8656667, -23115247, -38512817, -54605837, -71114797, + -87734187, -104118684, -119911490, -134714976, -148144714, -159788322, + -169256899, -176160487, -180148043, -180882561, -178086768, -171520785, + -161024629, -146479642, -127877567, -105271227, -78804161, -48731098, + -15371603, 20843417, 59393829, 99676740, 141010892, 182645196, + 223765608, 263517948, 301016662, 335366499, 365667808, 391049190, + 410689064, 423816593, 429762391, 427948384, 417924213, 399366813, + 372118999, 336184162, 291744393, 239157693, 178963703, 111897394, + 38855262, -39076188, -120670524, -204555997, -289250536, -373165551, + -454647551, -532020754, -603591727, -667697336, -722744462, -767256517, + -799860865, -819376406, -824826855, -815445853, -790753739, -750514716, + -694807177, -624005830, -538798080, -440180087, -329446119, -208181786, + -78228178, 58322457, 199177086, 341868299, 483806041, 622316802, + 754703901, 878291108, 990474654, 1088787157, 1170940744, 1234884629, + 1278855173, 1301396967, 1301443489, 1278304462, 1231723405, 1161876364, + 1069381916, 955316252, 821188818, 668927730, 500846793, 319639136, + 128281798, -69969079, -271643589, -473138138, -670788021, -860891365, + -1039840037, -1204143102, -1350521372, -1475985731, -1577855538, -1653868143, + -1702201550, -1721507212, -1710987200, -1670357852, -1599913631, -1500498908, + -1373524895, -1220918243, -1045119827, -849030441, -635951651, -409549533, + -173768611, 67236847, 309172231, 547685783, 778474962, 997324032, + 1200229451, 1383452973, 1543599999, 1677687708, 1783202582, 1858150469, + 1901102793, 1911207547, 1888235269, 1832550711, 1745137332, 1627554622, + 1481924147, 1310889170, 1117549902, 905412773, 678329960, 440406809, + 195946023, -50663943, -295003900, -532722276, -759616239, -971714214, + -1165343086, -1337202219, -1484407839, -1604573685, -1695818260, -1756812449, + -1786819343, -1785656952, -1753727278, -1692003786, -1601974636, -1485654570, + -1345493052, -1184355718, -1005445656, -812247941, -608443862, -397860620, + -184370436, 28155650, 235957789, 435414812, 623142459, 796038302, + 951331454, 1086646118, 1200032277, 1289966608, 1355409649, 1395802572, + 1411048221, 1401526273, 1368065265, 1311904927, 1234670391, 1138345134, + 1025205425, 897763065, 758730599, 610957451, 457356034, 300870453, + 144392851, -9273089, -157452086, -297686686, -427726193, -545602364, + -649633283, -738464975, -811055534, -866715451, -905106645, -926196810, + -930306878, -918048808, -890310025, -848238628, -793193671, -726739273, + -650563089, -566482249, -476362216, -382121302, -285648791, -188804509, + -93364778, -998556, 86774250, 168572629, 243214304, 309689690, + 367216509, 415201133, 453269644, 481254962, 499186921, 507293573, + 505953135, 495734458, 477315340, 451506885, 419217631, 381418708, + 339130862, 293409409, 245305078, 195852674, 146051406, 96847653, + 49123725, 3659924, -38835925, -77768267, -112648940, -143097159, + -168840927, -189723596, -205688470, -216780356, -223132535, -224963023, + -222563624, -216291546, -206547705, -193779025, -178448674, -161042676, + -142059071, -121973485, -101257674, -80361164, -59693896, -39639548, + -20528876, -2649969, 13743698, 28468278, 41381077, 52378701, + 61415428, 68489302, 73635092, 76919839, 78440949, 78342766, + 76763449, 73871913, 69846273, 64879055, 59156607, 52859212, + 46172815, 39271624, 32308042, 25436123, 18778046, 12454362, + 6550180, 1153222, -3690186, -7931022, -11549357, -14541771, + -16905259, -18670872, -19854696, -20504812, -20665306, -20388254, + -19735543, -18756855, -17510711, -16058137, -14452422, -12750215, + -10996406, -9230387, -7506048, -5841514, -4269596, -2815062, + -1498386, -320570, 699683, 1563959, 2280010, 2842827, + 3263548, 3556194, 3723649, 3782673, 3754077, 3639669, + 3463676, 3234034, 2965500, 2669406, 2362184, 2043555, + 1730398, 1426011, 1139067, 870062, 626287, 406552, + 214758, 52290, -81400, -192447, -276653, -339805, + -380854, -406690, -418638, -414054, -398956, -376437, + -345489, -315906, -280747, -249434, -213100, -176507, + -144467, -112761, -87348, -65472, -45559, -29659, + -17812, -6285, 5913, 11034, 14331, 17585, + 21840, 18597, 16523, 19606, 14800, 12216, + 13421, 8687, 9253, 5262, 7307, 4478, + 87, 917, 3655, 2959, -1190, -1801, + -2753, -174, -122, -410, -480, -795, + -1249, 1770, +}; + +static const int32_t fft_in_imag_512_q31[512] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, +}; + +static const int32_t fft_ref_real_512_q31[512] = { + -45, -91, 39, 13, 39, -12759, + 683966, -8435969, 44965977, -129224628, 221075980, -234823286, + 155575966, -62329239, 13936841, -1458185, 45393, -68, + -11, 94, 12, 28, -47, 61, + 89, -87, -33, 108, -49, -75, + -72, 76, -55, 53, 22, -71, + -24, 83, 42, -17, 71, 73, + 65, -2, 5, 63, -22, 0, + -22, 87, 31, -51, 42, -41, + -5, -51, 46, 32, -65, 92, + -3, 20, -36, -14, -131, -38, + 87, -49, 7, 6, 69, 9, + 26, -43, 11, -80, 145, -61, + 4, -4, -65, 76, 18, 25, + 118, -32, 8, 24, -76, 37, + -41, -23, 110, 126, -66, 55, + 12, -7, 119, -24, 29, -70, + 1, 42, -11, 118, 44, -5, + -28, -2, 33, -101, 36, -67, + 7, 19, -36, -15, 16, 16, + 30, 14, -41, -1, -6, -35, + -23, -50, 77, -11, 10, -28, + 102, 117, 41, 31, 39, 108, + 75, -68, -9, -6, 35, -69, + -52, 37, -81, 30, -76, -50, + 59, 0, 41, -24, 66, 61, + 6, -12, 28, 80, -68, 42, + 21, -62, 1, -103, -21, 7, + 46, 76, -48, 15, -76, 84, + 97, -35, 135, 18, 43, -20, + -22, 42, 54, 49, -48, -16, + -22, 18, -6, -76, 32, -80, + 25, 34, 8, 6, 9, 71, + -1, 97, -137, 52, -9, 0, + 2, 15, 19, -115, -40, 53, + 37, -22, -61, -72, -7, 4, + -41, 4, -44, -28, 16, -12, + -30, 17, 103, -24, 15, 41, + -25, -3, 15, -42, -73, 83, + -4, 49, 2, -96, 58, 85, + -11, -50, -24, -44, -75, -8, + 10, -23, 21, -26, 49, -50, + -40, 15, 87, -18, 58, -18, + 87, 15, -40, -50, 49, -26, + 21, -23, 10, -8, -75, -44, + -24, -50, -11, 85, 58, -96, + 2, 49, -4, 83, -73, -42, + 15, -3, -25, 41, 15, -24, + 103, 17, -30, -12, 16, -28, + -44, 4, -41, 4, -7, -72, + -61, -22, 37, 53, -40, -115, + 19, 15, 2, 0, -9, 52, + -137, 97, -1, 71, 9, 6, + 8, 34, 25, -80, 32, -76, + -6, 18, -22, -16, -48, 49, + 54, 42, -22, -20, 43, 18, + 135, -35, 97, 84, -76, 15, + -48, 76, 46, 7, -21, -103, + 1, -62, 21, 42, -68, 80, + 28, -12, 6, 61, 66, -24, + 41, 0, 59, -50, -76, 30, + -81, 37, -52, -69, 35, -6, + -9, -68, 75, 108, 39, 31, + 41, 117, 102, -28, 10, -11, + 77, -50, -23, -35, -6, -1, + -41, 14, 30, 16, 16, -15, + -36, 19, 7, -67, 36, -101, + 33, -2, -28, -5, 44, 118, + -11, 42, 1, -70, 29, -24, + 119, -7, 12, 55, -66, 126, + 110, -23, -41, 37, -76, 24, + 8, -32, 118, 25, 18, 76, + -65, -4, 4, -61, 145, -80, + 11, -43, 26, 9, 69, 6, + 7, -49, 87, -38, -131, -14, + -36, 20, -3, 92, -65, 32, + 46, -51, -5, -41, 42, -51, + 31, 87, -22, 0, -22, 63, + 5, -2, 65, 73, 71, -17, + 42, 83, -24, -71, 22, 53, + -55, 76, -72, -75, -49, 108, + -33, -87, 89, 61, -47, 28, + 12, 94, -11, -68, 45393, -1458185, + 13936841, -62329239, 155575966, -234823286, 221075980, -129224628, + 44965977, -8435969, 683966, -12759, 39, 13, + 39, -91, +}; + +static const int32_t fft_ref_imag_512_q31[512] = { + 0, 16, -60, 53, -58, -5240, + 284775, -3574190, 19378087, -56632327, 98507314, -106364728, + 71622799, -29159462, 6624575, -704027, 22181, -107, + 40, 52, 20, -56, -24, 12, + 16, -86, -125, 4, -12, 76, + -44, 24, 37, -11, 36, 32, + -10, 83, -45, 12, -22, 42, + -16, -11, 45, 41, 73, 29, + -59, 13, -10, -52, 9, -21, + -69, -51, -41, 13, -9, 102, + 4, 66, 62, -33, 113, -66, + -49, 36, -93, -52, -48, 49, + 56, 71, 1, 36, -56, -60, + -55, 36, -57, -130, 38, 51, + -69, 33, -49, -68, -10, 61, + 6, 29, 56, -41, -5, 18, + 65, 15, 71, 24, 27, -9, + 13, 19, 119, 52, -8, 26, + 60, -36, -5, 29, -25, -5, + -17, 3, 34, 21, -28, -92, + -21, -42, 28, 18, -95, 47, + 71, -4, -1, 47, -16, -27, + -25, 26, 16, 14, -92, 53, + -27, -14, 50, -23, 23, 87, + -45, 49, 156, -12, -49, 1, + 14, -22, -3, -33, -56, -39, + 24, -11, 74, -3, -36, -26, + -10, -5, 62, 48, -2, 58, + -111, 29, -20, 102, 104, -8, + -88, 41, 3, 24, 38, -40, + 79, -96, 11, 14, 23, -8, + 44, 26, -92, 14, 91, 9, + -74, -8, -40, 2, -99, -29, + -44, 10, -3, 49, -43, 11, + -66, -3, -1, 8, -2, 45, + 52, -39, 82, -32, -85, 55, + -59, -25, -58, -78, 34, 70, + -66, 104, -31, -5, 71, -56, + -25, -35, 37, 8, 18, 36, + 35, -15, 70, 86, 0, -54, + -65, -4, 45, 51, -101, 73, + 15, -27, 32, 32, 57, -22, + -3, -55, 46, -60, 0, 60, + -46, 55, 3, 22, -57, -32, + -32, 27, -15, -73, 101, -51, + -45, 4, 65, 54, 0, -86, + -70, 15, -35, -36, -18, -8, + -37, 35, 25, 56, -71, 5, + 31, -104, 66, -70, -34, 78, + 58, 25, 59, -55, 85, 32, + -82, 39, -52, -45, 2, -8, + 1, 3, 66, -11, 43, -49, + 3, -10, 44, 29, 99, -2, + 40, 8, 74, -9, -91, -14, + 92, -26, -44, 8, -23, -14, + -11, 96, -79, 40, -38, -24, + -3, -41, 88, 8, -104, -102, + 20, -29, 111, -58, 2, -48, + -62, 5, 10, 26, 36, 3, + -74, 11, -24, 39, 56, 33, + 3, 22, -14, -1, 49, 12, + -156, -49, 45, -87, -23, 23, + -50, 14, 27, -53, 92, -14, + -16, -26, 25, 27, 16, -47, + 1, 4, -71, -47, 95, -18, + -28, 42, 21, 92, 28, -21, + -34, -3, 17, 5, 25, -29, + 5, 36, -60, -26, 8, -52, + -119, -19, -13, 9, -27, -24, + -71, -15, -65, -18, 5, 41, + -56, -29, -6, -61, 10, 68, + 49, -33, 69, -51, -38, 130, + 57, -36, 55, 60, 56, -36, + -1, -71, -56, -49, 48, 52, + 93, -36, 49, 66, -113, 33, + -62, -66, -4, -102, 9, -13, + 41, 51, 69, 21, -9, 52, + 10, -13, 59, -29, -73, -41, + -45, 11, 16, -42, 22, -12, + 45, -83, 10, -32, -36, 11, + -37, -24, 44, -76, 12, -4, + 125, 86, -16, -12, 24, 56, + -20, -52, -40, 107, -22181, 704027, + -6624575, 29159462, -71622799, 106364728, -98507314, 56632327, + -19378087, 3574190, -284775, 5240, 58, -53, + 60, -16, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi_768_32.h b/test/cmocka/src/math/fft/ref_fft_multi_768_32.h new file mode 100644 index 000000000000..e2addddba223 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_768_32.h @@ -0,0 +1,532 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_768_NUM_TESTS 1 + +static const int32_t fft_in_real_768_q31[768] = { + -241, 3628, 1266, -2634, 3092, 232, + -640, -2125, -647, -471, 2119, 325, + 924, 1109, 2295, 142, 2343, 4363, + 2796, 852, 2382, 3248, 59, -164, + -472, -531, -1894, -3358, -6065, -6495, + -10815, -14044, -14091, -21234, -21055, -28456, + -27657, -28889, -31938, -37655, -37301, -39941, + -37891, -34378, -35403, -25561, -19647, -12509, + -606, 7543, 27322, 43905, 60616, 82045, + 106206, 131271, 155362, 177405, 206514, 230378, + 252852, 269899, 284703, 292311, 298400, 296951, + 287396, 266368, 239466, 199332, 153113, 89801, + 17743, -67554, -159603, -263913, -379403, -500228, + -624420, -747661, -878313, -1008009, -1123947, -1235504, + -1330305, -1415140, -1469543, -1503109, -1506498, -1472749, + -1404180, -1300722, -1150891, -953777, -717782, -430319, + -101128, 266708, 676619, 1119232, 1588541, 2080078, + 2582718, 3082395, 3581368, 4053897, 4495380, 4890271, + 5223260, 5483176, 5660980, 5732018, 5692000, 5528919, + 5231518, 4798517, 4214949, 3489048, 2614503, 1598896, + 445129, -831444, -2217322, -3689401, -5234758, -6824231, + -8425955, -10013777, -11546286, -12986974, -14303728, -15452171, + -16393147, -17098221, -17516838, -17627470, -17394452, -16795021, + -15807984, -14417914, -12622002, -10422907, -7825330, -4853484, + -1537434, 2089436, 5978600, 10075995, 14311269, 18609861, + 22892297, 27073727, 31067236, 34772158, 38090534, 40934898, + 43202133, 44813294, 45679346, 45731324, 44905126, 43149410, + 40438048, 36750358, 32085432, 26463085, 19925175, 12540171, + 4381317, -4438039, -13790945, -23543065, -33528565, -43564061, + -53465445, -63029646, -72045718, -80312846, -87610680, -93744955, + -98520554, -101753835, -103280411, -102966601, -100709277, -96415613, + -90045652, -81592422, -71092553, -58618157, -44282598, -28246494, + -10713843, 8066777, 27824234, 48231529, 68946383, 89591059, + 109773996, 129088677, 147128854, 163468860, 177716203, 189481150, + 198414424, 204188194, 206522572, 205187796, 200015913, 190891669, + 177791058, 160736722, 139852452, 115319077, 87417331, 56488140, + 22961781, -12682422, -49874998, -88011035, -126426119, -164419626, + -201273383, -236244280, -268603859, -297627612, -322626893, -342948091, + -358004727, -367277860, -370342769, -366852815, -356581652, -339422399, + -315383357, -284601000, -247362998, -204058953, -155232745, -101548024, + -43766850, 17205216, 80403869, 144751837, 209130532, 272363524, + 333253552, 390604777, 443225021, 489983715, 529796603, 561679037, + 584753366, 598271174, 601626791, 594389174, 576296927, 547288978, + 507501344, 457258651, 397112676, 327797845, 250251097, 165585699, + 75093904, -19793649, -117512265, -216400732, -314702204, -410646381, + -502420161, -588236711, -666381398, -735199970, -793172141, -838922144, + -871263019, -889212884, -892024318, -879199280, -850513416, -806023413, + -746080576, -671318723, -582662836, -481304796, -368721547, -246617566, + -116917087, 18270872, 156674321, 295907377, 433516862, 567002905, + 693899018, 811767777, 918300703, 1011331647, 1088889407, 1149227101, + 1190877755, 1212675673, 1213778899, 1193712929, 1152364866, 1090009355, + 1007296111, 905266409, 785326540, 649219884, 499038860, 337158886, + 166206194, -10961531, -191342499, -371803627, -549163002, -720223486, + -881850257, -1031031431, -1164911846, -1280868241, -1376550015, -1449939386, + -1499367541, -1523583693, -1521766543, -1493533215, -1438987495, -1358687436, + -1253679050, -1125438417, -975903567, -807401765, -622633116, -424638658, + -216716665, -2389257, 214658063, 430646136, 641770661, 844277440, + 1034504073, 1208988113, 1364494665, 1498093914, 1607219524, 1689717041, + 1743869703, 1768468592, 1762801849, 1726698298, 1660522023, 1565178648, + 1442100556, 1293212702, 1120923589, 928071098, 717883328, 493909272, + 259976392, 20109529, -221543570, -460775430, -693380588, -915279395, + -1122535646, -1311465176, -1478694764, -1621202263, -1736420964, -1822228493, + -1877035711, -1899782713, -1889981357, -1847719295, -1773655476, -1669011369, + -1535556633, -1375568847, -1191799200, -987421289, -765980565, -531317241, + -287522473, -38826774, 210438051, 455926599, 693378607, 918668739, + 1127898672, 1317450221, 1484066329, 1624902389, 1737561435, 1820169914, + 1871370256, 1890370085, 1876956318, 1831481264, 1754859942, 1648550469, + 1514537726, 1355269389, 1173649163, 972947096, 756747847, 528901760, + 293423150, 54461413, -183819750, -417285653, -641919290, -853887630, + -1049609077, -1225812585, -1379604726, -1508498680, -1610479734, -1684014303, + -1728095431, -1742222985, -1726455301, -1681364668, -1608026287, -1508012075, + -1383349677, -1236465382, -1070165680, -887555137, -691989929, -487024198, + -276323896, -63620915, 147368778, 353015035, 549823704, 734499919, + 904012813, 1055637525, 1186997279, 1296126973, 1381461577, 1441882934, + 1476731983, 1485810836, 1469378480, 1428137473, 1363206291, 1276124718, + 1168776500, 1043382186, 902429921, 748648315, 584934734, 414320933, + 239889131, 64740645, -108075141, -275595744, -435033737, -583772214, + -719463613, -840011127, -943642758, -1028922523, -1094765960, -1140450717, + -1165628503, -1170317758, -1154910358, -1120124363, -1067022676, -996950501, + -911527447, -812600545, -702233328, -582607456, -456037458, -324903799, + -191587971, -58477754, 72134075, 198026348, 317140968, 427596570, + 527697948, 615989474, 691267140, 752573081, 799243835, 830886626, + 847377376, 848875628, 835788248, 808780118, 768740386, 716762333, + 654109652, 582210084, 502593426, 416905102, 326822356, 234056696, + 140318147, 47264446, -43493550, -130454209, -212221899, -287551695, + -355341753, -414661156, -464781140, -505142479, -535375283, -555326382, + -564998467, -564605784, -554520170, -535277315, -507545850, -472137486, + -429952101, -381993665, -329320813, -273037272, -214275690, -154161305, + -93793908, -34261274, 23446178, 78376049, 129678588, 176604769, + 218510346, 254869838, 285274876, 309446449, 327216576, 338561446, + 343550216, 342374595, 335330281, 322798847, 305241328, 283205569, + 257276138, 228087926, 196306163, 162614199, 127698298, 92230529, + 56859824, 22218011, -11122306, -42635429, -71849428, -98358438, + -121834503, -141999690, -158667712, -171721547, -181107624, -186849406, + -189032211, -187801396, -183357131, -175951701, -165863098, -153423152, + -138980699, -122894992, -105545878, -87314275, -68566012, -49677861, + -30984026, -12814682, 4531458, 20798958, 35753250, 49203321, + 60992344, 71008612, 79174265, 85454460, 89847498, 92383097, + 93135114, 92195760, 89684369, 85748781, 80536599, 74229321, + 67008217, 59067898, 50589678, 41764861, 32780594, 23799570, + 14993219, 6509774, -1519081, -8981737, -15771145, -21811536, + -27053959, -31440950, -34961449, -37604251, -39392286, -40339728, + -40496531, -39917823, -38657779, -36799506, -34411495, -31574572, + -28386220, -24923452, -21270576, -17508795, -13717544, -9974397, + -6333739, -2866681, 384131, 3368107, 6055198, 8416649, + 10434463, 12091696, 13399827, 14352349, 14958192, 15241456, + 15221308, 14925295, 14374955, 13608579, 12654643, 11552968, + 10327766, 9020876, 7661805, 6278839, 4907365, 3564212, + 2278189, 1064063, -56710, -1068964, -1969870, -2748235, + -3400263, -3926939, -4334024, -4613344, -4777385, -4836237, + -4799867, -4673215, -4466130, -4199935, -3874971, -3511593, + -3118446, -2704701, -2280034, -1857999, -1445532, -1048462, + -672536, -324455, -6582, 276892, 520368, 728589, + 897649, 1032019, 1126293, 1192973, 1228285, 1231327, + 1206481, 1161397, 1102233, 1026682, 938355, 843020, + 739097, 631951, 530386, 428349, 326932, 240431, + 154170, 73476, 6017, -55869, -103578, -144953, + -178246, -202681, -221485, -230703, -235306, -226956, + -222383, -208635, -196477, -178217, -164594, -144650, + -125017, -105575, -87630, -67991, -51183, -39259, + -23108, -11134, 1244, 9731, 12825, 20491, + 23334, 24167, 26047, 27043, 28682, 26990, + 26946, 22875, 20894, 17822, 18266, 15434, + 12288, 11757, 9451, 4447, 6333, 2560, + 3081, 1489, 1911, 2215, -1287, 197, + 1072, -1622, -3627, -2827, -1107, -1453, + -1069, -4722, 633, 1036, -3478, -2766, + 990, -1236, 1683, -3486, 3291, -2011, +}; + +static const int32_t fft_in_imag_768_q31[768] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; + +static const int32_t fft_ref_real_768_q31[768] = { + 45, 20, -33, 47, 30, -4, + -56, -17, 21, -19, -368, 43718, + -759260, 5010913, -16911518, 33136889, -39906332, 30002948, + -13815282, 3661837, -487124, 23450, -78, 55, + 58, 54, -44, -50, 69, 7, + -8, 3, 9, 37, -38, 92, + 6, 75, 74, -35, 16, -23, + -30, 7, 60, -2, 33, -28, + 35, 5, -27, 48, -6, 36, + 74, 49, 3, -36, -82, -71, + -17, 44, 13, 9, 1, 0, + 15, 116, 24, 13, -22, -83, + -43, -23, 52, -7, -32, 26, + 77, 12, -9, 61, -27, 64, + 14, -20, 0, 28, 38, -32, + -48, 27, -35, -15, -25, -29, + -33, -64, 12, 25, -34, -17, + -26, 62, 57, 47, -53, 45, + 36, -75, -50, -100, -53, 1, + -23, 12, -27, 126, -25, 11, + -13, -23, -54, 30, -8, -4, + 74, 33, -26, -18, 45, -4, + -28, -84, 42, 19, 2, -15, + -27, 27, 42, -49, 68, -51, + 17, 77, -46, 58, 6, 15, + -72, 32, -8, 97, 1, 21, + 47, -67, -98, 1, 6, 16, + 13, 10, 65, 83, -7, 58, + 34, 29, 33, -47, 53, 8, + -33, 25, -34, 61, -22, -34, + 37, 45, 52, 32, 36, 32, + -29, -13, 53, 46, -110, -40, + -76, 32, -18, -32, -46, -5, + 8, -22, -73, -49, -23, -39, + 6, -27, -34, -56, -42, -34, + -24, -18, 48, -19, -12, 115, + -23, 45, -22, -81, -65, 13, + 42, 28, -15, 43, 9, -18, + -98, -21, 4, 21, 37, -35, + -14, -14, 20, -37, -62, 66, + 10, -1, -26, 1, 35, 2, + -25, -91, -9, 26, 23, -39, + 9, 5, -27, 21, -24, 21, + 12, -26, -71, -17, 26, -31, + -23, 1, 107, -94, -17, 12, + -30, -53, 62, 28, 0, 55, + -109, -29, -79, -80, -53, -30, + -61, -57, -47, 59, -44, -19, + 30, 48, -43, 42, -15, 11, + 1, -23, -38, -12, -47, -30, + -50, -3, -20, -20, 68, -42, + -1, -15, 16, -33, 4, -23, + -59, -24, -39, 5, -34, 67, + -40, 14, 105, 41, -40, 38, + -12, -34, 34, 16, -21, 68, + -42, -32, -32, -12, 8, -58, + 29, 2, 39, 76, 57, 35, + -26, -18, -70, -14, 20, -37, + 23, 18, -47, -72, 69, -24, + -6, 41, -1, 8, 25, -41, + -5, 58, 71, 72, -40, 50, + 32, -28, 55, 50, -52, -27, + 44, 38, -23, 18, 38, 9, + 53, -26, 45, 79, -17, 110, + 32, 110, -17, 79, 45, -26, + 53, 9, 38, 18, -23, 38, + 44, -27, -52, 50, 55, -28, + 32, 50, -40, 72, 71, 58, + -5, -41, 25, 8, -1, 41, + -6, -24, 69, -72, -47, 18, + 23, -37, 20, -14, -70, -18, + -26, 35, 57, 76, 39, 2, + 29, -58, 8, -12, -32, -32, + -42, 68, -21, 16, 34, -34, + -12, 38, -40, 41, 105, 14, + -40, 67, -34, 5, -39, -24, + -59, -23, 4, -33, 16, -15, + -1, -42, 68, -20, -20, -3, + -50, -30, -47, -12, -38, -23, + 1, 11, -15, 42, -43, 48, + 30, -19, -44, 59, -47, -57, + -61, -30, -53, -80, -79, -29, + -109, 55, 0, 28, 62, -53, + -30, 12, -17, -94, 107, 1, + -23, -31, 26, -17, -71, -26, + 12, 21, -24, 21, -27, 5, + 9, -39, 23, 26, -9, -91, + -25, 2, 35, 1, -26, -1, + 10, 66, -62, -37, 20, -14, + -14, -35, 37, 21, 4, -21, + -98, -18, 9, 43, -15, 28, + 42, 13, -65, -81, -22, 45, + -23, 115, -12, -19, 48, -18, + -24, -34, -42, -56, -34, -27, + 6, -39, -23, -49, -73, -22, + 8, -5, -46, -32, -18, 32, + -76, -40, -110, 46, 53, -13, + -29, 32, 36, 32, 52, 45, + 37, -34, -22, 61, -34, 25, + -33, 8, 53, -47, 33, 29, + 34, 58, -7, 83, 65, 10, + 13, 16, 6, 1, -98, -67, + 47, 21, 1, 97, -8, 32, + -72, 15, 6, 58, -46, 77, + 17, -51, 68, -49, 42, 27, + -27, -15, 2, 19, 42, -84, + -28, -4, 45, -18, -26, 33, + 74, -4, -8, 30, -54, -23, + -13, 11, -25, 126, -27, 12, + -23, 1, -53, -100, -50, -75, + 36, 45, -53, 47, 57, 62, + -26, -17, -34, 25, 12, -64, + -33, -29, -25, -15, -35, 27, + -48, -32, 38, 28, 0, -20, + 14, 64, -27, 61, -9, 12, + 77, 26, -32, -7, 52, -23, + -43, -83, -22, 13, 24, 116, + 15, 0, 1, 9, 13, 44, + -17, -71, -82, -36, 3, 49, + 74, 36, -6, 48, -27, 5, + 35, -28, 33, -2, 60, 7, + -30, -23, 16, -35, 74, 75, + 6, 92, -38, 37, 9, 3, + -8, 7, 69, -50, -44, 54, + 58, 55, -78, 23450, -487124, 3661837, + -13815282, 30002948, -39906332, 33136889, -16911518, 5010913, + -759260, 43718, -368, -19, 21, -17, + -56, -4, 30, 47, -33, 20, +}; + +static const int32_t fft_ref_imag_768_q31[768] = { + 0, -32, -5, 26, 5, 43, + -33, 33, 46, -24, -1903, 252986, + -4504301, 30493677, -105611719, 212501965, -262975509, 203317701, + -96347654, 26303114, -3606843, 179333, -945, -2, + -33, -11, -91, -18, -5, -11, + -4, 11, 43, -17, 26, 49, + 13, -31, -13, 4, 27, -2, + -1, 66, -18, -35, 34, -14, + 37, -68, 47, 2, -33, 36, + -10, 44, -5, -19, 8, -19, + -26, -44, 65, -29, -73, -29, + -22, -24, 11, -29, 13, -44, + -26, 44, 76, -44, -30, 26, + 3, -45, -18, 105, -113, 82, + -11, 57, -5, -54, -10, -36, + 0, 11, -10, 40, -33, -29, + 7, 34, -19, -11, -114, 57, + 18, 26, -81, -58, 9, -19, + 0, 92, 77, -34, -14, -76, + 35, -55, -9, 43, 7, 2, + 46, -51, 39, -57, 57, -96, + 9, 36, -6, 91, 12, -133, + -27, 38, 14, 52, 16, 12, + 16, -36, 43, -9, -23, 22, + 31, -5, -90, -25, -34, 61, + -49, 22, -56, 26, 39, -25, + -23, -69, -17, -49, 33, -10, + -86, 125, 10, -22, 62, -77, + -28, -96, -11, 68, 17, -26, + 69, 29, -16, -43, 29, 16, + 71, -13, -4, 26, 51, 21, + -43, -28, -30, -55, 26, 19, + 33, -7, -21, 9, -17, -38, + -41, -34, -14, 14, 6, -43, + -27, 70, 30, -53, -31, -11, + -24, -4, -27, 0, -31, -71, + -4, -17, 44, 29, 18, -32, + -11, -15, -12, -2, 2, -24, + -43, 9, -103, 54, -39, -80, + 41, -118, 17, -16, -35, -76, + 11, -34, -9, -58, -18, -20, + 54, 28, 23, -38, -47, -15, + 7, -104, 11, 59, 29, 37, + -29, -37, 16, 0, -4, 26, + 27, -40, 38, 58, -55, 2, + 42, 21, -51, 47, -5, -77, + -1, -29, 63, 14, 30, -35, + -73, 1, 13, 8, 65, -17, + -2, -21, -66, 87, -17, -134, + 9, -66, -11, 66, -27, -28, + 12, 31, -24, 0, -61, 14, + 58, 20, -46, -17, -14, -14, + -12, -47, 12, -63, 27, -21, + 33, -78, 1, 16, -25, -48, + -41, -96, 137, -59, 4, 18, + 43, 32, -33, -21, -13, 16, + 71, -39, -46, 33, 5, -7, + -11, -19, -13, -16, -59, 45, + -26, -24, -70, -39, 2, 12, + 70, 43, -58, 32, 34, -40, + 44, -32, -28, -26, 23, -7, + 64, -63, 24, 37, -17, 7, + -1, 0, -59, -16, 5, -77, + -16, 51, 19, 44, 16, 62, + 0, -62, -16, -44, -19, -51, + 16, 77, -5, 16, 59, 0, + 1, -7, 17, -37, -24, 63, + -64, 7, -23, 26, 28, 32, + -44, 40, -34, -32, 58, -43, + -70, -12, -2, 39, 70, 24, + 26, -45, 59, 16, 13, 19, + 11, 7, -5, -33, 46, 39, + -71, -16, 13, 21, 33, -32, + -43, -18, -4, 59, -137, 96, + 41, 48, 25, -16, -1, 78, + -33, 21, -27, 63, -12, 47, + 12, 14, 14, 17, 46, -20, + -58, -14, 61, 0, 24, -31, + -12, 28, 27, -66, 11, 66, + -9, 134, 17, -87, 66, 21, + 2, 17, -65, -8, -13, -1, + 73, 35, -30, -14, -63, 29, + 1, 77, 5, -47, 51, -21, + -42, -2, 55, -58, -38, 40, + -27, -26, 4, 0, -16, 37, + 29, -37, -29, -59, -11, 104, + -7, 15, 47, 38, -23, -28, + -54, 20, 18, 58, 9, 34, + -11, 76, 35, 16, -17, 118, + -41, 80, 39, -54, 103, -9, + 43, 24, -2, 2, 12, 15, + 11, 32, -18, -29, -44, 17, + 4, 71, 31, 0, 27, 4, + 24, 11, 31, 53, -30, -70, + 27, 43, -6, -14, 14, 34, + 41, 38, 17, -9, 21, 7, + -33, -19, -26, 55, 30, 28, + 43, -21, -51, -26, 4, 13, + -71, -16, -29, 43, 16, -29, + -69, 26, -17, -68, 11, 96, + 28, 77, -62, 22, -10, -125, + 86, 10, -33, 49, 17, 69, + 23, 25, -39, -26, 56, -22, + 49, -61, 34, 25, 90, 5, + -31, -22, 23, 9, -43, 36, + -16, -12, -16, -52, -14, -38, + 27, 133, -12, -91, 6, -36, + -9, 96, -57, 57, -39, 51, + -46, -2, -7, -43, 9, 55, + -35, 76, 14, 34, -77, -92, + 0, 19, -9, 58, 81, -26, + -18, -57, 114, 11, 19, -34, + -7, 29, 33, -40, 10, -11, + 0, 36, 10, 54, 5, -57, + 11, -82, 113, -105, 18, 45, + -3, -26, 30, 44, -76, -44, + 26, 44, -13, 29, -11, 24, + 22, 29, 73, 29, -65, 44, + 26, 19, -8, 19, 5, -44, + 10, -36, 33, -2, -47, 68, + -37, 14, -34, 35, 18, -66, + 1, 2, -27, -4, 13, 31, + -13, -49, -26, 17, -43, -11, + 4, 11, 5, 18, 91, 11, + 33, 2, 945, -179333, 3606843, -26303114, + 96347654, -203317701, 262975509, -212501965, 105611719, -30493677, + 4504301, -252986, 1903, 24, -46, -33, + 33, -43, -5, -26, 5, 32, +}; diff --git a/test/cmocka/src/math/fft/ref_fft_multi_96_32.h b/test/cmocka/src/math/fft/ref_fft_multi_96_32.h new file mode 100644 index 000000000000..48ed4c1e7ae1 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_fft_multi_96_32.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_FFT_MULTI_96_NUM_TESTS 1 + +static const int32_t fft_in_real_96_q31[96] = { + 2612, -585, 740, 1771, 10242, 28387, + 67673, 150357, 305252, 583434, 1049075, 1773977, + 2866391, 4421878, 6535194, 9264176, 12595638, 16410151, + 20420570, 24132226, 26792322, 27353105, 24457934, 16442487, + 1411524, -22682595, -57886075, -106071598, -168720146, -246662584, + -339873057, -447258396, -566496507, -693969722, -824813628, -953046420, + -1071834144, -1173876250, -1251869944, -1299031192, -1309635449, -1279509181, + -1206486132, -1090677103, -934610659, -743214358, -523566965, -284489188, + -36038274, 211200645, 446740932, 660913160, 845461777, 994029750, + 1102498010, 1169119233, 1194490190, 1181384510, 1134337335, 1059242451, + 962836599, 852157942, 734074206, 614854055, 499863929, 393334033, + 298286546, 216528461, 148768326, 94769100, 53566286, 23675203, + 3333228, -9343610, -16164205, -18786637, -18606500, -16758603, + -14096842, -11214929, -8500848, -6156283, -4266830, -2826418, + -1788630, -1079523, -614752, -331493, -166234, -76988, + -33171, -13273, -4796, -1383, 2439, 1203, +}; + +static const int32_t fft_in_imag_96_q31[96] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; + +static const int32_t fft_ref_real_96_q31[96] = { + -17402140, 14269492, -5584270, -2890773, 4789231, -2333890, + 486956, -35699, 330, 13, 164, 145, + 68, -18, -52, -121, 151, 206, + -21, -66, -30, 131, 0, 78, + -307, 162, -16, -184, 174, -39, + 140, -48, 32, -31, -199, 139, + -187, 137, -72, 272, 156, -11, + -74, 3, 49, 154, -109, 172, + 81, 172, -109, 154, 49, 3, + -74, -11, 156, 272, -72, 137, + -187, 139, -199, -31, 32, -48, + 140, -39, 174, -184, -16, 162, + -307, 78, 0, 131, -30, -66, + -21, 206, 151, -121, -52, -18, + 68, 145, 164, 13, 330, -35699, + 486956, -2333890, 4789231, -2890773, -5584270, 14269492, +}; + +static const int32_t fft_ref_imag_96_q31[96] = { + 0, 179914066, -259234323, 208477801, -102275624, 29288094, + -4318694, 244372, -1937, 98, -53, 13, + -18, 191, 43, 145, 120, 116, + -14, 54, 22, -22, -73, -99, + 113, 41, 26, -65, 99, -120, + -16, 69, -52, -74, 73, -70, + 85, -46, 106, -107, 55, -3, + 13, -45, -98, 68, 77, -85, + 0, 85, -77, -68, 98, 45, + -13, 3, -55, 107, -106, 46, + -85, 70, -73, 74, 52, -69, + 16, 120, -99, 65, -26, -41, + -113, 99, 73, 22, -22, -54, + 14, -116, -120, -145, -43, -191, + 18, -13, 53, -98, 1937, -244372, + 4318694, -29288094, 102275624, -208477801, 259234323, -179914066, +}; diff --git a/test/cmocka/src/math/fft/ref_ifft_multi_1024_32.h b/test/cmocka/src/math/fft/ref_ifft_multi_1024_32.h new file mode 100644 index 000000000000..f9d39f509c2e --- /dev/null +++ b/test/cmocka/src/math/fft/ref_ifft_multi_1024_32.h @@ -0,0 +1,704 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_IFFT_MULTI_1024_NUM_TESTS 1 + +static const int32_t ifft_in_real_1024_q31[1024] = { + -25, -79, 39, 48, -13, -34, + -8, -8, -21, -23, 43, -46, + -62, -24, -39, 10, -55147, 1535442, + -13543809, 57130805, -135763817, 195823576, -176199328, 98119764, + -32279401, 5635577, -409793, 5971, 1, 4, + 86, 8, -39, -22, 43, 34, + 22, -65, -65, 9, 49, 17, + 54, 42, -41, 100, 11, -49, + 26, 19, -36, 4, -26, 25, + -30, 19, 27, -30, 78, -61, + -71, 7, 2, 33, 51, -3, + 29, 17, 7, 0, -28, 45, + 17, -31, -72, 44, 14, -9, + 38, 11, 35, 10, 68, 34, + -3, 6, 19, 16, 45, -35, + 48, 21, 28, 27, 18, 41, + 5, 35, -2, -5, -69, 14, + -6, 45, 22, 19, 55, 14, + 13, 40, 5, 4, 11, -30, + 59, 18, 94, 41, -92, 27, + -3, -2, 50, 35, -24, 27, + 44, -40, 35, -28, 49, -30, + -3, 11, -54, -28, 6, 45, + -21, 63, -10, -10, -8, -2, + 24, 10, 50, 4, 21, -29, + -10, 39, -61, 16, -28, -29, + -58, 37, 38, -34, 19, -72, + -30, 9, 45, -36, 32, 23, + 38, 59, -59, -23, -31, -60, + 23, -11, 12, -15, -32, 36, + 15, 48, -39, -33, 81, -58, + -2, -73, 50, -70, 19, 8, + 45, -18, -22, 40, -8, 23, + 18, 42, 18, 80, 38, -1, + 7, -4, 3, 23, 23, -59, + -4, 21, -45, -26, 49, -17, + 61, -16, -17, 32, -8, -13, + 32, 77, -72, 50, -6, 9, + 51, 21, -35, -95, -32, -6, + 26, 17, 4, -56, 0, -94, + 3, -5, 3, 7, -57, -44, + -29, -18, 29, -92, -25, -93, + 41, 4, 5, -38, -1, -64, + -81, -63, -21, -41, -51, 41, + -59, -1, 68, -14, 40, -62, + 47, 73, 9, 25, 57, -18, + 15, -25, -39, -49, 1, 11, + 37, -28, 42, -52, 45, 5, + 47, -40, -10, -8, 45, -1, + -28, -33, 63, -44, 38, 15, + 15, -48, 45, -51, -28, -87, + 7, 10, -63, 25, 29, 48, + -1, -36, 10, -44, 41, 33, + 9, 32, -15, -40, -86, 12, + -84, 34, 46, -12, -5, 54, + -19, -8, -46, -26, -4, -57, + -44, -11, -7, -19, 10, -30, + -1, 39, 9, -17, -22, 35, + -14, -7, 5, -41, 27, -2, + -21, 33, 47, 20, 66, 1, + 23, -54, -4, -34, 2, 33, + 56, -7, 26, 11, 20, -30, + -66, -30, -20, 18, 72, -24, + -37, -20, -70, -21, -48, 64, + -45, 15, -46, 19, -41, -8, + -38, 17, -14, -27, 5, -72, + 34, 36, 29, -5, -11, 24, + -10, 26, -16, 30, 22, -18, + 37, 31, -14, 42, -14, -17, + -10, 29, -14, -80, -2, 26, + -10, -21, -87, 20, 76, 1, + 28, -11, 81, 44, 18, -9, + 12, 53, 40, 14, 8, 18, + 4, -3, -19, -4, -15, -8, + 19, -18, -12, -34, 10, -29, + -56, -10, -18, -59, 45, 19, + 12, 25, -4, 12, 34, -27, + 0, 1, 29, -16, 14, 7, + -41, 15, 26, -21, 24, -30, + -9, -24, 26, 14, 76, 0, + 76, 4, -32, 91, -21, -31, + -6, 8, -45, 21, 69, 44, + -9, 0, -7, -27, -14, 14, + -3, -6, 44, -4, 7, -35, + -40, 32, -18, -17, -40, -21, + -17, 51, 31, 51, -17, -21, + -40, -17, -18, 32, -40, -35, + 7, -4, 44, -6, -3, 14, + -14, -27, -7, 0, -9, 44, + 69, 21, -45, 8, -6, -31, + -21, 91, -32, 4, 76, 0, + 76, 14, 26, -24, -9, -30, + 24, -21, 26, 15, -41, 7, + 14, -16, 29, 1, 0, -27, + 34, 12, -4, 25, 12, 19, + 45, -59, -18, -10, -56, -29, + 10, -34, -12, -18, 19, -8, + -15, -4, -19, -3, 4, 18, + 8, 14, 40, 53, 12, -9, + 18, 44, 81, -11, 28, 1, + 76, 20, -87, -21, -10, 26, + -2, -80, -14, 29, -10, -17, + -14, 42, -14, 31, 37, -18, + 22, 30, -16, 26, -10, 24, + -11, -5, 29, 36, 34, -72, + 5, -27, -14, 17, -38, -8, + -41, 19, -46, 15, -45, 64, + -48, -21, -70, -20, -37, -24, + 72, 18, -20, -30, -66, -30, + 20, 11, 26, -7, 56, 33, + 2, -34, -4, -54, 23, 1, + 66, 20, 47, 33, -21, -2, + 27, -41, 5, -7, -14, 35, + -22, -17, 9, 39, -1, -30, + 10, -19, -7, -11, -44, -57, + -4, -26, -46, -8, -19, 54, + -5, -12, 46, 34, -84, 12, + -86, -40, -15, 32, 9, 33, + 41, -44, 10, -36, -1, 48, + 29, 25, -63, 10, 7, -87, + -28, -51, 45, -48, 15, 15, + 38, -44, 63, -33, -28, -1, + 45, -8, -10, -40, 47, 5, + 45, -52, 42, -28, 37, 11, + 1, -49, -39, -25, 15, -18, + 57, 25, 9, 73, 47, -62, + 40, -14, 68, -1, -59, 41, + -51, -41, -21, -63, -81, -64, + -1, -38, 5, 4, 41, -93, + -25, -92, 29, -18, -29, -44, + -57, 7, 3, -5, 3, -94, + 0, -56, 4, 17, 26, -6, + -32, -95, -35, 21, 51, 9, + -6, 50, -72, 77, 32, -13, + -8, 32, -17, -16, 61, -17, + 49, -26, -45, 21, -4, -59, + 23, 23, 3, -4, 7, -1, + 38, 80, 18, 42, 18, 23, + -8, 40, -22, -18, 45, 8, + 19, -70, 50, -73, -2, -58, + 81, -33, -39, 48, 15, 36, + -32, -15, 12, -11, 23, -60, + -31, -23, -59, 59, 38, 23, + 32, -36, 45, 9, -30, -72, + 19, -34, 38, 37, -58, -29, + -28, 16, -61, 39, -10, -29, + 21, 4, 50, 10, 24, -2, + -8, -10, -10, 63, -21, 45, + 6, -28, -54, 11, -3, -30, + 49, -28, 35, -40, 44, 27, + -24, 35, 50, -2, -3, 27, + -92, 41, 94, 18, 59, -30, + 11, 4, 5, 40, 13, 14, + 55, 19, 22, 45, -6, 14, + -69, -5, -2, 35, 5, 41, + 18, 27, 28, 21, 48, -35, + 45, 16, 19, 6, -3, 34, + 68, 10, 35, 11, 38, -9, + 14, 44, -72, -31, 17, 45, + -28, 0, 7, 17, 29, -3, + 51, 33, 2, 7, -71, -61, + 78, -30, 27, 19, -30, 25, + -26, 4, -36, 19, 26, -49, + 11, 100, -41, 42, 54, 17, + 49, 9, -65, -65, 22, 34, + 43, -22, -39, 8, 86, 4, + 1, 5971, -409793, 5635577, -32279401, 98119764, + -176199328, 195823576, -135763817, 57130805, -13543809, 1535442, + -55147, 10, -39, -24, -62, -46, + 43, -23, -21, -8, -8, -34, + -13, 48, 39, -79, +}; + +static const int32_t ifft_in_imag_1024_q31[1024] = { + 0, -83, 39, 95, 15, 7, + -35, 3, -6, -13, 35, 57, + 28, 60, -67, -79, 50487, -1395762, + 12235510, -51294609, 121144602, -173660953, 155294502, -85945073, + 28099679, -4875536, 352396, -5166, 26, -2, + -73, -42, 38, 16, 22, -70, + 59, -3, -20, 45, 5, -16, + 10, 11, 20, -37, -43, -13, + 25, -25, 28, 39, -27, -7, + 46, -10, 59, 84, 14, -82, + 2, 13, 16, -54, 84, 0, + 50, -8, 13, 59, -28, -33, + 81, -5, 42, -22, -37, -7, + -40, -26, -32, -90, 2, 60, + 17, 38, 19, -58, 29, 17, + 38, 31, -21, -77, -3, 43, + -27, 23, 10, 20, -35, 3, + 13, 16, 22, 36, -42, 0, + 5, 4, -38, 51, -37, -83, + 10, -7, -9, 2, -83, -99, + 7, -10, -32, -40, 26, -8, + 16, 62, -15, 28, -21, 111, + 17, 8, 71, 64, -25, 24, + -18, -18, 36, -2, 2, 42, + -4, -32, 19, -76, 28, -83, + 57, -12, -26, -11, -3, -17, + 51, -36, 33, -66, -1, -28, + 16, -7, -62, 24, -47, -23, + -18, -22, 80, -15, -86, 46, + 59, 11, -11, -20, -23, 35, + -5, 16, 29, -15, -20, -53, + 99, 58, -10, 34, 28, -13, + 23, 10, -42, -61, 52, 31, + -5, 9, 0, -50, -56, -47, + 13, 1, -22, -1, -48, 8, + -2, 34, -26, 39, -54, -9, + -9, -30, 15, 6, 46, -36, + -55, 24, 15, 1, -33, 7, + 0, 23, -19, 35, -15, 43, + 83, -21, -32, -11, -44, -1, + 81, 16, -34, 14, -39, -11, + -65, -17, -9, 42, -10, -4, + 24, -34, -15, -9, -15, -10, + -26, 20, 28, 0, -5, -46, + 7, -71, -48, -35, 1, -4, + 120, -22, 4, 1, -37, -2, + -35, -30, 67, -55, -40, -3, + -104, -17, 24, -2, 22, 44, + -32, -34, 11, 58, 10, -21, + 25, 13, 86, 12, -70, -14, + -26, -40, 3, 28, 26, -36, + 12, 32, -15, 10, 52, 40, + -4, 59, 13, -32, -23, -21, + 2, -54, 28, -27, -12, 14, + 69, -74, 0, 42, -32, 16, + 24, -10, 32, -10, 19, -8, + -14, -3, 50, 6, -33, -56, + 40, 6, -39, -29, 18, 7, + 40, -35, -39, 96, -32, 71, + 63, -32, 1, 49, -75, 60, + -56, 7, -51, -9, -30, 11, + 4, -54, 24, 55, -1, 87, + 56, -55, -4, 27, -20, -92, + -29, 49, 15, -32, 9, -32, + 53, 16, 40, -20, 29, 19, + 31, 21, 37, 19, -40, 76, + 25, 49, -8, 10, 26, 61, + -29, 24, 59, -34, 71, -43, + 42, -16, -5, 4, 4, -56, + -18, -56, 9, 30, -26, 1, + -71, 21, 86, -3, -58, 7, + 80, -38, -10, -16, -2, 18, + -14, -3, 15, 27, -17, -67, + -15, 41, -13, 6, 13, 24, + -25, 39, -24, -12, 16, -14, + 23, 26, 10, 53, -49, -49, + -38, 6, 31, -30, -5, -16, + 16, -14, -31, 60, -42, -7, + 66, 52, 16, -12, -36, -9, + -60, -21, 63, -40, -47, -4, + -73, 16, 75, -46, -41, -12, + -19, -48, 5, -22, 19, 14, + 56, 42, -23, -11, 29, -17, + -68, -31, -19, -4, -46, 16, + 55, 23, 22, -15, -9, -7, + -31, -26, 0, 26, 31, 7, + 9, 15, -22, -23, -55, -16, + 46, 4, 19, 31, 68, 17, + -29, 11, 23, -42, -56, -14, + -19, 22, -5, 48, 19, 12, + 41, 46, -75, -16, 73, 4, + 47, 40, -63, 21, 60, 9, + 36, 12, -16, -52, -66, 7, + 42, -60, 31, 14, -16, 16, + 5, 30, -31, -6, 38, 49, + 49, -53, -10, -26, -23, 14, + -16, 12, 24, -39, 25, -24, + -13, -6, 13, -41, 15, 67, + 17, -27, -15, 3, 14, -18, + 2, 16, 10, 38, -80, -7, + 58, 3, -86, -21, 71, -1, + 26, -30, -9, 56, 18, 56, + -4, -4, 5, 16, -42, 43, + -71, 34, -59, -24, 29, -61, + -26, -10, 8, -49, -25, -76, + 40, -19, -37, -21, -31, -19, + -29, 20, -40, -16, -53, 32, + -9, 32, -15, -49, 29, 92, + 20, -27, 4, 55, -56, -87, + 1, -55, -24, 54, -4, -11, + 30, 9, 51, -7, 56, -60, + 75, -49, -1, 32, -63, -71, + 32, -96, 39, 35, -40, -7, + -18, 29, 39, -6, -40, 56, + 33, -6, -50, 3, 14, 8, + -19, 10, -32, 10, -24, -16, + 32, -42, 0, 74, -69, -14, + 12, 27, -28, 54, -2, 21, + 23, 32, -13, -59, 4, -40, + -52, -10, 15, -32, -12, 36, + -26, -28, -3, 40, 26, 14, + 70, -12, -86, -13, -25, 21, + -10, -58, -11, 34, 32, -44, + -22, 2, -24, 17, 104, 3, + 40, 55, -67, 30, 35, 2, + 37, -1, -4, 22, -120, 4, + -1, 35, 48, 71, -7, 46, + 5, 0, -28, -20, 26, 10, + 15, 9, 15, 34, -24, 4, + 10, -42, 9, 17, 65, 11, + 39, -14, 34, -16, -81, 1, + 44, 11, 32, 21, -83, -43, + 15, -35, 19, -23, 0, -7, + 33, -1, -15, -24, 55, 36, + -46, -6, -15, 30, 9, 9, + 54, -39, 26, -34, 2, -8, + 48, 1, 22, -1, -13, 47, + 56, 50, 0, -9, 5, -31, + -52, 61, 42, -10, -23, 13, + -28, -34, 10, -58, -99, 53, + 20, 15, -29, -16, 5, -35, + 23, 20, 11, -11, -59, -46, + 86, 15, -80, 22, 18, 23, + 47, -24, 62, 7, -16, 28, + 1, 66, -33, 36, -51, 17, + 3, 11, 26, 12, -57, 83, + -28, 76, -19, 32, 4, -42, + -2, 2, -36, 18, 18, -24, + 25, -64, -71, -8, -17, -111, + 21, -28, 15, -62, -16, 8, + -26, 40, 32, 10, -7, 99, + 83, -2, 9, 7, -10, 83, + 37, -51, 38, -4, -5, 0, + 42, -36, -22, -16, -13, -3, + 35, -20, -10, -23, 27, -43, + 3, 77, 21, -31, -38, -17, + -29, 58, -19, -38, -17, -60, + -2, 90, 32, 26, 40, 7, + 37, 22, -42, 5, -81, 33, + 28, -59, -13, 8, -50, 0, + -84, 54, -16, -13, -2, 82, + -14, -84, -59, 10, -46, 7, + 27, -39, -28, 25, -25, 13, + 43, 37, -20, -11, -10, 16, + -5, -45, 20, 3, -59, 70, + -22, -16, -38, 42, 73, 2, + -26, 5166, -352396, 4875536, -28099679, 85945073, + -155294502, 173660953, -121144602, 51294609, -12235510, 1395762, + -50487, 79, 67, -60, -28, -57, + -35, 13, 6, -3, 35, -7, + -15, -95, -39, 83, +}; + +static const int32_t ifft_ref_real_1024_q31[1024] = { + 326, 1146, 2786, -3072, -3316, -605, + -2901, -840, -2671, 664, 2057, 956, + -21, -662, 462, 3641, -2217, 610, + -1321, 238, 2943, 688, 1060, 846, + -3792, -1576, 2121, -1631, -211, -2712, + -2722, -3466, -8597, -7806, -10107, -8978, + -8707, -11131, -9732, -15323, -15254, -13081, + -12623, -10274, -13212, -5985, -4940, -4716, + -1004, 3307, 7423, 11870, 21908, 23159, + 29444, 38649, 46299, 51698, 58474, 61509, + 69988, 71541, 78183, 80345, 79248, 80016, + 77508, 69254, 64701, 54919, 38485, 22397, + 7619, -18671, -39738, -64092, -93406, -121566, + -151206, -181934, -213000, -241011, -269356, -295013, + -318042, -331352, -343862, -348224, -349487, -339135, + -319901, -295323, -258729, -214256, -161875, -98338, + -22320, 61463, 148883, 241596, 343430, 449953, + 553092, 660575, 765348, 863233, 956207, 1031827, + 1098053, 1152642, 1181959, 1190748, 1179948, 1146590, + 1076767, 984062, 860947, 715027, 533899, 321992, + 91170, -167866, -444979, -738889, -1046761, -1361827, + -1677156, -1987696, -2285378, -2563978, -2820773, -3038273, + -3217797, -3348348, -3421990, -3434697, -3385794, -3264787, + -3066741, -2788681, -2438638, -2011383, -1505748, -933663, + -291619, 399962, 1144061, 1925860, 2735503, 3549988, + 4362537, 5151016, 5907267, 6604092, 7230123, 7760787, + 8186022, 8488314, 8646197, 8646598, 8484987, 8152712, + 7635835, 6935136, 6051955, 4991930, 3755510, 2363819, + 826364, -834320, -2599066, -4440124, -6321571, -8216197, + -10077901, -11885570, -13588265, -15155182, -16535940, -17702619, + -18613150, -19234858, -19532980, -19487165, -19075195, -18273148, + -17078708, -15490893, -13506877, -11147624, -8430976, -5382361, + -2046368, 1542253, 5318886, 9227859, 13214381, 17188190, + 21089248, 24838424, 28350006, 31546237, 34346432, 36681320, + 38471965, 39655342, 40176918, 39988511, 39053022, 37340045, + 34844574, 31564156, 27518651, 22736319, 17272291, 11186028, + 4553529, -2522282, -9940434, -17585491, -25318423, -33006825, + -40506944, -47660215, -54327081, -60355027, -65599108, -69911020, + -73182968, -75287952, -76129493, -75629810, -73723931, -70383367, + -65595111, -59372093, -51768179, -42837441, -32692074, -21452167, + -9277743, 3657281, 17156928, 30990380, 44930749, 58723629, + 72104522, 84815781, 96588254, 107170396, 116310129, 123773406, + 129346015, 132845872, 134109268, 133017610, 129484530, 123462360, + 114949234, 103998137, 90691090, 75177605, 57635434, 38303041, + 17446134, -4620199, -27539988, -50941560, -74413943, -97543947, + -119891596, -141022922, -160505079, -177918821, -192864296, -204973947, + -213909668, -219387656, -221170208, -219080741, -212996462, -202883444, + -188761959, -170722219, -148945912, -123689848, -95255466, -64056433, + -30529263, 4794075, 41356921, 78547365, 115714160, 152194199, + 187309917, 220377731, 250731557, 277733009, 300773373, 319311844, + 332844739, 340960776, 343321097, 339692071, 329923185, 313994650, + 291963289, 264028543, 230483055, 191743888, 148332347, 100859462, + 50042902, -3319828, -58361358, -114155510, -169723973, -224083369, + -276218550, -325136386, -369863274, -409475668, -443106446, -469980132, + -489407054, -500821595, -503772467, -497957373, -483223160, -459560044, + -427130807, -386246818, -337395714, -281211712, -218478864, -150120760, + -77192341, -857360, 77633043, 156945573, 235703099, 312492496, + 385896495, 454541831, 517077914, 572237251, 618849440, 655864033, + 682381207, 697662138, 701140517, 692454437, 671455926, 638192497, + 592950953, 536228301, 468743311, 391413562, 305373081, 211917193, + 112515196, 8778457, -97574737, -204722093, -310812643, -413944496, + -512244821, -603865242, -687056465, -760154912, -821653865, -870222658, + -904720479, -924233005, -928095122, -915899426, -887528715, -843128402, + -783143163, -708310042, -619630001, -518370643, -406052045, -284427622, + -155436858, -21195452, 116047980, 253948213, 390107041, 522103241, + 647551921, 764128146, 869637593, 962029890, 1039437023, 1100241539, + 1143083583, 1166892820, 1170916692, 1154740779, 1118299769, 1061881018, + 986122536, 892029173, 780944200, 654513839, 514700066, 363723079, + 204041778, 38296711, -130712875, -300087519, -466886151, -628155008, + -781010506, -922657115, -1050458160, -1161992111, -1255074688, -1327830658, + -1378698781, -1406490452, -1410403952, -1390048744, -1345443160, -1277046282, + -1185733013, -1072792031, -939913170, -789152392, -622900774, -443861303, + -254992312, -59450927, 139443874, 338270624, 533579987, 721937713, + 899993623, 1064543298, 1212581744, 1341359152, 1448429579, 1531710980, + 1589512741, 1620569648, 1624074651, 1599696439, 1547574911, 1468356915, + 1363161501, 1233562136, 1081583751, 909664374, 720608445, 517535818, + 303845742, 83153937, -140773909, -364088220, -582915643, -793431776, + -991930383, -1174877083, -1339004161, -1481332999, -1599238488, -1690519489, + -1753417293, -1786653305, -1789473370, -1761623106, -1703406621, -1615638750, + -1499680365, -1357367601, -1191013457, -1003373006, -797566749, -577067164, + -345613976, -107144347, 134245982, 374403491, 609177711, 834477933, + 1046389454, 1241198812, 1415473145, 1566135863, 1690502316, 1786338339, + 1851906157, 1885975091, 1887878900, 1857497793, 1795262548, 1702180329, + 1579789356, 1430135802, 1255748305, 1059597591, 845017078, 615693842, + 375555802, 128728549, -120541875, -367952417, -609239266, -840247912, + -1056986532, -1255711898, -1433001718, -1585806912, -1711490644, -1807893880, + -1873372869, -1906821270, -1907681888, -1875968599, -1812268342, -1717704175, + -1593954721, -1443189071, -1268052547, -1071604372, -857256046, -628745296, + -390036133, -145250986, 101370068, 345578885, 583188397, 810124441, + 1022511584, 1216750332, 1389559157, 1538037301, 1659724323, 1752624907, + 1815261574, 1846685940, 1846484281, 1814806282, 1752336430, 1660299848, + 1540418887, 1394895267, 1226368506, 1037861164, 832714737, 614557244, + 387207300, 154634175, -79136531, -310076941, -534235098, -747807622, + -947193377, -1129055065, -1290399669, -1428593288, -1541436757, -1627178290, + -1684539978, -1712767863, -1711595900, -1681285479, -1622599120, -1536772665, + -1425517966, -1290963494, -1135616184, -962344542, -774274368, -574781562, + -367391560, -155748026, 56468987, 265617545, 468136455, 660612031, + 839839063, 1002881883, 1147108605, 1270245760, 1370406427, 1446131637, + 1496385859, 1520595225, 1518643671, 1490871745, 1438059084, 1361412752, + 1262534324, 1143392079, 1006288158, 853795822, 688738010, 514100456, + 333016242, 148666198, -35733786, -217015994, -392114684, -558100465, + -712257271, -852104103, -975444447, -1080394328, -1165418355, -1229357540, + -1271415577, -1291209572, -1288731220, -1264358312, -1218861398, -1153343168, + -1069242324, -968305532, -852531316, -724153592, -585580472, -439354359, + -288129099, -134568938, 18639437, 168876066, 313606234, 450448228, + 577184171, 691821653, 792615435, 878069759, 947011876, 998555008, + 1032137571, 1047524066, 1044787870, 1024323798, 986830822, 933272555, + 864888321, 783151052, 689717699, 586439370, 475283364, 358327327, + 237682213, 115515955, -6047289, -124936621, -239160418, -346849610, + -446305192, -535984604, -614569358, -680950643, -734254056, -773856112, + -799382239, -810716482, -807980300, -791555184, -762029195, -720221489, + -667137368, -603957468, -532003241, -452726882, -367667281, -278430831, + -186650850, -93967586, -2010105, 87670605, 173583395, 254348294, + 328705558, 395535680, 453880834, 502971400, 542184178, 571117360, + 589547079, 597424930, 594903224, 582311351, 560135788, 529013782, + 489740139, 443210310, 390428155, 332480838, 270509976, 205696632, + 139248261, 72346401, 6164976, -58182531, -119639865, -177226711, + -230066695, -277391885, -318549814, -353018304, -380398777, -400445720, + -413030907, -418170496, -416006843, -406808812, -390949602, -368911794, + -341285549, -308709477, -271916169, -231679042, -188803111, -144109017, + -98433010, -52605797, -7410253, 36387441, 78074158, 117003911, + 152593644, 184341862, 211838920, 234752163, 252840296, 265961426, + 274066892, 277186709, 275448124, 269055850, 258286481, 243481885, + 225049684, 203441735, 179143029, 152678153, 124588986, 95419225, + 65714533, 36014755, 6833670, -21342804, -48066571, -72929222, + -95564180, -115671966, -133002819, -147362366, -158618696, -166699102, + -171586889, -173327948, -172026559, -167814604, -160894287, -151489663, + -139871117, -126329356, -111186960, -94771411, -77414678, -59467657, + -41266314, -23138140, -5391564, 11671033, 27790902, 42722186, + 56256573, 68223974, 78479099, 86918806, 93483066, 98132973, + 100882481, 101761537, 100840788, 98224915, 94030256, 88408558, + 81520765, 73547285, 64681638, 55113243, 45056283, 34698342, + 24242606, 13871476, 3767927, -5908113, -15006947, -23389971, + -30957637, -37604085, -43265955, -47896929, -51453182, -53942389, + -55361586, -55748217, -55150039, -53619207, -51237913, -48086596, + -44270032, -39882417, -35035095, -29835697, -24398261, -18831626, + -13233531, -7709600, -2359060, 2741076, 7508090, 11883351, + 15802228, 19226824, 22123134, 24464432, 26249325, 27466691, + 28134399, 28273722, 27908768, 27072999, 25812506, 24173126, + 22210833, 19974234, 17521274, 14903269, 12184305, 9415050, + 6651964, 3939391, 1325486, -1151329, -3451045, -5548765, + -7411580, -9028634, -10385842, -11469809, -12283476, -12825585, + -13106189, -13133337, -12930778, -12512723, -11898955, -11114197, + -10181485, -9136535, -7996551, -6790865, -5546526, -4288121, + -3042708, -1831404, -666060, 426453, 1433672, 2346296, + 3151055, 3844528, 4418334, 4867341, 5201684, 5417090, + 5517138, 5510524, 5407103, 5212655, 4939564, 4596810, + 4201640, 3756418, 3276626, 2775443, 2263223, 1749530, + 1245083, 755616, 295067, -137266, -531108, -885778, + -1193909, -1455972, -1667698, -1836140, -1951262, -2025669, + -2058551, -2043942, -1998955, -1921219, -1810497, -1674966, + -1525317, -1355771, -1176953, -994191, -810831, -625797, + -442618, -273791, -112000, 39406, 171237, 287439, + 392918, 476625, 546027, 599266, 631420, 652492, + 661672, 651810, 635639, 603428, 568623, 520399, + 472127, 414285, 362057, 300075, 247514, 186936, + 134315, 82093, 36560, -9730, -45362, -81307, + -109537, -129710, -147427, -160759, -168481, -172912, + -172555, -167998, -163837, -153003, -142682, -133355, + -120121, -102416, -88146, -72605, -59067, -43018, + -30225, -20737, -6450, 2671, 9514, 15270, + 21544, 27571, 31312, 30051, 32554, 35022, + 29866, 33834, 34496, 30956, 25856, 24739, + 21090, 18605, 13885, 11395, 12074, 8208, + 6113, 1491, 2436, -1194, 755, -1141, + -1742, -2584, -3779, -2934, -5882, -4082, + -4822, -4378, -850, -2076, -212, 341, + -1712, -2779, -3499, 1149, -151, 92, + -3132, 333, 1147, -3681, -2353, 1598, + 1786, -536, -1080, -780, 238, -2557, + -1215, -478, 1247, 793, +}; + +static const int32_t ifft_ref_imag_1024_q31[1024] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +}; diff --git a/test/cmocka/src/math/fft/ref_ifft_multi_1536_32.h b/test/cmocka/src/math/fft/ref_ifft_multi_1536_32.h new file mode 100644 index 000000000000..1a1b0fc65f4a --- /dev/null +++ b/test/cmocka/src/math/fft/ref_ifft_multi_1536_32.h @@ -0,0 +1,1044 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_IFFT_MULTI_1536_NUM_TESTS 1 + +static const int32_t ifft_in_real_1536_q31[1536] = { + 99, -4, 22, -33, 37, 83, + 29, 51, 3, 13, -14, -14, + -20, -21, 39, 31, -29, -6, + -26, -52, -4, -9, -9, -9, + 29, -25, -825, 92195, -1546020, 10045581, + -33641397, 65657100, -78882664, 59164046, -27128469, 7128081, + -930292, 42792, -213, 1, 4, 7, + 58, -24, 27, -19, -58, -34, + -1, -41, -4, -16, -22, -20, + -1, 35, 2, 8, 21, -59, + 28, -17, -35, -32, 56, 7, + -45, 10, 19, 26, 13, 7, + -17, 21, -20, 18, 19, -15, + -57, -18, 3, 33, 9, 11, + 9, -17, -5, 34, 23, 55, + -3, -10, 20, -2, 23, -8, + -6, -28, -21, -10, -15, 5, + 4, -21, -58, 16, 24, 45, + -15, -42, 10, -10, -46, -23, + 7, 13, 2, 17, -12, -35, + -31, 17, 30, -5, 1, 11, + 18, -5, 41, -13, -1, 14, + -9, -10, -16, -41, 12, 8, + 21, 13, 91, -53, -38, 19, + 11, 32, 36, 29, -19, 16, + -32, 22, 47, -35, -17, 6, + -1, -2, -34, 27, -12, -7, + -18, 16, -11, 28, 8, 31, + -72, 33, -32, 2, 27, -35, + -26, 2, -35, 9, 33, 1, + -34, -29, -35, 9, 12, -22, + -8, 0, 11, 21, -14, 3, + 41, 11, 27, 8, -14, 7, + -2, -18, 39, 26, -15, 7, + -6, 15, -17, -4, 19, 2, + -33, -11, -27, 0, 37, 45, + -8, 8, 38, 43, -16, -51, + -17, -35, -19, 32, 50, 9, + 2, -23, 36, 8, 34, 41, + -22, -40, 7, 9, -4, 23, + -35, 2, 0, 49, 66, 4, + -9, 18, 2, -25, -30, -21, + 51, -65, -15, -38, 72, 16, + -7, 27, -14, 2, 2, 18, + -45, -18, -17, -10, 17, -63, + -6, 1, -58, -16, -26, -8, + 9, 44, -9, 6, -19, 15, + -48, 28, -12, 51, -17, 42, + 6, -3, 12, -31, 19, -22, + 34, -9, 20, 38, -9, 0, + 40, -14, 31, 39, 74, -19, + -38, 19, 46, -2, -2, 27, + -24, -5, -34, 15, 8, 52, + 36, 53, 20, 31, -6, -4, + 21, -10, -6, 19, 7, -11, + -49, 32, -8, -16, 29, 9, + -6, -3, -2, 20, -7, -13, + 10, -16, -12, -81, -29, -34, + -42, 36, 4, 76, -12, -24, + 40, 39, 8, 9, 33, -8, + 34, 39, 16, 18, -30, -16, + 13, -22, 25, 21, 8, 28, + -17, -18, 2, -42, 40, -44, + 20, -53, -35, 30, 2, 25, + -58, -15, -32, 43, 25, 8, + 7, 6, -34, 27, 21, 56, + -65, 52, 27, -11, 28, 43, + -14, -11, 40, -29, 71, -69, + 28, 0, -11, -57, -33, 17, + 28, -21, -29, 0, -40, 1, + -28, -44, 31, 6, -16, -38, + 1, -41, -17, 46, -10, -21, + 30, 46, 57, -30, 37, -3, + -22, -55, -15, 20, -8, -4, + -29, 13, -11, 11, 3, 5, + -2, 51, -10, -29, -28, -5, + 33, -12, 5, -20, 3, -13, + -9, 7, -25, -38, 33, -13, + -46, -18, -7, -99, -32, -56, + 28, -1, 23, -17, -61, -36, + -14, -20, 17, -14, -11, -19, + 45, -10, 12, -12, -15, 18, + 32, 11, 6, -47, 0, -19, + 49, -23, 40, -36, 35, -19, + 9, -23, -7, -14, -45, 6, + 71, -8, 8, -25, -1, 14, + 39, 39, 61, -3, -42, 20, + 10, 27, -14, 49, -36, 6, + 21, 19, 15, 5, -12, -9, + 15, 6, -45, 19, -43, -4, + 9, 37, 37, 5, -29, 34, + -1, -24, -8, -18, -8, 39, + -19, -1, -12, 54, -36, -14, + 14, -8, 23, -59, -54, -13, + 39, 1, -12, -51, 18, 15, + -14, 5, 28, -15, -30, -5, + 7, 35, 21, -25, -40, -13, + -58, 36, 42, -16, 14, -28, + -50, -17, -10, -20, 2, 7, + -49, 38, -19, -2, -16, 8, + 9, 16, -12, 20, 1, 34, + 38, -9, 43, 31, 30, 0, + -55, -2, 69, 14, -23, 39, + -31, -20, 26, 46, 22, -24, + -1, 29, -24, 24, 6, 34, + -13, 21, 25, -34, 7, 9, + -47, -3, 46, -11, 27, -23, + -13, -21, -24, 5, 9, -49, + -7, 38, -13, 46, 2, 32, + 18, 38, 17, -47, 5, 4, + 8, 5, 34, -11, 26, 14, + 1, -7, 3, 45, -31, 2, + -13, -43, 58, 11, 14, -3, + -57, -28, -23, -5, 28, 42, + -1, 2, -1, 2, 25, -49, + -57, 18, -57, 18, 50, -32, + 26, -3, -23, -6, -60, -28, + 24, -9, 3, 28, 21, -46, + -22, -57, -21, 4, -63, -39, + -46, -51, 2, 20, -35, -47, + -14, 64, -75, 1, -8, 12, + 34, 13, 48, -10, 45, 23, + 12, 12, -6, -61, -45, 3, + 3, 45, -39, 12, 10, -49, + -14, 47, 7, -8, 31, -36, + -45, 9, 5, -2, -2, -8, + 24, -35, 6, -15, -8, 67, + 28, -5, -14, -9, -8, -24, + 131, -24, -8, -9, -14, -5, + 28, 67, -8, -15, 6, -35, + 24, -8, -2, -2, 5, 9, + -45, -36, 31, -8, 7, 47, + -14, -49, 10, 12, -39, 45, + 3, 3, -45, -61, -6, 12, + 12, 23, 45, -10, 48, 13, + 34, 12, -8, 1, -75, 64, + -14, -47, -35, 20, 2, -51, + -46, -39, -63, 4, -21, -57, + -22, -46, 21, 28, 3, -9, + 24, -28, -60, -6, -23, -3, + 26, -32, 50, 18, -57, 18, + -57, -49, 25, 2, -1, 2, + -1, 42, 28, -5, -23, -28, + -57, -3, 14, 11, 58, -43, + -13, 2, -31, 45, 3, -7, + 1, 14, 26, -11, 34, 5, + 8, 4, 5, -47, 17, 38, + 18, 32, 2, 46, -13, 38, + -7, -49, 9, 5, -24, -21, + -13, -23, 27, -11, 46, -3, + -47, 9, 7, -34, 25, 21, + -13, 34, 6, 24, -24, 29, + -1, -24, 22, 46, 26, -20, + -31, 39, -23, 14, 69, -2, + -55, 0, 30, 31, 43, -9, + 38, 34, 1, 20, -12, 16, + 9, 8, -16, -2, -19, 38, + -49, 7, 2, -20, -10, -17, + -50, -28, 14, -16, 42, 36, + -58, -13, -40, -25, 21, 35, + 7, -5, -30, -15, 28, 5, + -14, 15, 18, -51, -12, 1, + 39, -13, -54, -59, 23, -8, + 14, -14, -36, 54, -12, -1, + -19, 39, -8, -18, -8, -24, + -1, 34, -29, 5, 37, 37, + 9, -4, -43, 19, -45, 6, + 15, -9, -12, 5, 15, 19, + 21, 6, -36, 49, -14, 27, + 10, 20, -42, -3, 61, 39, + 39, 14, -1, -25, 8, -8, + 71, 6, -45, -14, -7, -23, + 9, -19, 35, -36, 40, -23, + 49, -19, 0, -47, 6, 11, + 32, 18, -15, -12, 12, -10, + 45, -19, -11, -14, 17, -20, + -14, -36, -61, -17, 23, -1, + 28, -56, -32, -99, -7, -18, + -46, -13, 33, -38, -25, 7, + -9, -13, 3, -20, 5, -12, + 33, -5, -28, -29, -10, 51, + -2, 5, 3, 11, -11, 13, + -29, -4, -8, 20, -15, -55, + -22, -3, 37, -30, 57, 46, + 30, -21, -10, 46, -17, -41, + 1, -38, -16, 6, 31, -44, + -28, 1, -40, 0, -29, -21, + 28, 17, -33, -57, -11, 0, + 28, -69, 71, -29, 40, -11, + -14, 43, 28, -11, 27, 52, + -65, 56, 21, 27, -34, 6, + 7, 8, 25, 43, -32, -15, + -58, 25, 2, 30, -35, -53, + 20, -44, 40, -42, 2, -18, + -17, 28, 8, 21, 25, -22, + 13, -16, -30, 18, 16, 39, + 34, -8, 33, 9, 8, 39, + 40, -24, -12, 76, 4, 36, + -42, -34, -29, -81, -12, -16, + 10, -13, -7, 20, -2, -3, + -6, 9, 29, -16, -8, 32, + -49, -11, 7, 19, -6, -10, + 21, -4, -6, 31, 20, 53, + 36, 52, 8, 15, -34, -5, + -24, 27, -2, -2, 46, 19, + -38, -19, 74, 39, 31, -14, + 40, 0, -9, 38, 20, -9, + 34, -22, 19, -31, 12, -3, + 6, 42, -17, 51, -12, 28, + -48, 15, -19, 6, -9, 44, + 9, -8, -26, -16, -58, 1, + -6, -63, 17, -10, -17, -18, + -45, 18, 2, 2, -14, 27, + -7, 16, 72, -38, -15, -65, + 51, -21, -30, -25, 2, 18, + -9, 4, 66, 49, 0, 2, + -35, 23, -4, 9, 7, -40, + -22, 41, 34, 8, 36, -23, + 2, 9, 50, 32, -19, -35, + -17, -51, -16, 43, 38, 8, + -8, 45, 37, 0, -27, -11, + -33, 2, 19, -4, -17, 15, + -6, 7, -15, 26, 39, -18, + -2, 7, -14, 8, 27, 11, + 41, 3, -14, 21, 11, 0, + -8, -22, 12, 9, -35, -29, + -34, 1, 33, 9, -35, 2, + -26, -35, 27, 2, -32, 33, + -72, 31, 8, 28, -11, 16, + -18, -7, -12, 27, -34, -2, + -1, 6, -17, -35, 47, 22, + -32, 16, -19, 29, 36, 32, + 11, 19, -38, -53, 91, 13, + 21, 8, 12, -41, -16, -10, + -9, 14, -1, -13, 41, -5, + 18, 11, 1, -5, 30, 17, + -31, -35, -12, 17, 2, 13, + 7, -23, -46, -10, 10, -42, + -15, 45, 24, 16, -58, -21, + 4, 5, -15, -10, -21, -28, + -6, -8, 23, -2, 20, -10, + -3, 55, 23, 34, -5, -17, + 9, 11, 9, 33, 3, -18, + -57, -15, 19, 18, -20, 21, + -17, 7, 13, 26, 19, 10, + -45, 7, 56, -32, -35, -17, + 28, -59, 21, 8, 2, 35, + -1, -20, -22, -16, -4, -41, + -1, -34, -58, -19, 27, -24, + 58, 7, 4, 1, -213, 42792, + -930292, 7128081, -27128469, 59164046, -78882664, 65657100, + -33641397, 10045581, -1546020, 92195, -825, -25, + 29, -9, -9, -9, -4, -52, + -26, -6, -29, 31, 39, -21, + -20, -14, -14, 13, 3, 51, + 29, 83, 37, -33, 22, -4, +}; + +static const int32_t ifft_in_imag_1536_q31[1536] = { + 0, 0, 18, -9, 28, 19, + 4, -28, -9, -34, -6, -1, + 0, 31, 9, -9, -65, -34, + 6, 1, -49, -34, -2, 18, + -20, -61, -2523, 286383, -4833354, 31628685, + -106676469, 209692391, -253750715, 191701771, -88543013, 23436058, + -3081460, 142801, -570, -45, -20, -15, + 0, -4, -25, 28, -24, -66, + -10, 11, 37, -2, 10, 5, + 64, -2, 10, -9, 25, 32, + 34, -76, -24, 40, 11, -61, + -57, 0, -18, -22, -30, 32, + -3, -26, 9, 28, 6, -25, + -29, 18, -31, -39, -59, -23, + -14, -71, 33, 9, -12, -61, + 44, -9, 8, 38, 65, 48, + 17, -22, 16, 15, 8, -12, + 36, 16, -55, -24, 13, -22, + -38, -58, 34, -28, 52, -24, + -12, 38, -6, -16, 5, 23, + -11, 21, -21, 11, 52, 0, + -1, 29, -39, 20, 40, 47, + 34, -16, 34, 23, -19, -39, + 14, -28, -10, 5, 23, 22, + 21, 8, -10, 18, -20, 33, + -16, 19, 22, -45, -13, -21, + 6, 23, -19, -18, -15, 15, + -5, -13, 26, -19, -33, 2, + 46, 7, -1, -10, 0, 50, + -4, -34, 23, -3, -36, -76, + -58, 28, 18, 16, 0, 7, + 6, 52, 9, 10, -14, 37, + 43, 28, -21, 37, 16, 4, + -28, -7, -64, -2, 3, -35, + -52, -25, -7, -30, -3, 46, + -24, 27, 64, 17, 2, -23, + 15, -6, -26, 33, 49, 7, + 9, -39, -38, 43, -33, -37, + 58, 16, 48, 23, 34, 24, + -15, -15, 21, 17, -3, -19, + 2, -15, 37, -9, 21, -18, + 26, 89, 39, 29, 1, -17, + 38, 25, -48, -27, -16, 21, + 20, -36, 16, -3, 16, -23, + -8, -34, 29, -62, 47, -39, + -2, 8, -23, -18, -20, 24, + -4, 29, 3, 14, -15, -13, + -36, 21, -15, -29, 15, -13, + -19, 21, -2, 53, -28, 11, + -12, -70, 48, -1, -11, -62, + -18, 7, -14, -2, 22, -40, + 6, -35, 35, 8, 5, -25, + -24, 69, -21, 26, 12, 53, + 21, 17, -3, -42, 39, -7, + 64, 23, -37, 30, -35, 37, + 23, 29, 20, 72, 0, 29, + 49, 38, -76, -39, -63, 33, + -3, -5, -8, 21, -15, -36, + 25, -34, -7, -1, 0, -74, + 15, 5, -9, 59, -12, 3, + -22, 48, -11, -36, -57, 4, + -5, 45, -38, 61, -17, 9, + 67, 11, 7, 22, -10, 13, + -10, 10, 11, -20, -9, 46, + -26, 12, 12, -54, 36, -8, + 7, -27, 24, 2, -26, 9, + -34, -15, 35, 59, 40, 18, + 19, 5, 20, 11, -41, -4, + -54, 50, -30, 19, -28, 3, + 0, 3, -12, -37, -75, 6, + -25, -9, -5, 33, 32, -40, + 38, 33, 21, -11, -24, -15, + 33, -16, -13, 30, -5, 31, + 44, 26, -33, -10, 10, 27, + -14, -2, -76, -6, -12, -29, + -20, -7, 1, 28, 13, -24, + 11, 64, -29, -10, -1, -10, + -30, -61, -10, -8, 23, 16, + -28, 68, -37, -49, -7, 73, + -39, 1, 53, 54, 44, 10, + 8, 14, -19, -6, -10, -6, + 42, -2, -15, 27, -6, -41, + 7, -27, 3, -43, -15, -31, + 15, 2, -17, 18, -37, -1, + -1, 5, 11, 11, -38, 33, + 17, -24, -53, 0, 30, -17, + 39, -20, -9, -6, 26, -18, + -17, 6, 10, -3, -75, -12, + -7, -27, 13, -25, -52, 41, + -19, -1, -78, 7, 23, -15, + 24, 16, -36, -15, -40, 8, + 20, 31, 8, 8, 48, -40, + 4, -29, -2, -1, -14, -56, + -37, -26, -41, 21, -17, -38, + -34, -1, 24, 33, -31, -14, + 8, -23, 6, -51, 28, 2, + 6, 4, 38, 4, -1, -39, + 17, -24, 0, 21, -32, -4, + -22, 6, 23, -67, 11, 31, + 36, 3, 27, 16, 24, -9, + 10, -9, -53, -45, -42, 17, + -24, -1, 15, -1, -8, -11, + -4, -59, 30, -47, -30, -24, + 27, -24, 62, 7, -60, 79, + -6, 2, 47, -20, -5, 41, + -8, 4, 43, -14, 32, -8, + -2, 11, -8, 12, -33, 5, + 24, -17, 8, -44, 37, 28, + -7, 24, -5, 42, -6, -42, + -8, 49, -30, 10, 61, -3, + 23, 48, 25, 45, -43, 4, + -7, -26, -23, -13, 18, -13, + -42, 52, 39, -60, -21, 23, + -71, -35, 9, 3, 1, -8, + 19, 0, -9, 8, -39, 1, + 8, 35, 2, 67, 1, -32, + -11, -16, 32, -16, -78, 14, + 54, -32, -16, 16, 2, -10, + 31, 1, 26, -20, -20, -25, + 1, -13, -16, -64, 0, 45, + -6, -29, 21, 55, 27, 55, + -10, -34, -22, 57, -1, 7, + 2, -6, 14, -9, -28, 13, + 1, 7, 7, 11, -45, -35, + -24, -46, 32, -27, 76, -27, + 4, -14, -7, -37, 24, -8, + -2, 58, 26, 34, -24, 23, + 29, 30, 28, -18, -5, 17, + 0, -17, 5, 18, -28, -30, + -29, -23, 24, -34, -26, -58, + 2, 8, -24, 37, 7, 14, + -4, 27, -76, 27, -32, 46, + 24, 35, 45, -11, -7, -7, + -1, -13, 28, 9, -14, 6, + -2, -7, 1, -57, 22, 34, + 10, -55, -27, -55, -21, 29, + 6, -45, 0, 64, 16, 13, + -1, 25, 20, 20, -26, -1, + -31, 10, -2, -16, 16, 32, + -54, -14, 78, 16, -32, 16, + 11, 32, -1, -67, -2, -35, + -8, -1, 39, -8, 9, 0, + -19, 8, -1, -3, -9, 35, + 71, -23, 21, 60, -39, -52, + 42, 13, -18, 13, 23, 26, + 7, -4, 43, -45, -25, -48, + -23, 3, -61, -10, 30, -49, + 8, 42, 6, -42, 5, -24, + 7, -28, -37, 44, -8, 17, + -24, -5, 33, -12, 8, -11, + 2, 8, -32, 14, -43, -4, + 8, -41, 5, 20, -47, -2, + 6, -79, 60, -7, -62, 24, + -27, 24, 30, 47, -30, 59, + 4, 11, 8, 1, -15, 1, + 24, -17, 42, 45, 53, 9, + -10, 9, -24, -16, -27, -3, + -36, -31, -11, 67, -23, -6, + 22, 4, 32, -21, 0, 24, + -17, 39, 1, -4, -38, -4, + -6, -2, -28, 51, -6, 23, + -8, 14, 31, -33, -24, 1, + 34, 38, 17, -21, 41, 26, + 37, 56, 14, 1, 2, 29, + -4, 40, -48, -8, -8, -31, + -20, -8, 40, 15, 36, -16, + -24, 15, -23, -7, 78, 1, + 19, -41, 52, 25, -13, 27, + 7, 12, 75, 3, -10, -6, + 17, 18, -26, 6, 9, 20, + -39, 17, -30, 0, 53, 24, + -17, -33, 38, -11, -11, -5, + 1, 1, 37, -18, 17, -2, + -15, 31, 15, 43, -3, 27, + -7, 41, 6, -27, 15, 2, + -42, 6, 10, 6, 19, -14, + -8, -10, -44, -54, -53, -1, + 39, -73, 7, 49, 37, -68, + 28, -16, -23, 8, 10, 61, + 30, 10, 1, 10, 29, -64, + -11, 24, -13, -28, -1, 7, + 20, 29, 12, 6, 76, 2, + 14, -27, -10, 10, 33, -26, + -44, -31, 5, -30, 13, 16, + -33, 15, 24, 11, -21, -33, + -38, 40, -32, -33, 5, 9, + 25, -6, 75, 37, 12, -3, + 0, -3, 28, -19, 30, -50, + 54, 4, 41, -11, -20, -5, + -19, -18, -40, -59, -35, 15, + 34, -9, 26, -2, -24, 27, + -7, 8, -36, 54, -12, -12, + 26, -46, 9, 20, -11, -10, + 10, -13, 10, -22, -7, -11, + -67, -9, 17, -61, 38, -45, + 5, -4, 57, 36, 11, -48, + 22, -3, 12, -59, 9, -5, + -15, 74, 0, 1, 7, 34, + -25, 36, 15, -21, 8, 5, + 3, -33, 63, 39, 76, -38, + -49, -29, 0, -72, -20, -29, + -23, -37, 35, -30, 37, -23, + -64, 7, -39, 42, 3, -17, + -21, -53, -12, -26, 21, -69, + 24, 25, -5, -8, -35, 35, + -6, 40, -22, 2, 14, -7, + 18, 62, 11, 1, -48, 70, + 12, -11, 28, -53, 2, -21, + 19, 13, -15, 29, 15, -21, + 36, 13, 15, -14, -3, -29, + 4, -24, 20, 18, 23, -8, + 2, 39, -47, 62, -29, 34, + 8, 23, -16, 3, -16, 36, + -20, -21, 16, 27, 48, -25, + -38, 17, -1, -29, -39, -89, + -26, 18, -21, 9, -37, 15, + -2, 19, 3, -17, -21, 15, + 15, -24, -34, -23, -48, -16, + -58, 37, 33, -43, 38, 39, + -9, -7, -49, -33, 26, 6, + -15, 23, -2, -17, -64, -27, + 24, -46, 3, 30, 7, 25, + 52, 35, -3, 2, 64, 7, + 28, -4, -16, -37, 21, -28, + -43, -37, 14, -10, -9, -52, + -6, -7, 0, -16, -18, -28, + 58, 76, 36, 3, -23, 34, + 4, -50, 0, 10, 1, -7, + -46, -2, 33, 19, -26, 13, + 5, -15, 15, 18, 19, -23, + -6, 21, 13, 45, -22, -19, + 16, -33, 20, -18, 10, -8, + -21, -22, -23, -5, 10, 28, + -14, 39, 19, -23, -34, 16, + -34, -47, -40, -20, 39, -29, + 1, 0, -52, -11, 21, -21, + 11, -23, -5, 16, 6, -38, + 12, 24, -52, 28, -34, 58, + 38, 22, -13, 24, 55, -16, + -36, 12, -8, -15, -16, 22, + -17, -48, -65, -38, -8, 9, + -44, 61, 12, -9, -33, 71, + 14, 23, 59, 39, 31, -18, + 29, 25, -6, -28, -9, 26, + 3, -32, 30, 22, 18, 0, + 57, 61, -11, -40, 24, 76, + -34, -32, -25, 9, -10, 2, + -64, -5, -10, 2, -37, -11, + 10, 66, 24, -28, 25, 4, + 0, 15, 20, 45, 570, -142801, + 3081460, -23436058, 88543013, -191701771, 253750715, -209692391, + 106676469, -31628685, 4833354, -286383, 2523, 61, + 20, -18, 2, 34, 49, -1, + -6, 34, 65, 9, -9, -31, + 0, 1, 6, 34, 9, 28, + -4, -19, -28, 9, -18, 0, +}; + +static const int32_t ifft_ref_real_1536_q31[1536] = { + -208, 1028, -2146, -280, 776, 1608, + 1081, 637, 842, 2274, 792, -115, + 4394, -1464, 1851, 967, -191, -578, + 3180, 1263, 2142, 3402, 586, 3266, + 1202, 1888, -1120, -375, 151, -3604, + -122, 1991, -236, -3107, -2506, -2626, + -4282, -4639, -172, -4654, -4533, -2999, + -15, -5065, -155, -4063, 1261, 721, + 3129, -671, 2662, 2723, 1061, 8426, + 7675, 7229, 12234, 10576, 10304, 13036, + 14434, 17152, 14472, 17043, 18274, 13826, + 13241, 11632, 10311, 8876, 7535, 5023, + 3673, -2123, -7309, -14532, -15667, -19573, + -23310, -31847, -36355, -41917, -44643, -49330, + -54444, -56048, -54924, -55007, -57774, -56197, + -52275, -46488, -40590, -33525, -26331, -14534, + -5315, 9452, 18671, 36735, 52659, 65412, + 79725, 95877, 109849, 123652, 137540, 145200, + 153930, 156815, 164349, 165740, 158411, 156119, + 147951, 133110, 115471, 91519, 70424, 42272, + 11340, -21575, -56827, -94279, -134881, -172055, + -213360, -250037, -284627, -319512, -347581, -372634, + -392288, -406000, -415059, -413205, -406127, -386463, + -366070, -328695, -289256, -232414, -177543, -111152, + -32078, 46657, 132162, 217378, 312255, 401003, + 492486, 578105, 657728, 735235, 800967, 858345, + 901514, 933447, 945826, 945383, 923194, 881957, + 823666, 744892, 650339, 532505, 401713, 249385, + 86826, -91622, -272974, -466517, -662726, -858114, + -1051320, -1236046, -1411686, -1569633, -1705463, -1822427, + -1914305, -1971737, -1997485, -1988663, -1938185, -1857534, + -1732525, -1564796, -1360688, -1122122, -845645, -539384, + -203558, 157006, 530053, 917864, 1312502, 1707075, + 2090197, 2459433, 2801281, 3110743, 3383779, 3607114, + 3778184, 3890401, 3933792, 3914304, 3817403, 3643098, + 3399418, 3073155, 2678505, 2209822, 1678372, 1084276, + 442509, -245337, -960479, -1702598, -2445594, -3185798, + -3906204, -4592220, -5233953, -5810889, -6310512, -6724566, + -7038143, -7235970, -7314842, -7265505, -7076677, -6754784, + -6296018, -5699434, -4969654, -4108742, -3136922, -2059649, + -890244, 353243, 1648727, 2977030, 4314244, 5640043, + 6926146, 8145887, 9277320, 10297821, 11185992, 11903031, + 12448852, 12792884, 12916543, 12821770, 12484853, 11912496, + 11102716, 10052315, 8769831, 7273682, 5584355, 3711104, + 1693775, -447201, -2677090, -4958879, -7247563, -9511744, + -11703465, -13782705, -15702704, -17424542, -18916260, -20127258, + -21032184, -21595619, -21803149, -21624235, -21057140, -20087223, + -18716527, -16953659, -14810811, -12321141, -9503518, -6400778, + -3055652, 480782, 4156075, 7903631, 11669689, 15374606, + 18958814, 22346114, 25474151, 28274296, 30683080, 32639661, + 34096110, 35002560, 35321394, 35025586, 34095720, 32521541, + 30304896, 27471731, 24037163, 20047123, 15547141, 10594808, + 5269683, -351499, -6179407, -12112749, -18058849, -23905328, + -29545744, -34872979, -39781852, -44166629, -47923957, -50978111, + -53236721, -54638099, -55119176, -54643963, -53185424, -50737369, + -47298744, -42907294, -37598036, -31434040, -24498741, -16887429, + -8713123, -94741, 8820257, 17893205, 26963034, 35871054, + 44447851, 52538069, 59975530, 66609377, 72294399, 76892212, + 80292014, 82392141, 83110260, 82389572, 80193927, 76508526, + 71360649, 64780127, 56849853, 47655824, 37328004, 26008147, + 13867342, 1085333, -12120465, -25536048, -38934836, -52068253, + -64705008, -76603397, -87527796, -97258179, -105585075, -112314562, + -117280713, -120338580, -121384153, -120330545, -117127521, -111779505, + -104304143, -94771825, -83291461, -70009055, -55094819, -38774930, + -21294148, -2914662, 16054170, 35299102, 54488431, 73287116, + 91347784, 108331536, 123909356, 137766473, 149616023, 159180965, + 166233868, 170575046, 172064616, 170576428, 166068025, 158531167, + 148009147, 134610545, 118483473, 99844653, 78947786, 56095457, + 31645852, 5973079, -20500963, -47330323, -74052822, -100200161, + -125296303, -148871677, -170474655, -189679049, -206074331, -219306189, + -229059310, -235068628, -237134168, -235123748, -228956546, -218641946, + -204252159, -185934134, -163910290, -138473312, -109988245, -78863628, + -45594336, -10693457, 25250196, 61651254, 97872112, 133279643, + 167232663, 199102751, 228284556, 254194790, 276309629, 294146180, + 307294012, 315412570, 318233653, 315585456, 307396754, 293662441, + 274507454, 250130988, 220841590, 187039402, 149213225, 107920491, + 63808737, 17587427, -29987869, -78118952, -125968080, -172711586, + -217494176, -259499772, -297926602, -332032449, -361127238, -384589906, + -401888592, -412591548, -416368239, -413003605, -402401970, -384597510, + -359738491, -328121730, -290141454, -246339982, -197346613, -143913090, + -86867154, -27145840, 34282217, 96378194, 158069896, 218280353, + 275928983, 329964614, 379369503, 423194148, 460570682, 490705819, + 512949051, 526745521, 531697773, 527540589, 514173891, 491656679, + 460188620, 420159841, 372096451, 316682269, 254737793, 187222598, + 115194822, 39831891, -37626003, -115868772, -193555103, -269324053, + -341819985, -409734768, -471798949, -526832218, -573747752, -611592070, + -639544497, -656948721, -663307112, -658324851, -641879757, -614068853, + -575169661, -525665973, -466233677, -397737653, -321211140, -237834773, + -148953290, -56002184, 39464289, 135838415, 231470672, 324683029, + 413824173, 497281235, 573519966, 641099500, 698711660, 745193260, + 779570707, 801047198, 809057956, 803239996, 783490048, 749925326, + 702910625, 643062665, 571208539, 488421585, 395954303, 295274829, + 187992943, 75867686, -39234688, -155364893, -270526625, -382721173, + -489954333, -590312450, -681948840, -763162502, -832395730, -888280790, + -929662923, -955628164, -965508614, -958905396, -935714163, -896097977, + -840525812, -769729565, -684734615, -586818083, -477494634, -358505054, + -231767635, -99384991, 36447908, 173418741, 309179351, 441372486, + 567665080, 685809850, 793657618, 889220299, 970691248, 1036487321, + 1085290926, 1116036982, 1127985532, 1120690429, 1094052234, 1048304735, + 983994827, 902020022, 803586229, 690197392, 563634712, 425927856, + 279326828, 126252690, -30727602, -188948106, -345698579, -498253663, + -643943557, -780184469, -904517779, -1014672187, -1108602474, -1184506618, + -1240893623, -1276580740, -1290736320, -1282893759, -1252957322, -1201218320, + -1128344799, -1035378921, -923712736, -795091118, -651549487, -495428782, + -329278199, -155867023, 21884624, 200964166, 378296390, 550817084, + 715509842, 869465952, 1009935821, 1134382373, 1240516904, 1326342221, + 1390206083, 1430813800, 1447256973, 1439042403, 1406102963, 1348789380, + 1267880510, 1164559892, 1040430447, 897443767, 737906646, 564425518, + 379875346, 187325754, -9959043, -208628068, -405280556, -596522969, + -779024043, -949576504, -1105159555, -1242986235, -1360557688, -1455707771, + -1526630125, -1571931512, -1590656579, -1582288902, -1546785379, -1484564418, + -1396514081, -1283966465, -1148699380, -992870834, -819030265, -630046527, + -429061869, -219452221, -4767624, 211344570, 425174230, 633047815, + 831345812, 1016614742, 1185594779, 1335289737, 1463018092, 1566456589, + 1643704895, 1693273650, 1714172081, 1705882228, 1668384051, 1602168866, + 1508224931, 1388011642, 1243467936, 1076940537, 891184470, 689290793, + 474641988, 250858324, 21737861, -208816087, -436846641, -658446865, + -869777852, -1067170436, -1247183257, -1406646888, -1542751972, -1653062659, + -1735582597, -1788791763, -1811654306, -1803668814, -1764855539, -1695759994, + -1597456049, -1471530418, -1320042339, -1145497633, -950809867, -739249865, + -514385056, -280041257, -40181383, 201080379, 439624918, 671355509, + 892286064, 1098594389, 1286706868, 1453352441, 1595628823, 1711035463, + 1797521019, 1853538365, 1878059813, 1870600384, 1831206309, 1760492154, + 1659602184, 1530203408, 1374457364, 1194986427, 994818107, 777345237, + 546255918, 305492794, 59165875, -188527458, -433341422, -671079309, + -897668893, -1109214643, -1302074023, -1472937031, -1618848646, -1737290618, + -1826217726, -1884079590, -1909863238, -1903105212, -1863905400, -1792913351, + -1691333260, -1560895247, -1403806747, -1222758514, -1020847804, -801517798, + -568519036, -325840915, -77637046, 171850151, 418353964, 657652106, + 885660159, 1098481666, 1292480155, 1464355516, 1611177051, 1730444441, + 1820150539, 1878772825, 1905343502, 1899434946, 1861181237, 1791267354, + 1690932265, 1561919190, 1406470627, 1227285157, 1027454790, 810422575, + 579933199, 339937735, 94560706, -151998519, -395519648, -631847447, + -856952704, -1067020943, -1258483185, -1428108906, -1573046811, -1690880320, + -1779653406, -1837919413, -1864754559, -1859783641, -1823171173, -1755625833, + -1658386915, -1533198396, -1382281189, -1208279192, -1014238945, -803541923, + -579834919, -346970773, -108971582, 130083337, 366114057, 595094166, + 813132897, 1016558501, 1201938275, 1366176039, 1506542457, 1620740077, + 1706919479, 1763717224, 1790275640, 1786276393, 1751908357, 1687891249, + 1595438012, 1476262486, 1332509163, 1166745659, 981900242, 781222554, + 568211774, 346560641, 120100574, -107289782, -331713541, -549356216, + -756540884, -949779137, -1125851227, -1281843132, -1415192803, -1523754996, + -1605802264, -1660092492, -1685848824, -1682801752, -1651163067, -1591637338, + -1505408041, -1394110256, -1259790097, -1104882900, -932150731, -744661919, + -545709413, -338757446, -127382761, 84765707, 294067250, 496976412, + 690070929, 870113211, 1034134977, 1179439235, 1303678232, 1404885195, + 1481490379, 1532369848, 1556838111, 1554667668, 1526100288, 1471814589, + 1392935146, 1290979951, 1167883446, 1025897621, 867598300, 695803013, + 513556483, 324055689, 130579822, -63530664, -254960711, -440468393, + -616936322, -781437175, -931258704, -1063977475, -1177469159, -1269973586, + -1340088669, -1386818867, -1409579450, -1408193505, -1382898111, -1334344314, + -1263572251, -1171997342, -1061377097, -933764183, -791500540, -637158044, + -473474842, -303339128, -129708618, 44418353, 216071053, 382335233, + 540448165, 687781229, 821938681, 940758749, 1042384718, 1125252993, + 1188147956, 1230202439, 1250926083, 1250188874, 1228226406, 1185647049, + 1123399468, 1042758074, 945299018, 832869534, 707550079, 571621816, + 427526974, 277809022, 125084990, -28007635, -178856734, -324907138, + -463734021, -593052973, -710764745, -815013568, -904171247, -976904534, + -1032170687, -1069237209, -1087700273, -1087470343, -1068778111, -1032176645, + -978516872, -908919323, -824774811, -727708909, -619535342, -502245966, + -377946914, -248858753, -117245647, 14624738, 144489450, 270173067, + 389580624, 500766017, 601940765, 691518395, 768126426, 830640815, + 878191105, 910178934, 926258016, 926396556, 910805951, 879973778, + 834645350, 775805740, 704647514, 622561565, 531103763, 431972981, + 326970096, 217973439, 106899986, -4330812, -113813213, -219710289, + -320272154, -413860814, -498998744, -574348156, -638786776, -691379857, + -731412862, -758411959, -772099815, -772476020, -759732747, -734296127, + -696804018, -648095467, -589173798, -521211860, -445513712, -363500819, + -276669977, -186588833, -94839242, -3023445, 87304541, 174622298, + 257494031, 334584378, 404667892, 466682945, 519706284, 562979312, + 595951179, 618222270, 629608809, 630112956, 619904735, 599360500, + 569008486, 529544706, 481803119, 426750006, 365455529, 299075876, + 228840843, 156016605, 81889836, 7756860, -65127282, -135536293, + -202317721, -264407579, -320823972, -370715300, -413363358, -448173476, + -474700396, -492652588, -501896551, -502436599, -494431331, -478193830, + -454159830, -422893027, -385065038, -341461778, -292933893, -240416823, + -184881223, -127335687, -68805911, -10307038, 47162104, 102643156, + 155228358, 204082912, 248449560, 287665317, 321164977, 348506386, + 369349387, 383472021, 390781163, 391299046, 385158588, 372607442, + 354005897, 329793737, 300515771, 266774740, 229249182, 188658014, + 145771955, 101363895, 56228463, 11154361, -33085315, -75765867, + -116185210, -153712088, -187762879, -217843178, -243525696, -264475607, + -280445626, -291273854, -296909542, -297359668, -292750374, -283274804, + -269211393, -250910393, -228781316, -203300855, -174980799, -144372364, + -112054201, -78621969, -44668588, -10793090, 22429460, 54446787, + 84748044, 112851032, 138327117, 160818678, 180008562, 195655717, + 207575091, 215660629, 219880235, 220245999, 216864942, 209880683, + 199509818, 186014197, 169708472, 150946259, 130109644, 107612785, + 83879303, 59350962, 34464106, 9662772, -14639065, -38039657, + -60160003, -80657250, -99220426, -115593466, -129546162, -140913942, + -149573644, -155442464, -158504321, -158789018, -156361959, -151342314, + -143885404, -134196704, -122497522, -109047150, -94117870, -78022254, + -61057968, -43547261, -25804349, -8129901, 9162869, 25798240, + 41501763, 56035957, 69186490, 80772311, 90633998, 98658424, + 104762522, 108903204, 111057934, 111259018, 109562688, 106046605, + 100834254, 94063360, 85898082, 76517844, 66128784, 54935713, + 43153877, 31006516, 18711362, 6483672, -5469064, -16945311, + -27770754, -37775892, -46818615, -54771112, -61533068, -67026503, + -71200739, -74026465, -75494146, -75627807, -74467061, -72073364, + -68533189, -63937179, -58405371, -52064462, -45039931, -37490040, + -29556752, -21379814, -13124254, -4921292, 3081325, 10761369, + 17992294, 24664939, 30680797, 35969684, 40457241, 44097381, + 46861649, 48722338, 49681754, 49764898, 48992385, 47410889, + 45073356, 42055772, 38424287, 34266273, 29673244, 24744847, + 19568708, 14249149, 8882570, 3560649, -1623890, -6587324, + -11253071, -15553237, -19428909, -22822812, -25697558, -28027913, + -29781633, -30967017, -31573078, -31616950, -31116986, -30105009, + -28612194, -26690950, -24392479, -21758782, -18856741, -15747532, + -12493053, -9151192, -5784785, -2455284, 778428, 3873794, + 6780421, 9450391, 11848188, 13945439, 15721307, 17153486, + 18229833, 18951292, 19317601, 19331829, 19021991, 18391908, + 17477080, 16298631, 14892301, 13286497, 11524410, 9636999, + 7666248, 5643968, 3619164, 1614643, -329494, -2182511, + -3917053, -5510740, -6935551, -8181585, -9230774, -10069505, + -10702745, -11124460, -11330344, -11338179, -11147183, -10771893, + -10229996, -9534288, -8708260, -7772003, -6742108, -5645520, + -4499511, -3330022, -2160619, -1007517, 105958, 1168081, + 2163850, 3069108, 3879602, 4582611, 5175824, 5650631, + 6001619, 6231347, 6348767, 6345832, 6232970, 6020724, + 5711035, 5319768, 4857301, 4330983, 3759052, 3147093, + 2517341, 1869971, 1228320, 593568, -13299, -596644, + -1133926, -1626587, -2061258, -2441661, -2757956, -3009281, + -3195090, -3317069, -3371358, -3369538, -3302704, -3189124, + -3018550, -2810982, -2566460, -2287369, -1982568, -1663786, + -1330037, -993438, -655731, -327480, -11833, 285255, + 559486, 814369, 1035555, 1225864, 1383761, 1511685, + 1599628, 1660692, 1688986, 1684490, 1647570, 1589017, + 1501582, 1394429, 1269741, 1134725, 981075, 823149, + 660159, 493844, 330114, 168814, 14527, -125758, + -257464, -379420, -486743, -577185, -649186, -707958, + -749120, -773688, -786833, -783576, -765253, -738249, + -693765, -642543, -586705, -522856, -450846, -376578, + -301263, -227397, -150470, -82949, -13294, 54367, + 108632, 162347, 208816, 250661, 281292, 304919, + 322777, 332948, 337096, 334473, 326032, 313228, + 295408, 269412, 246699, 215496, 190086, 157695, + 129658, 95562, 61975, 35544, 6711, -22281, + -42869, -59780, -80439, -98610, -110030, -117739, + -124576, -125753, -129948, -128983, -126581, -120301, + -111860, -100762, -94013, -80985, -73587, -61872, + -44448, -35456, -24861, -15228, -2995, 5562, + 13149, 23916, 29909, 35440, 38197, 42010, + 41917, 45141, 44609, 43511, 37540, 35788, + 34531, 31114, 29589, 26982, 24108, 17555, + 14847, 11406, 8428, 3218, 3294, -1756, + -1478, -3498, -8358, -10181, -11537, -11814, + -13888, -11146, -12862, -10178, -12001, -9587, + -8324, -8228, -7163, -2786, -4551, -4214, + -5084, -462, -2985, -2426, -1665, 3391, + 1562, -1694, 4507, 3775, 5534, 2691, + 2039, 5411, 4536, 2785, 1536, 1316, + 3155, 784, -961, 1172, 6, 2598, + 6, -1522, -831, 2692, 3324, -1300, + -1621, -647, -107, 3253, 1955, -1892, + 328, -2424, 701, -926, 497, -2227, + -2074, 2411, -2446, -1601, 854, 603, +}; + +static const int32_t ifft_ref_imag_1536_q31[1536] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; diff --git a/test/cmocka/src/math/fft/ref_ifft_multi_24_32.h b/test/cmocka/src/math/fft/ref_ifft_multi_24_32.h new file mode 100644 index 000000000000..8bcfdd9a5674 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_ifft_multi_24_32.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_IFFT_MULTI_24_NUM_TESTS 1 + +static const int32_t ifft_in_real_24_q31[24] = { + 482922326, -394845603, 213372960, -73385945, 14855847, -1509706, + 52714, 201, 43, 63, -129, -11, + 417, -11, -129, 63, 43, 201, + 52714, -1509706, 14855847, -73385945, 213372960, -394845603, +}; + +static const int32_t ifft_in_imag_24_q31[24] = { + 0, -45964234, 50459274, -26744935, 7515901, -1010620, + 45488, -203, -258, 455, -501, -248, + 0, 248, 501, -455, 258, 203, + -45488, 1010620, -7515901, 26744935, -50459274, 45964234, +}; + +static const int32_t ifft_ref_real_24_q31[24] = { + 3611, 3470, 104050, 1303039, 8697436, 38649256, + 126241459, 320754897, 656625195, 1107910524, 1563494828, 1861834284, + 1878967615, 1607563569, 1161729935, 703464423, 352140415, 142695560, + 45325407, 10719014, 1734754, 163218, 8211, 1653, +}; + +static const int32_t ifft_ref_imag_24_q31[24] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; diff --git a/test/cmocka/src/math/fft/ref_ifft_multi_256_32.h b/test/cmocka/src/math/fft/ref_ifft_multi_256_32.h new file mode 100644 index 000000000000..edc4d0e6bcf5 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_ifft_multi_256_32.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:52 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_IFFT_MULTI_256_NUM_TESTS 1 + +static const int32_t ifft_in_real_256_q31[256] = { + -104443, 1525281, -13889136, 60179033, -146702250, 217202408, + -201034199, 115601193, -39529650, 7259750, -570251, 9887, + -10, -25, -68, -107, 25, -62, + -37, -112, 27, -50, -122, 55, + 55, -9, -19, -74, 31, 1, + -21, 24, -93, -138, 2, 128, + 31, -108, -62, -21, 153, 60, + -104, 65, 61, 63, 82, 19, + -92, -12, -63, -10, -8, 72, + 6, -41, -35, 2, 172, 109, + 7, 87, -64, -88, 4, 133, + 19, -113, 0, 93, 82, 106, + 17, 44, 38, -76, -19, -96, + 25, 37, 52, -61, -129, 25, + -116, -18, -62, -88, -142, -17, + 88, 52, 70, 8, -36, -104, + 138, 103, 24, -9, 60, 17, + -86, 24, -150, 13, -84, 138, + -114, -4, 17, 65, 0, 9, + 22, 13, -110, -64, 50, 52, + -37, 79, -79, -85, -120, -34, + 76, -81, 60, -81, 76, -34, + -120, -85, -79, 79, -37, 52, + 50, -64, -110, 13, 22, 9, + 0, 65, 17, -4, -114, 138, + -84, 13, -150, 24, -86, 17, + 60, -9, 24, 103, 138, -104, + -36, 8, 70, 52, 88, -17, + -142, -88, -62, -18, -116, 25, + -129, -61, 52, 37, 25, -96, + -19, -76, 38, 44, 17, 106, + 82, 93, 0, -113, 19, 133, + 4, -88, -64, 87, 7, 109, + 172, 2, -35, -41, 6, 72, + -8, -10, -63, -12, -92, 19, + 82, 63, 61, 65, -104, 60, + 153, -21, -62, -108, 31, 128, + 2, -138, -93, 24, -21, 1, + 31, -74, -19, -9, 55, 55, + -122, -50, 27, -112, -37, -62, + 25, -107, -68, -25, -10, 9887, + -570251, 7259750, -39529650, 115601193, -201034199, 217202408, + -146702250, 60179033, -13889136, 1525281, +}; + +static const int32_t ifft_in_imag_256_q31[256] = { + 0, -1104526, 9802224, -41374276, 98231553, -141609308, + 127580058, -71388104, 23746028, -4240611, 323629, -5337, + 32, -60, -129, -15, -27, 102, + 58, -169, -92, 19, 75, 5, + -81, 131, -54, -36, -21, -15, + 118, -72, -77, 65, -42, 118, + -9, -18, 106, 80, -7, 88, + 41, 65, 32, -107, -22, -1, + 67, 45, 7, -109, 47, -25, + -53, -44, -33, -24, 2, 179, + -68, 105, 153, 16, -75, -42, + 11, -113, -44, -22, -63, -25, + 6, 2, 26, -87, 111, 106, + -53, -51, -36, -51, -27, 235, + -114, -20, -69, 10, -97, 83, + -57, -37, -69, -148, -34, 75, + 76, -38, 60, 29, 152, 37, + 141, 35, 52, -103, 96, -39, + -4, 38, -124, 18, 162, -48, + 52, -93, 94, -33, -1, 129, + 54, -27, 16, 64, 44, -43, + -45, 22, 0, -22, 45, 43, + -44, -64, -16, 27, -54, -129, + 1, 33, -94, 93, -52, 48, + -162, -18, 124, -38, 4, 39, + -96, 103, -52, -35, -141, -37, + -152, -29, -60, 38, -76, -75, + 34, 148, 69, 37, 57, -83, + 97, -10, 69, 20, 114, -235, + 27, 51, 36, 51, 53, -106, + -111, 87, -26, -2, -6, 25, + 63, 22, 44, 113, -11, 42, + 75, -16, -153, -105, 68, -179, + -2, 24, 33, 44, 53, 25, + -47, 109, -7, -45, -67, 1, + 22, 107, -32, -65, -41, -88, + 7, -80, -106, 18, 9, -118, + 42, -65, 77, 72, -118, 15, + 21, 36, 54, -131, 81, -5, + -75, -19, 92, 169, -58, -102, + 27, 15, 129, 60, -32, 5337, + -323629, 4240611, -23746028, 71388104, -127580058, 141609308, + -98231553, 41374276, -9802224, 1104526, +}; + +static const int32_t ifft_ref_real_256_q31[256] = { + -1569, -830, -1909, -1488, 3415, 3228, + 2188, 5284, 6862, 8740, 14431, 22319, + 31495, 39307, 50570, 64256, 80688, 97686, + 111687, 123695, 129388, 123769, 106202, 69953, + 5001, -90529, -229211, -419412, -662837, -975167, + -1362616, -1829929, -2378158, -3009308, -3713257, -4488081, + -5304582, -6149738, -6981956, -7751361, -8417790, -8914691, + -9158092, -9075448, -8582552, -7568550, -5957542, -3636565, + -521174, 3464467, 8388636, 14295537, 21192186, 29060893, + 37842039, 47439021, 57690475, 68385421, 79264186, 90000101, + 100216705, 109496356, 117359992, 123303230, 126792865, 127286147, + 124251244, 117173422, 105589837, 89107796, 67418137, 40323152, + 7767654, -30165152, -73203423, -120914317, -172649439, -227578442, + -284684073, -342740508, -400372402, -456051421, -508121756, -554862914, + -594502691, -625273094, -645469812, -653507615, -647957114, -627616785, + -591570790, -539212509, -470319052, -385064318, -284054609, -168344268, + -39430444, 100735569, 249803271, 405020394, 563321689, 721358446, + 875594019, 1022376304, 1158027755, 1278948253, 1381696559, 1463114882, + 1520394842, 1551181119, 1553662138, 1526604042, 1469444535, 1382288632, + 1265978107, 1122031888, 952680234, 760801123, 549852852, 323835818, + 87168988, -155419072, -398954843, -638404904, -868755989, -1085152640, + -1283040981, -1458244948, -1607111733, -1726568155, -1814231913, -1868441101, + -1888300566, -1873720889, -1825365598, -1744688034, -1633837210, -1495617661, + -1333406076, -1151061358, -952804289, -743116848, -526638885, -308020361, + -91818428, 117599868, 316184921, 500269979, 666664268, 812707094, + 936326727, 1036037706, 1110986476, 1160919766, 1186188110, 1187665485, + 1166746402, 1125255573, 1065389168, 989631979, 900676276, 801355102, + 694539705, 583089310, 469753347, 357133296, 247607391, 143289840, + 46010628, -42730106, -121763798, -190243820, -247669626, -293855572, + -328899891, -353164563, -367242673, -371922368, -368136646, -356940054, + -339446602, -316817655, -290210974, -260754391, -229500117, -197441719, + -165470302, -134343018, -104720510, -77121551, -51962267, -29512549, + -9954815, 6654740, 20324394, 31163846, 39337881, 45058213, + 48577520, 50167506, 50120504, 48722648, 46250707, 42973219, + 39131997, 34949970, 30607270, 26272771, 22078954, 18121182, + 14480497, 11206366, 8326540, 5845185, 3759796, 2057048, + 705551, -326115, -1083775, -1602381, -1917835, -2073023, + -2101305, -2038436, -1903566, -1728329, -1527768, -1319424, + -1111624, -920902, -739460, -586382, -452219, -337529, + -243069, -171574, -119157, -73001, -40498, -22362, + -7395, -1426, 8844, 10381, 5185, 10614, + 6251, 4908, 6476, 3273, 608, 2586, + -939, 517, -2100, 59, +}; + +static const int32_t ifft_ref_imag_256_q31[256] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +}; diff --git a/test/cmocka/src/math/fft/ref_ifft_multi_3072_32.h b/test/cmocka/src/math/fft/ref_ifft_multi_3072_32.h new file mode 100644 index 000000000000..9fc9c64978d3 --- /dev/null +++ b/test/cmocka/src/math/fft/ref_ifft_multi_3072_32.h @@ -0,0 +1,2068 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. + */ + +/* Created 20-Nov-2025 16:11:53 with script ref_fft_multi.m v1.9-rc1-6882-ge0b90b605-dirty */ + +#define REF_SOFM_IFFT_MULTI_3072_NUM_TESTS 1 + +static const int32_t ifft_in_real_3072_q31[3072] = { + -59, -1, -55, 24, -14, 0, + -14, -29, -16, 30, -13, 24, + 23, -8, -29, -3, -6, -29, + -25, -14, -20, 1, -8, 2, + 7, -21, -15, 18, -56, 0, + -26, 43, -5, 7, 42, -26, + -13, -5, -24, -8, -11, -27, + 20, -6, -4, -1, 14, -21, + -23, 31, 4, -7, 21, 31, + 51, -20, -8, -5, -2784, 237345, + -3580001, 21781536, -69391859, 129763784, -149772281, 107836784, + -47262139, 11753785, -1421192, 57131, -155, -28, + -24, 6, -19, 20, -3, 7, + -19, -9, -52, 28, -31, 44, + -14, 8, -3, -37, 7, -25, + 13, 29, 2, 70, 13, 16, + -4, 40, -34, 7, -23, 26, + -20, 9, 21, 6, -31, -27, + -19, 12, 20, -15, 15, -3, + -34, 34, -24, 39, 62, 3, + -38, 21, -21, 39, 2, -4, + 8, 9, -25, -17, 35, 14, + -4, 13, 30, -13, 7, 18, + 22, -27, 8, -34, -15, 5, + 0, 18, -26, -22, 16, 6, + -19, -15, -12, -19, 11, 25, + -6, 6, -1, 40, 24, -17, + 0, -30, 2, -3, 15, 6, + 32, -2, -6, 8, -44, -28, + -11, -17, -16, 24, -4, 9, + 11, 22, -16, 9, 13, -10, + 11, -31, 10, -39, -9, 3, + 24, 7, -32, 31, -9, -22, + -17, 7, -17, 22, 8, -11, + 0, 6, 20, 22, -25, 18, + 1, 6, -21, -8, -1, -2, + 22, -1, -30, 13, -8, -21, + -21, -22, 15, -17, 40, -15, + -21, 7, -6, 9, 37, -3, + 13, -10, -52, 31, -8, 23, + 39, 14, -4, 5, -9, -38, + -9, -4, 10, 2, 42, -27, + 2, 28, -15, -16, -22, 17, + 0, -15, 14, -11, 4, -17, + -24, 4, 6, -15, -2, 40, + 7, 1, 22, -2, 0, -10, + -2, 31, -5, 20, -12, -6, + 0, 12, 1, -35, 7, -26, + 11, -47, 3, -34, 23, 1, + -8, 0, 11, 18, 26, -1, + -31, 23, 10, -17, -12, 7, + 5, -21, 19, 10, -14, 11, + 12, -10, 49, 0, 5, -16, + -9, 24, 11, 21, -29, -15, + -31, -21, -5, 46, -25, 1, + 62, -18, -32, -8, 4, 5, + -22, -27, 38, -15, 19, 3, + -22, 8, 16, -27, 18, -31, + -25, -22, 23, -34, 1, 39, + 1, -11, 2, 40, 19, 29, + -29, -3, 4, 33, -26, 1, + 15, 3, -8, 65, 29, 3, + -7, 26, -25, 10, -4, 14, + 40, -30, 1, 11, 5, 17, + 9, 8, -6, -13, 18, 27, + -1, -25, 15, 85, -20, 6, + -32, -29, 31, 13, -17, -4, + 9, -3, 8, 11, -11, -38, + -26, 7, -19, 13, 28, 32, + 20, 1, -8, 11, 13, 1, + 8, 20, 40, 2, -41, -7, + -13, 6, 0, 45, -8, 26, + 13, 9, 7, 31, -19, -28, + -18, -19, 10, 13, -5, -32, + 18, -26, -23, 19, -23, -3, + -7, -9, 4, 3, -12, 7, + 14, -14, 29, 22, 0, 63, + -6, 5, -24, -13, 7, 34, + -9, 9, 9, 21, 4, 7, + 3, 17, 31, -27, -38, -47, + 17, 12, -11, -14, 15, -10, + -3, 22, 11, 14, 2, -16, + 23, 5, -48, -18, -21, 38, + -23, 8, -7, -19, 31, 29, + -14, -7, 22, 6, 38, 1, + 22, 24, -9, -2, 20, -70, + 21, 20, -42, -1, -39, -7, + -7, 26, -57, -18, 28, 22, + -4, 11, -13, 12, -16, -5, + -9, -5, 9, 3, 4, -38, + -2, -2, -20, 4, -34, -21, + 15, -54, -8, -47, -17, 25, + -26, 20, 6, 12, -20, 21, + -10, -7, 32, -26, 16, -3, + -9, 1, -3, -3, 6, -9, + -11, 18, 0, -23, -17, 1, + 1, -13, -9, -1, 7, 8, + -16, -7, 19, 15, -38, 4, + 21, 20, 3, -1, 5, -2, + -7, 25, -66, 41, -9, -20, + -17, -22, 11, -16, 4, 17, + 6, 22, -20, 14, -4, -2, + 22, -5, 32, 16, 36, -1, + -6, 0, -20, 8, -2, 14, + -29, -2, 6, 14, -4, 9, + 23, -4, 4, -21, -11, -20, + -13, -22, -30, 14, -18, 39, + 27, -24, 24, -19, 24, 29, + 1, -29, 14, 22, -2, -4, + -34, -26, 7, 24, -22, 4, + 24, -19, -35, 11, -4, 10, + -12, -21, 22, 7, 14, 17, + 8, 11, 9, 23, 3, -15, + -6, 20, -11, -17, -28, 33, + -6, 2, -12, -19, -13, -18, + -7, 45, 18, -20, -1, 2, + 15, -1, 37, 9, -15, -12, + 23, 10, 0, 29, -23, 42, + -15, 7, -22, -9, 2, 6, + -30, -26, 56, -18, 2, -1, + -20, -25, 30, 25, -15, 29, + 20, -11, -25, 29, 4, -26, + 9, -8, -14, 29, 13, 4, + -29, 2, -5, -12, 3, 27, + -9, -13, 42, 10, -6, -18, + -6, -3, -26, -40, -8, -11, + 17, -3, 10, -23, -24, -8, + -30, -8, -6, 18, 30, -6, + 24, -1, 3, -1, -35, 9, + -10, -6, -20, -2, -32, 15, + -48, 14, 19, -15, -10, -22, + -19, -26, -59, 3, -3, 39, + 4, 1, 16, 38, -25, 17, + 10, 57, 28, 5, 31, 19, + 2, 18, 16, -26, -6, 28, + -54, -12, -12, -12, -20, 1, + 21, 22, -22, -4, -11, 26, + -1, 0, -2, -8, 13, 35, + 30, -28, -10, -3, -15, -45, + -4, 3, -6, 23, 42, 2, + 29, -35, 45, 0, 2, 6, + -15, 16, -5, 0, -11, 4, + 22, -20, 36, 37, -14, 10, + 6, 5, 19, 35, -3, 44, + -22, -13, -22, 5, 15, 14, + -33, 9, -23, -17, 13, -9, + -17, 9, -25, -14, -17, 31, + 3, -4, -27, -16, 25, 1, + 16, -34, 6, -21, -15, 16, + -25, 3, 23, 17, -4, 14, + 8, -10, 31, 9, 21, 5, + 6, 14, 14, 20, -25, -3, + 12, 2, 37, -25, -14, -1, + -17, -19, -14, 0, 14, 18, + 24, -42, 22, -5, -12, -13, + -21, -1, -31, 25, -17, -38, + -10, -21, -18, 33, 19, 20, + -16, -7, -27, -9, -10, -11, + 17, 9, 10, -33, 23, -23, + 13, 17, -8, 2, -19, -9, + 18, -4, 31, 11, -21, -2, + 2, -2, -11, -15, 12, -20, + 0, 11, -3, -22, -6, 6, + 12, 13, 19, -1, 16, 21, + 11, 1, 7, 9, -31, 29, + 6, -12, -27, -41, -21, 16, + 23, 17, -16, -52, 12, 63, + -6, -37, 26, -16, 52, 28, + -32, -12, -4, 10, -46, 12, + -17, -5, 72, 10, 43, -9, + -27, 43, 14, 26, -39, -16, + 13, -3, -23, -4, 11, 9, + -2, -22, 8, 26, -5, 13, + -18, -9, -18, 5, 29, -35, + 3, 23, 21, 17, -18, -40, + 43, -38, 18, -3, -7, 28, + -1, 27, -15, -31, -30, 2, + 9, -18, -3, -21, -10, -13, + -26, 5, -6, 18, 32, 41, + 11, -1, -4, 14, 22, -39, + 2, -20, -17, 22, -8, 2, + 20, 32, -1, -9, 3, 1, + -34, -8, -20, 3, -18, 12, + 13, -10, -26, -45, 15, -32, + -12, 0, -38, -2, 0, -6, + 10, 1, -17, -1, 17, 15, + -7, -29, 9, 17, -10, -6, + -33, -8, -11, -4, 37, 11, + 28, 9, 0, 3, 18, -24, + -36, -8, -9, 38, 16, 47, + -19, -9, -22, 24, 22, -22, + 10, 40, 2, -10, 1, 3, + -17, 2, -22, -7, 33, -17, + -9, 18, 37, 6, 21, -23, + 17, -30, -54, -9, 31, 13, + -7, -23, 30, 2, 47, 21, + 28, -34, 3, 32, -40, -7, + 27, 8, 33, -28, -14, 48, + -21, -57, 38, -14, -40, 1, + -9, -21, 3, 24, 6, 19, + 10, 1, 9, 12, -15, 3, + 9, 21, -2, 8, 6, -51, + 10, 16, -25, 15, 13, 18, + -8, 20, -24, -19, 10, 11, + -17, -15, -14, 47, 9, 14, + 20, -24, -10, 17, -4, 7, + -8, 9, -19, 5, 6, 27, + 7, 36, 26, -22, -4, -30, + -19, -3, -30, 33, 7, -31, + 23, 7, -34, 23, 31, -20, + 8, 33, 31, 8, -1, -1, + -39, 19, -22, -50, -27, -23, + -13, 18, -8, -5, -1, 8, + 25, 14, 7, -29, 21, 0, + 28, 35, 26, 18, 7, -1, + -18, -25, 33, -23, -5, -28, + -37, 28, -1, -13, 5, -18, + -11, -8, 1, -18, -4, 1, + 2, -20, 8, -23, -21, 31, + 20, 12, -4, -5, -4, -10, + 9, -41, -12, 32, 30, -5, + -30, 1, -23, -11, 22, -21, + 30, -14, -29, -15, 23, 0, + -6, 7, -15, -18, 26, -3, + 5, -3, -2, 0, 26, 36, + -17, -6, 14, 0, 3, -19, + 1, 23, 20, 6, 15, -8, + -33, -15, -26, -14, 10, -23, + -25, 11, 0, -18, -4, -2, + -3, -11, 21, -40, 15, 19, + -10, 21, 12, -44, -21, 16, + 22, 8, -18, -13, -12, -8, + 0, -52, -4, -9, -20, -3, + 16, 21, -16, -35, -23, 4, + 11, -18, 10, 3, -26, -34, + -24, -33, -6, -28, -21, 57, + 0, 22, 9, -31, 8, -9, + -4, 24, 22, 22, 19, -10, + 17, 38, 43, 10, 27, 21, + 7, 8, 3, -57, -9, -36, + 3, -13, 3, 18, 34, 23, + -22, -31, -8, -3, 24, 28, + -48, -24, 25, -13, 2, 9, + 6, -22, 4, -46, -30, 9, + -13, -4, 9, -24, -2, -21, + -20, 1, -36, 0, -23, -21, + -37, -21, 3, 17, 4, -34, + 5, -36, -13, -4, -25, -18, + 20, -40, -2, -26, -9, -7, + -4, -34, -16, -26, 22, -12, + -17, -24, -40, -3, -26, 37, + -14, 23, -8, 0, -35, 2, + 11, 5, -7, -11, 54, 9, + -25, 26, -59, 0, -5, 40, + -13, -6, -12, 43, 11, 9, + -25, -16, -47, -28, 6, -3, + -27, -3, 6, -28, -47, -16, + -25, 9, 11, 43, -12, -6, + -13, 40, -5, 0, -59, 26, + -25, 9, 54, -11, -7, 5, + 11, 2, -35, 0, -8, 23, + -14, 37, -26, -3, -40, -24, + -17, -12, 22, -26, -16, -34, + -4, -7, -9, -26, -2, -40, + 20, -18, -25, -4, -13, -36, + 5, -34, 4, 17, 3, -21, + -37, -21, -23, 0, -36, 1, + -20, -21, -2, -24, 9, -4, + -13, 9, -30, -46, 4, -22, + 6, 9, 2, -13, 25, -24, + -48, 28, 24, -3, -8, -31, + -22, 23, 34, 18, 3, -13, + 3, -36, -9, -57, 3, 8, + 7, 21, 27, 10, 43, 38, + 17, -10, 19, 22, 22, 24, + -4, -9, 8, -31, 9, 22, + 0, 57, -21, -28, -6, -33, + -24, -34, -26, 3, 10, -18, + 11, 4, -23, -35, -16, 21, + 16, -3, -20, -9, -4, -52, + 0, -8, -12, -13, -18, 8, + 22, 16, -21, -44, 12, 21, + -10, 19, 15, -40, 21, -11, + -3, -2, -4, -18, 0, 11, + -25, -23, 10, -14, -26, -15, + -33, -8, 15, 6, 20, 23, + 1, -19, 3, 0, 14, -6, + -17, 36, 26, 0, -2, -3, + 5, -3, 26, -18, -15, 7, + -6, 0, 23, -15, -29, -14, + 30, -21, 22, -11, -23, 1, + -30, -5, 30, 32, -12, -41, + 9, -10, -4, -5, -4, 12, + 20, 31, -21, -23, 8, -20, + 2, 1, -4, -18, 1, -8, + -11, -18, 5, -13, -1, 28, + -37, -28, -5, -23, 33, -25, + -18, -1, 7, 18, 26, 35, + 28, 0, 21, -29, 7, 14, + 25, 8, -1, -5, -8, 18, + -13, -23, -27, -50, -22, 19, + -39, -1, -1, 8, 31, 33, + 8, -20, 31, 23, -34, 7, + 23, -31, 7, 33, -30, -3, + -19, -30, -4, -22, 26, 36, + 7, 27, 6, 5, -19, 9, + -8, 7, -4, 17, -10, -24, + 20, 14, 9, 47, -14, -15, + -17, 11, 10, -19, -24, 20, + -8, 18, 13, 15, -25, 16, + 10, -51, 6, 8, -2, 21, + 9, 3, -15, 12, 9, 1, + 10, 19, 6, 24, 3, -21, + -9, 1, -40, -14, 38, -57, + -21, 48, -14, -28, 33, 8, + 27, -7, -40, 32, 3, -34, + 28, 21, 47, 2, 30, -23, + -7, 13, 31, -9, -54, -30, + 17, -23, 21, 6, 37, 18, + -9, -17, 33, -7, -22, 2, + -17, 3, 1, -10, 2, 40, + 10, -22, 22, 24, -22, -9, + -19, 47, 16, 38, -9, -8, + -36, -24, 18, 3, 0, 9, + 28, 11, 37, -4, -11, -8, + -33, -6, -10, 17, 9, -29, + -7, 15, 17, -1, -17, 1, + 10, -6, 0, -2, -38, 0, + -12, -32, 15, -45, -26, -10, + 13, 12, -18, 3, -20, -8, + -34, 1, 3, -9, -1, 32, + 20, 2, -8, 22, -17, -20, + 2, -39, 22, 14, -4, -1, + 11, 41, 32, 18, -6, 5, + -26, -13, -10, -21, -3, -18, + 9, 2, -30, -31, -15, 27, + -1, 28, -7, -3, 18, -38, + 43, -40, -18, 17, 21, 23, + 3, -35, 29, 5, -18, -9, + -18, 13, -5, 26, 8, -22, + -2, 9, 11, -4, -23, -3, + 13, -16, -39, 26, 14, 43, + -27, -9, 43, 10, 72, -5, + -17, 12, -46, 10, -4, -12, + -32, 28, 52, -16, 26, -37, + -6, 63, 12, -52, -16, 17, + 23, 16, -21, -41, -27, -12, + 6, 29, -31, 9, 7, 1, + 11, 21, 16, -1, 19, 13, + 12, 6, -6, -22, -3, 11, + 0, -20, 12, -15, -11, -2, + 2, -2, -21, 11, 31, -4, + 18, -9, -19, 2, -8, 17, + 13, -23, 23, -33, 10, 9, + 17, -11, -10, -9, -27, -7, + -16, 20, 19, 33, -18, -21, + -10, -38, -17, 25, -31, -1, + -21, -13, -12, -5, 22, -42, + 24, 18, 14, 0, -14, -19, + -17, -1, -14, -25, 37, 2, + 12, -3, -25, 20, 14, 14, + 6, 5, 21, 9, 31, -10, + 8, 14, -4, 17, 23, 3, + -25, 16, -15, -21, 6, -34, + 16, 1, 25, -16, -27, -4, + 3, 31, -17, -14, -25, 9, + -17, -9, 13, -17, -23, 9, + -33, 14, 15, 5, -22, -13, + -22, 44, -3, 35, 19, 5, + 6, 10, -14, 37, 36, -20, + 22, 4, -11, 0, -5, 16, + -15, 6, 2, 0, 45, -35, + 29, 2, 42, 23, -6, 3, + -4, -45, -15, -3, -10, -28, + 30, 35, 13, -8, -2, 0, + -1, 26, -11, -4, -22, 22, + 21, 1, -20, -12, -12, -12, + -54, 28, -6, -26, 16, 18, + 2, 19, 31, 5, 28, 57, + 10, 17, -25, 38, 16, 1, + 4, 39, -3, 3, -59, -26, + -19, -22, -10, -15, 19, 14, + -48, 15, -32, -2, -20, -6, + -10, 9, -35, -1, 3, -1, + 24, -6, 30, 18, -6, -8, + -30, -8, -24, -23, 10, -3, + 17, -11, -8, -40, -26, -3, + -6, -18, -6, 10, 42, -13, + -9, 27, 3, -12, -5, 2, + -29, 4, 13, 29, -14, -8, + 9, -26, 4, 29, -25, -11, + 20, 29, -15, 25, 30, -25, + -20, -1, 2, -18, 56, -26, + -30, 6, 2, -9, -22, 7, + -15, 42, -23, 29, 0, 10, + 23, -12, -15, 9, 37, -1, + 15, 2, -1, -20, 18, 45, + -7, -18, -13, -19, -12, 2, + -6, 33, -28, -17, -11, 20, + -6, -15, 3, 23, 9, 11, + 8, 17, 14, 7, 22, -21, + -12, 10, -4, 11, -35, -19, + 24, 4, -22, 24, 7, -26, + -34, -4, -2, 22, 14, -29, + 1, 29, 24, -19, 24, -24, + 27, 39, -18, 14, -30, -22, + -13, -20, -11, -21, 4, -4, + 23, 9, -4, 14, 6, -2, + -29, 14, -2, 8, -20, 0, + -6, -1, 36, 16, 32, -5, + 22, -2, -4, 14, -20, 22, + 6, 17, 4, -16, 11, -22, + -17, -20, -9, 41, -66, 25, + -7, -2, 5, -1, 3, 20, + 21, 4, -38, 15, 19, -7, + -16, 8, 7, -1, -9, -13, + 1, 1, -17, -23, 0, 18, + -11, -9, 6, -3, -3, 1, + -9, -3, 16, -26, 32, -7, + -10, 21, -20, 12, 6, 20, + -26, 25, -17, -47, -8, -54, + 15, -21, -34, 4, -20, -2, + -2, -38, 4, 3, 9, -5, + -9, -5, -16, 12, -13, 11, + -4, 22, 28, -18, -57, 26, + -7, -7, -39, -1, -42, 20, + 21, -70, 20, -2, -9, 24, + 22, 1, 38, 6, 22, -7, + -14, 29, 31, -19, -7, 8, + -23, 38, -21, -18, -48, 5, + 23, -16, 2, 14, 11, 22, + -3, -10, 15, -14, -11, 12, + 17, -47, -38, -27, 31, 17, + 3, 7, 4, 21, 9, 9, + -9, 34, 7, -13, -24, 5, + -6, 63, 0, 22, 29, -14, + 14, 7, -12, 3, 4, -9, + -7, -3, -23, 19, -23, -26, + 18, -32, -5, 13, 10, -19, + -18, -28, -19, 31, 7, 9, + 13, 26, -8, 45, 0, 6, + -13, -7, -41, 2, 40, 20, + 8, 1, 13, 11, -8, 1, + 20, 32, 28, 13, -19, 7, + -26, -38, -11, 11, 8, -3, + 9, -4, -17, 13, 31, -29, + -32, 6, -20, 85, 15, -25, + -1, 27, 18, -13, -6, 8, + 9, 17, 5, 11, 1, -30, + 40, 14, -4, 10, -25, 26, + -7, 3, 29, 65, -8, 3, + 15, 1, -26, 33, 4, -3, + -29, 29, 19, 40, 2, -11, + 1, 39, 1, -34, 23, -22, + -25, -31, 18, -27, 16, 8, + -22, 3, 19, -15, 38, -27, + -22, 5, 4, -8, -32, -18, + 62, 1, -25, 46, -5, -21, + -31, -15, -29, 21, 11, 24, + -9, -16, 5, 0, 49, -10, + 12, 11, -14, 10, 19, -21, + 5, 7, -12, -17, 10, 23, + -31, -1, 26, 18, 11, 0, + -8, 1, 23, -34, 3, -47, + 11, -26, 7, -35, 1, 12, + 0, -6, -12, 20, -5, 31, + -2, -10, 0, -2, 22, 1, + 7, 40, -2, -15, 6, 4, + -24, -17, 4, -11, 14, -15, + 0, 17, -22, -16, -15, 28, + 2, -27, 42, 2, 10, -4, + -9, -38, -9, 5, -4, 14, + 39, 23, -8, 31, -52, -10, + 13, -3, 37, 9, -6, 7, + -21, -15, 40, -17, 15, -22, + -21, -21, -8, 13, -30, -1, + 22, -2, -1, -8, -21, 6, + 1, 18, -25, 22, 20, 6, + 0, -11, 8, 22, -17, 7, + -17, -22, -9, 31, -32, 7, + 24, 3, -9, -39, 10, -31, + 11, -10, 13, 9, -16, 22, + 11, 9, -4, 24, -16, -17, + -11, -28, -44, 8, -6, -2, + 32, 6, 15, -3, 2, -30, + 0, -17, 24, 40, -1, 6, + -6, 25, 11, -19, -12, -15, + -19, 6, 16, -22, -26, 18, + 0, 5, -15, -34, 8, -27, + 22, 18, 7, -13, 30, 13, + -4, 14, 35, -17, -25, 9, + 8, -4, 2, 39, -21, 21, + -38, 3, 62, 39, -24, 34, + -34, -3, 15, -15, 20, 12, + -19, -27, -31, 6, 21, 9, + -20, 26, -23, 7, -34, 40, + -4, 16, 13, 70, 2, 29, + 13, -25, 7, -37, -3, 8, + -14, 44, -31, 28, -52, -9, + -19, 7, -3, 20, -19, 6, + -24, -28, -155, 57131, -1421192, 11753785, + -47262139, 107836784, -149772281, 129763784, -69391859, 21781536, + -3580001, 237345, -2784, -5, -8, -20, + 51, 31, 21, -7, 4, 31, + -23, -21, 14, -1, -4, -6, + 20, -27, -11, -8, -24, -5, + -13, -26, 42, 7, -5, 43, + -26, 0, -56, 18, -15, -21, + 7, 2, -8, 1, -20, -14, + -25, -29, -6, -3, -29, -8, + 23, 24, -13, 30, -16, -29, + -14, 0, -14, 24, -55, -1, +}; + +static const int32_t ifft_in_imag_3072_q31[3072] = { + 0, 10, -20, -15, 21, -8, + 63, -15, -9, -25, 3, -7, + -21, -6, -5, -35, 2, 43, + -21, 1, -6, 0, 13, 8, + -6, -7, 1, -1, 7, 3, + -10, 68, 17, 12, -28, -34, + 26, 4, -5, -17, -4, 11, + -21, -2, -21, -7, 13, -33, + -11, 10, 19, 6, -5, 16, + -7, 50, -5, 33, -4068, 340975, + -5154185, 31427845, -100341977, 188051721, -217523237, 156961250, + -68943059, 17183334, -2082308, 83903, -220, 19, + -10, -17, 24, 8, 30, -1, + -16, -1, -1, 7, -30, -32, + 4, 12, -10, 52, 41, 0, + -23, -1, 33, -13, -27, 33, + -23, -27, 2, -53, -7, 17, + -5, 54, 6, -1, 7, 11, + -8, 25, -10, 22, -9, 25, + 0, -26, -27, 3, -5, -19, + -24, -7, 29, -1, 15, 8, + 27, 33, 25, 16, -57, -14, + 13, 11, -22, 24, -22, 10, + -17, 8, 10, 43, 19, 15, + -19, -12, -13, -26, 2, 11, + 29, 29, -29, 24, 20, -31, + 16, 4, 5, -21, -16, -21, + -22, 5, -5, 22, -15, -2, + 29, -21, -3, -5, 9, 6, + 4, 6, 7, -3, -5, -27, + 31, 6, -2, 8, -36, -3, + 43, 2, -8, -16, -23, -44, + -17, -8, 33, -37, -8, 13, + -24, 3, -12, 35, -26, -13, + -22, -2, -5, 5, -23, 5, + -20, 2, -20, 21, 42, 17, + -19, 2, 31, -31, 10, 23, + 4, 20, -11, 9, 15, -5, + 13, -20, -45, 34, -6, -10, + -25, 5, -17, -14, 25, -27, + 9, 5, -7, 7, -24, 10, + -5, -10, -8, 3, -34, -43, + -10, 8, 23, 11, 36, 18, + -26, -11, -1, -3, -19, -4, + -31, -31, -15, 12, 15, 44, + 39, -13, 20, 45, -2, -4, + 7, 5, -7, 32, 9, -4, + -4, -1, -13, 22, 10, -35, + -1, 2, 31, 16, 36, 37, + -21, -14, -42, -34, 32, -26, + 9, 25, -9, 8, -18, -2, + 2, 13, 38, 24, -9, -17, + -4, -1, -10, 2, -1, 45, + 28, -25, 18, 10, -46, -19, + 30, 1, -46, -13, 10, -7, + -27, 22, 2, 23, -24, -13, + -22, -15, -30, 27, 16, 3, + -55, 29, 24, 5, 29, -3, + 1, 15, -18, -6, 22, 11, + 19, -8, 25, -12, 15, 14, + 31, -46, -10, 18, -38, -10, + 22, 16, -2, 8, 4, 37, + 22, 30, 42, 48, -30, -5, + 21, -15, -13, -13, -31, 27, + -4, -26, 2, -15, 33, -17, + -39, 7, -20, -1, 14, -19, + 21, 4, 22, -20, -18, 23, + -2, -9, 38, -23, 8, 35, + -9, -7, 3, 7, -5, -5, + 46, 20, 35, 21, -28, 17, + -33, 19, 22, -23, 30, 14, + 34, -12, -25, -19, -14, 21, + -20, 22, 4, 8, -9, 20, + 24, -36, 0, -24, -18, -4, + 6, 11, -4, -26, -22, -15, + -36, 16, -32, 23, -3, 14, + -51, -36, -5, 14, 8, 10, + 41, -12, -20, 25, 1, -24, + 16, 12, 43, 14, -17, 4, + -60, -28, -4, -41, 44, 6, + 1, -4, 6, -1, -1, -14, + -9, 3, -14, -38, 0, 14, + 1, 35, -9, -14, 22, 39, + -21, -29, 15, 32, 4, 23, + 19, 20, 1, -40, -29, 31, + 6, -33, -14, -15, 11, -8, + -13, -36, -35, -8, -7, 2, + 21, -17, -19, -2, 38, 19, + -5, 4, 15, -21, 51, 52, + 18, 1, 45, -7, -11, -22, + -7, 1, -49, -6, -12, 24, + -7, -46, -63, 1, -13, -15, + -25, 3, 27, 10, 9, -33, + -6, -36, 6, 1, -25, -7, + 13, -5, -4, 2, -5, 3, + -33, -36, -2, -26, -27, -16, + -6, -10, 37, -29, 18, 3, + -18, -4, -7, -1, -7, -4, + 3, 46, -12, -30, -7, -12, + -6, 5, -25, -9, 1, 12, + 31, 17, -7, 20, -36, 10, + 0, 13, 16, -16, 10, 17, + 23, -14, 10, -4, -17, -1, + -8, -8, -25, 24, 3, 7, + -16, 59, 2, 28, 25, -1, + 14, -3, -30, -27, -17, 25, + 46, -14, -22, 21, 18, -9, + 13, 23, -5, -23, -18, -5, + -35, 7, 12, -18, -17, 8, + 3, -47, 1, -16, -6, 38, + 38, 20, -3, 41, 71, 0, + 3, 31, 29, -9, 5, -20, + 23, 19, -30, 14, 30, 45, + 14, -29, -6, -9, -12, 14, + -11, 26, -6, -20, -26, 20, + -2, -5, 30, 1, 3, -2, + -36, 13, 5, -7, 30, 18, + -8, -16, 9, 24, 4, 8, + -18, -15, -7, 6, -44, 2, + 9, -18, -21, 3, 4, 1, + -13, -12, 18, -5, 7, -11, + -17, -26, 10, 12, -7, 24, + 7, -12, 39, 21, -16, 37, + -10, -12, -36, -9, -9, 17, + -29, -37, 6, -3, 28, 19, + -37, 17, -21, 7, 4, -5, + 22, 10, -2, -13, 26, -5, + -5, 6, -22, -2, 19, -5, + 15, 15, -2, 9, -15, 11, + -18, -5, -24, 21, 40, -33, + -9, -3, 40, -14, -15, 32, + 31, 13, -23, -17, 32, 10, + 14, 7, 18, -30, -13, -27, + -11, -27, -52, -15, -18, 15, + 42, -7, 17, 10, -1, -30, + -13, -21, 7, -3, 37, 19, + 8, -22, -6, -28, -7, 43, + 9, -24, -27, -33, -7, 27, + -21, 21, 28, -20, -44, 14, + 29, 6, -6, -4, 2, -18, + 13, -5, 14, 21, 15, -2, + 57, -2, 25, -4, 28, 20, + -10, -9, -29, 16, -43, 27, + 12, -9, -1, -21, 47, -45, + -15, -26, -1, 18, 22, -20, + 3, -22, 19, -55, 5, 19, + -4, -15, -11, 0, -14, -9, + -47, 15, 21, -17, -3, 3, + 6, 43, 14, 9, 10, -38, + -1, -22, 13, 6, 11, -17, + 52, -1, -7, 4, 12, -22, + 1, -13, -4, -30, -17, 7, + 6, 39, -5, -34, -15, 21, + -15, -10, -15, 6, -24, -23, + 0, -18, -23, -22, -44, 1, + -16, -3, 22, 3, -14, 4, + 18, -1, -6, 10, 3, 6, + 19, -1, -4, 11, 1, -9, + -3, 6, 22, -11, 6, 5, + -6, -9, -4, 0, -7, -43, + -29, 1, 2, 28, 9, 34, + 19, -2, 1, 7, -9, 16, + 9, 5, -2, 6, -10, 25, + -3, -28, -46, -8, 10, -10, + 0, 36, 1, 10, -2, 14, + 12, 28, -6, 22, -1, -2, + -18, -15, 15, 7, -2, -4, + 28, 17, -6, 5, 8, 22, + -12, -52, 8, 33, 7, 8, + -26, -19, -11, 8, 1, 18, + 12, -38, 25, 9, 22, -6, + 16, 9, 34, -33, 27, -22, + -6, -24, 0, -28, -5, 25, + -6, 36, -4, -38, 6, -14, + 1, -21, -17, 27, -73, -21, + 19, 20, 13, -13, -28, 21, + 2, 34, -2, -33, -8, 28, + 5, 18, 3, 16, -35, 7, + 14, 1, -20, -11, 33, -16, + 20, 15, -21, -21, 10, 9, + 3, -27, -10, -1, -2, 22, + 6, 34, -34, -25, 7, 37, + 8, -33, -16, 5, 5, 5, + 17, 5, -5, 3, 37, -18, + -9, 10, -20, 6, -5, 56, + 26, -11, -17, 5, 10, 7, + 5, -23, 51, 15, -24, -15, + -20, -24, -16, 23, -22, -5, + -18, 30, 23, -35, 2, 23, + 12, 20, -9, -3, 25, -4, + 0, 2, 47, -24, -10, 12, + 14, 22, -7, 18, -14, 10, + 20, -6, 9, 20, 0, -2, + -32, 22, -17, -12, 26, -39, + -2, -16, 29, 2, 16, 13, + 8, -14, 3, -15, 3, 3, + 2, -26, -46, 9, 14, -16, + -29, 36, 1, 49, 25, -45, + 23, 7, -1, 13, -3, 24, + -15, -23, -9, -13, -10, -7, + 28, -14, -14, 29, 1, -7, + -10, 5, 17, 4, 24, 27, + -4, 31, 8, 10, 22, -18, + 27, -12, -47, 24, 3, 8, + 8, -12, -7, -10, -50, -38, + 28, 11, 18, -6, 38, 22, + -1, 15, -15, 8, -27, 27, + -50, 10, -15, 20, 10, 1, + -15, -12, -13, 1, 6, -22, + 17, -3, 23, 13, -17, -12, + 20, -27, -23, -6, 0, -12, + 15, -23, 18, -3, -2, -37, + -32, 28, 20, 0, -33, 10, + -25, 3, -16, -6, 5, 5, + -3, -28, 5, 33, -11, -18, + 31, 34, -2, -2, -53, 15, + 12, -3, 9, 12, 11, 30, + -18, 25, 34, 3, 43, 15, + -18, 43, -5, -10, 2, -6, + 45, 19, 18, -15, -9, 26, + 3, -21, -25, -7, 17, 4, + -7, -27, 11, 5, 18, -40, + 28, 1, 0, -7, 38, -26, + 9, 15, 12, 3, 9, 15, + -34, 51, -1, -30, 4, 45, + 13, 9, 13, -15, 17, 25, + 22, -21, 30, 27, -52, -41, + 40, -37, -8, -44, 45, 26, + 1, 20, -5, 4, 13, 30, + 19, -7, 4, -6, -10, -8, + -19, -30, 4, -35, 4, 10, + -2, -6, 1, 50, -3, 2, + 14, 0, 10, 24, 3, 36, + -13, 4, -21, -15, -4, -9, + 18, -26, -4, 13, 11, -16, + 17, 1, -15, -4, 14, -14, + 4, -23, -2, 3, 12, -8, + 32, 10, -4, 6, 2, 11, + -31, 20, 7, -37, 7, 23, + -18, -30, -31, 20, -1, 10, + -18, 17, 31, -10, -12, -9, + -3, -16, -44, -16, -10, -6, + -21, -10, -13, 7, 6, -1, + -18, 10, -9, 23, -14, -31, + -21, -8, 32, 11, 35, 11, + -18, 1, -8, -29, 7, 6, + -16, -4, 9, 10, -4, 0, + -12, -7, 13, 9, -23, 7, + -18, -16, 23, 46, -39, 17, + -9, -18, 9, 11, 18, 7, + -18, 1, -20, 8, -1, -7, + 21, -2, 13, -23, -12, 8, + -28, 17, -12, -36, 33, 10, + 34, -8, -2, 44, -2, 11, + 19, -17, -11, 55, 26, 4, + -14, -41, 5, 3, 49, -44, + 0, 44, -49, -3, -5, 41, + 14, -4, -26, -55, 11, 17, + -19, -11, 2, -44, 2, 8, + -34, -10, -33, 36, 12, -17, + 28, -8, 12, 23, -13, 2, + -21, 7, 1, -8, 20, -1, + 18, -7, -18, -11, -9, 18, + 9, -17, 39, -46, -23, 16, + 18, -7, 23, -9, -13, 7, + 12, 0, 4, -10, -9, 4, + 16, -6, -7, 29, 8, -1, + 18, -11, -35, -11, -32, 8, + 21, 31, 14, -23, 9, -10, + 18, 1, -6, -7, 13, 10, + 21, 6, 10, 16, 44, 16, + 3, 9, 12, 10, -31, -17, + 18, -10, 1, -20, 31, 30, + 18, -23, -7, 37, -7, -20, + 31, -11, -2, -6, 4, -10, + -32, 8, -12, -3, 2, 23, + -4, 14, -14, 4, 15, -1, + -17, 16, -11, -13, 4, 26, + -18, 9, 4, 15, 21, -4, + 13, -36, -3, -24, -10, 0, + -14, -2, 3, -50, -1, 6, + 2, -10, -4, 35, -4, 30, + 19, 8, 10, 6, -4, 7, + -19, -30, -13, -4, 5, -20, + -1, -26, -45, 44, 8, 37, + -40, 41, 52, -27, -30, 21, + -22, -25, -17, 15, -13, -9, + -13, -45, -4, 30, 1, -51, + 34, -15, -9, -3, -12, -15, + -9, 26, -38, 7, 0, -1, + -28, 40, -18, -5, -11, 27, + 7, -4, -17, 7, 25, 21, + -3, -26, 9, 15, -18, -19, + -45, 6, -2, 10, 5, -43, + 18, -15, -43, -3, -34, -25, + 18, -30, -11, -12, -9, 3, + -12, -15, 53, 2, 2, -34, + -31, 18, 11, -33, -5, 28, + 3, -5, -5, 6, 16, -3, + 25, -10, 33, 0, -20, -28, + 32, 37, 2, 3, -18, 23, + -15, 12, 0, 6, 23, 27, + -20, 12, 17, -13, -23, 3, + -17, 22, -6, -1, 13, 12, + 15, -1, -10, -20, 15, -10, + 50, -27, 27, -8, 15, -15, + 1, -22, -38, 6, -18, -11, + -28, 38, 50, 10, 7, 12, + -8, -8, -3, -24, 47, 12, + -27, 18, -22, -10, -8, -31, + 4, -27, -24, -4, -17, -5, + 10, 7, -1, -29, 14, 14, + -28, 7, 10, 13, 9, 23, + 15, -24, 3, -13, 1, -7, + -23, 45, -25, -49, -1, -36, + 29, 16, -14, -9, 46, 26, + -2, -3, -3, 15, -3, 14, + -8, -13, -16, -2, -29, 16, + 2, 39, -26, 12, 17, -22, + 32, 2, 0, -20, -9, 6, + -20, -10, 14, -18, 7, -22, + -14, -12, 10, 24, -47, -2, + 0, 4, -25, 3, 9, -20, + -12, -23, -2, 35, -23, -30, + 18, 5, 22, -23, 16, 24, + 20, 15, 24, -15, -51, 23, + -5, -7, -10, -5, 17, 11, + -26, -56, 5, -6, 20, -10, + 9, 18, -37, -3, 5, -5, + -17, -5, -5, -5, 16, 33, + -8, -37, -7, 25, 34, -34, + -6, -22, 2, 1, 10, 27, + -3, -9, -10, 21, 21, -15, + -20, 16, -33, 11, 20, -1, + -14, -7, 35, -16, -3, -18, + -5, -28, 8, 33, 2, -34, + -2, -21, 28, 13, -13, -20, + -19, 21, 73, -27, 17, 21, + -1, 14, -6, 38, 4, -36, + 6, -25, 5, 28, 0, 24, + 6, 22, -27, 33, -34, -9, + -16, 6, -22, -9, -25, 38, + -12, -18, -1, -8, 11, 19, + 26, -8, -7, -33, -8, 52, + 12, -22, -8, -5, 6, -17, + -28, 4, 2, -7, -15, 15, + 18, 2, 1, -22, 6, -28, + -12, -14, 2, -10, -1, -36, + 0, 10, -10, 8, 46, 28, + 3, -25, 10, -6, 2, -5, + -9, -16, 9, -7, -1, 2, + -19, -34, -9, -28, -2, -1, + 29, 43, 7, 0, 4, 9, + 6, -5, -6, 11, -22, -6, + 3, 9, -1, -11, 4, 1, + -19, -6, -3, -10, 6, 1, + -18, -4, 14, -3, -22, 3, + 16, -1, 44, 22, 23, 18, + 0, 23, 24, -6, 15, 10, + 15, -21, 15, 34, 5, -39, + -6, -7, 17, 30, 4, 13, + -1, 22, -12, -4, 7, 1, + -52, 17, -11, -6, -13, 22, + 1, 38, -10, -9, -14, -43, + -6, -3, 3, 17, -21, -15, + 47, 9, 14, 0, 11, 15, + 4, -19, -5, 55, -19, 22, + -3, 20, -22, -18, 1, 26, + 15, 45, -47, 21, 1, 9, + -12, -27, 43, -16, 29, 9, + 10, -20, -28, 4, -25, 2, + -57, 2, -15, -21, -14, 5, + -13, 18, -2, 4, 6, -6, + -29, -14, 44, 20, -28, -21, + 21, -27, 7, 33, 27, 24, + -9, -43, 7, 28, 6, 22, + -8, -19, -37, 3, -7, 21, + 13, 30, 1, -10, -17, 7, + -42, -15, 18, 15, 52, 27, + 11, 27, 13, 30, -18, -7, + -14, -10, -32, 17, 23, -13, + -31, -32, 15, 14, -40, 3, + 9, 33, -40, -21, 24, 5, + 18, -11, 15, -9, 2, -15, + -15, 5, -19, 2, 22, -6, + 5, 5, -26, 13, 2, -10, + -22, 5, -4, -7, 21, -17, + 37, -19, -28, 3, -6, 37, + 29, -17, 9, 9, 36, 12, + 10, -37, 16, -21, -39, 12, + -7, -24, 7, -12, -10, 26, + 17, 11, -7, 5, -18, 12, + 13, -1, -4, -3, 21, 18, + -9, -2, 44, -6, 7, 15, + 18, -8, -4, -24, -9, 16, + 8, -18, -30, 7, -5, -13, + 36, 2, -3, -1, -30, 5, + 2, -20, 26, 20, 6, -26, + 11, -14, 12, 9, 6, 29, + -14, -45, -30, -14, 30, -19, + -23, 20, -5, 9, -29, -31, + -3, 0, -71, -41, 3, -20, + -38, -38, 6, 16, -1, 47, + -3, -8, 17, 18, -12, -7, + 35, 5, 18, 23, 5, -23, + -13, 9, -18, -21, 22, 14, + -46, -25, 17, 27, 30, 3, + -14, 1, -25, -28, -2, -59, + 16, -7, -3, -24, 25, 8, + 8, 1, 17, 4, -10, 14, + -23, -17, -10, 16, -16, -13, + 0, -10, 36, -20, 7, -17, + -31, -12, -1, 9, 25, -5, + 6, 12, 7, 30, 12, -46, + -3, 4, 7, 1, 7, 4, + 18, -3, -18, 29, -37, 10, + 6, 16, 27, 26, 2, 36, + 33, -3, 5, -2, 4, 5, + -13, 7, 25, -1, -6, 36, + 6, 33, -9, -10, -27, -3, + 25, 15, 13, -1, 63, 46, + 7, -24, 12, 6, 49, -1, + 7, 22, 11, 7, -45, -1, + -18, -52, -51, 21, -15, -4, + 5, -19, -38, 2, 19, 17, + -21, -2, 7, 8, 35, 36, + 13, 8, -11, 15, 14, 33, + -6, -31, 29, 40, -1, -20, + -19, -23, -4, -32, -15, 29, + 21, -39, -22, 14, 9, -35, + -1, -14, 0, 38, 14, -3, + 9, 14, 1, 1, -6, 4, + -1, -6, -44, 41, 4, 28, + 60, -4, 17, -14, -43, -12, + -16, 24, -1, -25, 20, 12, + -41, -10, -8, -14, 5, 36, + 51, -14, 3, -23, 32, -16, + 36, 15, 22, 26, 4, -11, + -6, 4, 18, 24, 0, 36, + -24, -20, 9, -8, -4, -22, + 20, -21, 14, 19, 25, 12, + -34, -14, -30, 23, -22, -19, + 33, -17, 28, -21, -35, -20, + -46, 5, 5, -7, -3, 7, + 9, -35, -8, 23, -38, 9, + 2, -23, 18, 20, -22, -4, + -21, 19, -14, 1, 20, -7, + 39, 17, -33, 15, -2, 26, + 4, -27, 31, 13, 13, 15, + -21, 5, 30, -48, -42, -30, + -22, -37, -4, -8, 2, -16, + -22, 10, 38, -18, 10, 46, + -31, -14, -15, 12, -25, 8, + -19, -11, -22, 6, 18, -15, + -1, 3, -29, -5, -24, -29, + 55, -3, -16, -27, 30, 15, + 22, 13, 24, -23, -2, -22, + 27, 7, -10, 13, 46, -1, + -30, 19, 46, -10, -18, 25, + -28, -45, 1, -2, 10, 1, + 4, 17, 9, -24, -38, -13, + -2, 2, 18, -8, 9, -25, + -9, 26, -32, 34, 42, 14, + 21, -37, -36, -16, -31, -2, + 1, 35, -10, -22, 13, 1, + 4, 4, -9, -32, 7, -5, + -7, 4, 2, -45, -20, 13, + -39, -44, -15, -12, 15, 31, + 31, 4, 19, 3, 1, 11, + 26, -18, -36, -11, -23, -8, + 10, 43, 34, -3, 8, 10, + 5, -10, 24, -7, 7, -5, + -9, 27, -25, 14, 17, -5, + 25, 10, 6, -34, 45, 20, + -13, 5, -15, -9, 11, -20, + -4, -23, -10, 31, -31, -2, + 19, -17, -42, -21, 20, -2, + 20, -5, 23, -5, 5, 2, + 22, 13, 26, -35, 12, -3, + 24, -13, 8, 37, -33, 8, + 17, 44, 23, 16, 8, -2, + -43, 3, 36, -8, 2, -6, + -31, 27, 5, 3, -7, -6, + -4, -6, -9, 5, 3, 21, + -29, 2, 15, -22, 5, -5, + 22, 21, 16, 21, -5, -4, + -16, 31, -20, -24, 29, -29, + -29, -11, -2, 26, 13, 12, + 19, -15, -19, -43, -10, -8, + 17, -10, 22, -24, 22, -11, + -13, 14, 57, -16, -25, -33, + -27, -8, -15, 1, -29, 7, + 24, 19, 5, -3, 27, 26, + 0, -25, 9, -22, 10, -25, + 8, -11, -7, 1, -6, -54, + 5, -17, 7, 53, -2, 27, + 23, -33, 27, 13, -33, 1, + 23, 0, -41, -52, 10, -12, + -4, 32, 30, -7, 1, 1, + 16, 1, -30, -8, -24, 17, + 10, -19, 220, -83903, 2082308, -17183334, + 68943059, -156961250, 217523237, -188051721, 100341977, -31427845, + 5154185, -340975, 4068, -33, 5, -50, + 7, -16, 5, -6, -19, -10, + 11, 33, -13, 7, 21, 2, + 21, -11, 4, 17, 5, -4, + -26, 34, 28, -12, -17, -68, + 10, -3, -7, 1, -1, 7, + 6, -8, -13, 0, 6, -1, + 21, -43, -2, 35, 5, 6, + 21, 7, -3, 25, 9, 15, + -63, 8, -21, 15, 20, -10, +}; + +static const int32_t ifft_ref_real_3072_q31[3072] = { + -1954, 1267, -1428, -189, -2328, -332, + -2139, 2088, 1120, -504, -2966, -2008, + -3174, 846, -914, 1141, -2101, -1347, + 3027, -1403, -1333, 362, 1668, -927, + 1181, -1244, -225, -358, 228, -2786, + 2981, -1883, 1268, -3378, 837, -534, + -1694, -1442, -1609, 233, 657, 23, + -1344, 662, -1927, -982, -3378, -381, + -779, 844, 2776, 2991, -1622, -1119, + 3870, 265, -548, 2619, 4851, -163, + 1724, 2204, 750, 902, 2561, 4782, + 3436, 2236, 3459, 607, -2115, 1150, + 684, 206, -433, -699, -4322, -665, + -1792, -1032, -2476, -4106, -4595, -7403, + -5622, -4960, -3025, -6094, -4879, -5786, + -6701, -500, -3185, -2761, -3410, -1888, + 2902, 3236, 1579, 1072, 6289, 5865, + 3737, 7878, 10582, 11262, 5716, 8054, + 10346, 11274, 12870, 8232, 10221, 8739, + 9892, 9425, 8387, 2936, 1194, 3767, + 3503, -909, -5905, -5029, -9175, -10882, + -13511, -12505, -18920, -17241, -21785, -18975, + -18165, -21109, -20486, -23023, -18012, -19889, + -16786, -16232, -16213, -12552, -11375, -5925, + -3013, -68, 6753, 11006, 10410, 17275, + 18657, 26177, 27511, 30865, 35720, 36178, + 40779, 42618, 39224, 37957, 35824, 38634, + 33522, 32862, 26097, 23825, 18366, 10697, + 2542, -3672, -8849, -17950, -25991, -35087, + -41498, -47572, -51102, -58015, -62956, -68385, + -70399, -70984, -75068, -68763, -72106, -66894, + -60619, -53553, -47109, -36855, -27916, -17365, + -9085, 4803, 17617, 31120, 43881, 55889, + 67189, 80156, 92141, 98698, 106521, 111873, + 119040, 120646, 121770, 119358, 115558, 112068, + 103408, 89951, 80567, 66268, 48447, 35386, + 11202, -5637, -31755, -52096, -69437, -90322, + -113541, -131335, -149125, -165772, -176375, -189568, + -193607, -198890, -199959, -201103, -193177, -183881, + -169659, -150640, -131600, -112287, -80475, -51938, + -22370, 9892, 41497, 76822, 111071, 143854, + 174132, 205505, 236130, 261930, 279611, 299838, + 309539, 319576, 321418, 317950, 307013, 292425, + 272196, 248900, 217268, 174794, 134153, 89526, + 39276, -11100, -64816, -117792, -169261, -224363, + -272702, -320621, -363995, -405013, -436618, -461801, + -484416, -498480, -498357, -493096, -476616, -455593, + -423250, -379896, -334722, -274426, -209798, -142911, + -68726, 10645, 91081, 174972, 259533, 339980, + 415872, 486041, 556745, 615719, 664094, 704463, + 734385, 750620, 754842, 747862, 725129, 692003, + 643234, 579508, 509962, 422076, 326650, 221229, + 109587, -7844, -129406, -252356, -374193, -495182, + -610853, -720845, -820495, -906599, -985383, -1044324, + -1087653, -1116727, -1119971, -1110995, -1079312, -1030261, + -955116, -868440, -755018, -634629, -491612, -340000, + -174008, -2545, 175459, 357679, 534472, 711584, + 880611, 1044734, 1187234, 1319178, 1429981, 1514941, + 1579514, 1621514, 1632752, 1615925, 1570986, 1497739, + 1396079, 1264505, 1111550, 930262, 727987, 506360, + 270114, 20615, -236580, -496428, -752595, -1006049, + -1248329, -1478414, -1689987, -1875964, -2034697, -2162770, + -2260013, -2312597, -2336506, -2314000, -2246916, -2147191, + -1999537, -1819161, -1598211, -1339436, -1053219, -741591, + -404819, -52105, 309008, 673402, 1040004, 1399854, + 1743725, 2065359, 2364137, 2627629, 2852233, 3037607, + 3171927, 3252277, 3278896, 3252821, 3166834, 3019401, + 2821154, 2565178, 2259733, 1902289, 1505911, 1071868, + 604387, 114568, -390538, -901979, -1414555, -1914667, + -2392421, -2844993, -3257702, -3627354, -3937513, -4197246, + -4382927, -4499670, -4541377, -4505222, -4388437, -4193254, + -3917142, -3572652, -3149370, -2664511, -2114061, -1520182, + -878438, -206493, 488632, 1187065, 1887697, 2573079, + 3234344, 3854568, 4423382, 4930050, 5363304, 5713011, + 5974276, 6138366, 6197414, 6153614, 6000228, 5736857, + 5367596, 4895708, 4327978, 3670697, 2930826, 2121844, + 1253041, 345643, -591645, -1542721, -2491418, -3421573, + -4314585, -5153975, -5923671, -6613787, -7199081, -7676067, + -8032673, -8261748, -8344694, -8289718, -8091735, -7743502, + -7254200, -6625856, -5868940, -4992277, -4003982, -2924878, + -1768018, -551110, 699523, 1970706, 3241390, 4481897, + 5675977, 6800856, 7836039, 8754662, 9546004, 10185660, + 10671856, 10976049, 11105194, 11035120, 10778861, 10326591, + 9683699, 8861631, 7867395, 6705779, 5405603, 3980232, + 2454384, 850530, -805109, -2486513, -4160748, -5805891, + -7382307, -8869688, -10233575, -11456331, -12505369, -13360134, + -14001774, -14417847, -14592276, -14519772, -14192650, -13609416, + -12782143, -11705217, -10409849, -8901823, -7209623, -5352473, + -3361810, -1266846, 895532, 3091918, 5277170, 7420525, + 9489624, 11432011, 13218921, 14821879, 16198902, 17320553, + 18176905, 18728063, 18968219, 18889211, 18474356, 17736672, + 16676488, 15301851, 13630777, 11691303, 9503862, 7109981, + 4543576, 1837027, -952943, -3787629, -6616674, -9389765, + -12060838, -14575923, -16896520, -18966998, -20757833, -22225876, + -23339580, -24064965, -24399452, -24313960, -23801953, -22874513, + -21529058, -19786854, -17661695, -15187331, -12403054, -9343646, + -6061675, -2608238, 960215, 4587200, 8203769, 11754426, + 15171453, 18398050, 21370217, 24031857, 26331810, 28224976, + 29662244, 30620056, 31063943, 30981748, 30362653, 29208928, + 27521429, 25329400, 22653382, 19531351, 16013837, 12153017, + 7998716, 3631447, -887872, -5478882, -10065002, -14563158, + -18898704, -22992346, -26766793, -30153622, -33084231, -35497471, + -37346046, -38578296, -39177363, -39107071, -38357663, -36931725, + -34843569, -32109203, -28776745, -24879474, -20480119, -15636363, + -10440654, -4962221, 700614, 6457439, 12213225, 17863443, + 23312919, 28460670, 33212090, 37476766, 41174535, 44229347, + 46576727, 48162205, 48947682, 48902130, 48012213, 46278804, + 43713794, 40343588, 36215821, 31390803, 25937800, 19941472, + 13486924, 6681309, -359302, -7516992, -14675702, -21708040, + -28497166, -34910721, -40834521, -46165672, -50790519, -54624928, + -57581677, -59595573, -60621295, -60618413, -59571237, -57474927, + -54349703, -50239530, -45184393, -39261870, -32559111, -25183391, + -17240783, -8864180, -195070, 8633884, 17462285, 26142836, + 34521640, 42450999, 49782997, 56376985, 62114562, 66884038, + 70577659, 73119273, 74442582, 74504938, 73280556, 70778132, + 67008877, 62027743, 55891005, 48684209, 40526777, 31524482, + 21837075, 11608676, 1013426, -9776897, -20582082, -31205608, + -41468126, -51178912, -60175566, -68283677, -75344704, -81222512, + -85802753, -88973444, -90664439, -90820751, -89418368, -86452620, + -81948797, -75958944, -68566242, -59877640, -50011282, -39132078, + -27402568, -15013504, -2168131, 10918713, 24020964, 36927546, + 49396361, 61209585, 72158752, 82038947, 90660079, 97855090, + 103473914, 107407932, 109551924, 109843422, 108249115, 104763010, + 99421497, 92289068, 83455070, 73050647, 61227870, 48169481, + 34081773, 19187156, 3739342, -12004598, -27791472, -43333230, + -58365766, -72626836, -85851549, -97795818, -108239741, -116981970, + -123840767, -128671350, -131359123, -131835146, -130042269, -125987174, + -119707501, -111272601, -100798435, -88436623, -74369612, -58823550, + -42030940, -24264150, -5826716, 12986473, 31848307, 50441973, + 68433889, 85512134, 101368634, 115713840, 128269407, 138806740, + 147108818, 153002353, 156352203, 157056990, 155072795, 150393409, + 143062822, 133169262, 120845178, 106267660, 89657885, 71273294, + 51399725, 30366288, 8514011, -13792699, -36174735, -58248196, + -79627543, -99936507, -118812766, -135906620, -150905421, -163518325, + -173495056, -180624235, -184755195, -185764212, -183594689, -178240626, + -169750794, -158228079, -143834201, -126764583, -107293151, -85713607, + -62363318, -37632655, -11918011, 14346364, 40717861, 66742307, + 91968909, 115955469, 138267475, 158501540, 176282366, 191273980, + 203176778, 211748630, 216793410, 218187466, 215847622, 209772219, + 200013871, 186692507, 169996463, 150155667, 127480051, 102325892, + 75082013, 46198998, 16151019, -14561432, -45418844, -75894680, + -105459536, -133586607, -159787579, -183572791, -204511701, -222205628, + -236312691, -246538905, -252660476, -254524141, -252042329, -245203169, + -234069735, -218776002, -199541362, -176642414, -150419791, -121291048, + -89722588, -56220440, -21344396, 14334015, 50206743, 85657746, + 120072210, 152844393, 183400551, 211180477, 235674009, 256422421, + 273023557, 285141522, 292508799, 294952686, 292362193, 284725036, + 272111181, 254677613, 232669346, 206404757, 176282500, 142783969, + 106437823, 67830506, 27604415, -13569950, -54991741, -95959498, + -135761919, -173705841, -209109551, -241337116, -269805490, -293980085, + -313391229, -327649859, -336454096, -339589981, -336941047, -328484687, + -314290618, -294554567, -269534232, -239604639, -205232447, -166945906, + -125368449, -81167635, -35075166, 12139805, 59675747, 106722917, + 152463819, 196110460, 236875290, 274037087, 306914105, 334892098, + 357442746, 374110440, 384551660, 388518382, 385864545, 376568060, + 360714253, 338512455, 310255664, 276379501, 237393220, 193922019, + 146648837, 96353228, 43872047, -9932907, -64141763, -117837085, + -170085645, -219975310, -266629410, -309200944, -346939392, -379119852, + -405153604, -424514398, -436807953, -441745719, -439164716, -429031904, + -411439319, -386617372, -354913267, -316797073, -272860523, -223800373, + -170393396, -113518291, -54112519, 6827960, 68275656, 129182673, + 188492573, 245180555, 298245210, 346732971, 389775867, 426573829, + 456438737, 478787157, 493153292, 499220637, 496795613, 485840102, + 466452793, 438881992, 403526130, 360909673, 311691302, 256650303, + 196670827, 132739707, 65907805, -2700984, -71937130, -140610726, + -207548644, -271569377, -331569987, -386464900, -435269685, -477092614, + -511151438, -536775753, -553458247, -560822864, -558660166, -546903818, + -525680344, -495253593, -456060540, -408696645, -353886403, -292506414, + -225548912, -154104305, -79357989, -2561325, 74990181, 151972303, + 227066091, 298962161, 366405218, 428188514, 483211372, 530459862, + 569062016, 598277372, 617510900, 626356585, 624560000, 612060937, + 588968499, 555591130, 512411217, 460077642, 399402792, 331356454, + 257035710, 177661517, 94544543, 9078357, -77292654, -163096706, + -246858480, -327129277, -402500612, -471640542, -533309915, -586386059, + -629889889, -662987333, -685024657, -695536650, -694236254, -681048472, + -656096749, -619709358, -572413134, -514919077, -448139426, -373131135, + -291109258, -203418830, -111520436, -16947282, 78700085, 173795497, + 266706134, 355821766, 439583391, 516516093, 585243211, 644522213, + 693263322, 730544442, 755633273, 768005415, 767338814, 753543170, + 726752740, 687313915, 635809216, 573019067, 499930312, 417713744, + 327700363, 231372022, 130329737, 26257105, -79076016, -183887358, + -286366416, -384750216, -477320353, -562449725, -638616288, -704458907, + -758758447, -800507282, -828883506, -843307951, -843426655, -829126268, + -800540682, -758051926, -702285573, -634098007, -554555308, -464934509, + -366696843, -261459008, -150968810, -37078553, 78287202, 193169274, + 305590106, 413617022, 515363932, 609041209, 692999791, 765716620, + 825874328, 872350899, 904255173, 920933942, 921991897, 907302345, + 876995606, 831491084, 771450963, 697802833, 611711188, 514553522, + 407924872, 293581426, 173412732, 49450008, -76218165, -201462064, + -324123571, -442093130, -553318187, -655856510, -747889886, -827768644, + -894047369, -945499331, -981148121, -1000271653, -1002435558, -987487658, + -955564675, -907105489, -842828582, -763719588, -671045492, -566295061, + -451176469, -327596047, -197610656, -63402519, 72763028, 208568268, + 341689279, 469837824, 590779804, 702411793, 802756107, 890031701, + 962659652, 1019302373, 1058894770, 1080652653, 1084089892, 1069029267, + 1035616997, 984310463, 915868643, 831368539, 732138036, 619797618, + 496178710, 363330656, 223463581, 78932936, -67831952, -214321056, + -358035511, -496501573, -627322734, -748210245, -857045845, -951889207, + -1031046097, -1093063589, -1136783070, -1161342438, -1166218018, -1151211372, + -1116459710, -1062446233, -989977050, -900187067, -794513962, -674664651, + -542612066, -400545709, -250835618, -95987277, 61364836, 218559073, + 372902420, 521744972, 662503466, 792739349, 910160054, 1012694129, + 1098502669, 1166028599, 1214023809, 1241553437, 1248036967, 1233254419, + 1197341171, 1140794021, 1064475666, 969571958, 857622760, 730435171, + 590108274, 438970794, 279545597, 114515489, -53334992, -221140870, + -386048025, -545211956, -695892850, -835473083, -961502732, -1071771032, + -1164306249, -1237436513, -1289821237, -1320457758, -1328710489, -1314334805, + -1277454667, -1218590303, -1138644363, -1038872942, -920883135, -786610219, + -638256404, -478293472, -309391820, -134402940, 43720522, 221947038, + 397237986, 566582584, 727057401, 875882937, 1010467192, 1128437030, + 1227705429, 1306486153, 1363337657, 1397194988, 1407374023, 1393581661, + 1355955920, 1295029129, 1211727393, 1107379233, 983675309, 842639668, + 686599942, 518157159, 340132910, 155517872, -32551047, -220888680, + -406281117, -585536670, -755581427, -913471547, -1056447125, -1182018238, + -1287955758, -1372371364, -1433739680, -1470903413, -1483138046, -1470128386, + -1431988068, -1369264203, -1282936733, -1174373434, -1045338297, -897950837, + -734656662, -558176986, -371475445, -177689527, 19892513, 217915644, + 412997957, 601805608, 781081716, 947733928, 1098870125, 1231847160, + 1344327293, 1434310121, 1500180677, 1540715667, 1555129526, 1543084250, + 1504675269, 1440471194, 1351469669, 1239099003, 1105185102, 951940796, + 781910283, 597941305, 403111530, 200712781, -5824762, -212994191, + -417261433, -615130588, -803202090, -978230008, -1137190856, -1277301705, + -1396119506, -1491538873, -1561855656, -1605779457, -1622481182, -1611573682, + -1573160731, -1507799779, -1416525935, -1300804137, -1162532566, -1003997496, + -827842473, -637007723, -434707419, -224363857, -9529147, 206141110, + 418961991, 625309440, 821625264, 1004543936, 1170892474, 1317789291, + 1442668348, 1543329576, 1617986419, 1665291150, 1684353298, 1674763544, + 1636596958, 1570432320, 1477313125, 1358749421, 1216693848, 1053501196, + 871900049, 674928292, 465909734, 248374414, 26011493, -197396416, + -418047432, -632168499, -836088206, -1026306899, -1199532237, -1352774708, + -1483362122, -1589013138, -1667859380, -1718486820, -1739959414, -1731839850, + -1694188625, -1627580629, -1533073593, -1412212813, -1266996403, -1099843876, + -913551827, -711245725, -496342808, -272475963, -43448807, 186852460, + 414501321, 635605431, 846385683, 1043217713, 1222718789, 1381788185, + 1517669181, 1627982917, 1710811456, 1764671245, 1788582254, 1782075582, + 1745195237, 1678510734, 1583094073, 1460515358, 1312808363, 1142439233, + 952272960, 745500972, 525630752, 296374628, 61627773, -174619248, + -408338841, -635548976, -852356373, -1055039545, -1240132943, -1404437242, + -1545116122, -1659725677, -1746274508, -1803234452, -1829578860, -1824800936, + -1788947477, -1722558810, -1626723784, -1503026676, -1353526848, -1180736873, + -987560877, -777264714, -553400924, -319762014, -80323054, 160850975, + 399648300, 631989745, 853911556, 1061611842, 1251535835, 1420413179, + 1565341882, 1683813544, 1773777276, 1833658423, 1862393559, 1859456468, + 1824850431, 1759130098, 1663373112, 1539169746, 1388612600, 1214226013, + 1018956148, 806102039, 579277584, 342326951, 99278560, -145730951, + -388522944, -624972370, -851028582, -1062836348, -1256765856, -1429496044, + -1578067280, -1699914608, -1792940108, -1855530759, -1886589380, -1885556536, + -1852427918, -1787733942, -1692547773, -1568470823, -1417588696, -1242446357, + -1046016840, -831625333, -602914593, -363764440, -118246447, 129457933, + 375133133, 614592525, 843753094, 1058698702, 1255759245, 1431571485, + 1583116729, 1707807432, 1803502380, 1868552397, 1901829488, 1902756563, + 1871297545, 1807976709, 1713849715, 1590510399, 1440048829, 1265014746, + 1068377633, 853481494, 623978067, 383777980, 136958703, -112263451, + -359658453, -601001951, -832182190, -1049261424, -1248533642, -1426603203, + -1580431454, -1707395036, -1805325977, -1872546489, -1907914848, -1910818076, + -1881207464, -1819578191, -1726983553, -1604994703, -1455689253, -1281612422, + -1085724274, -871362313, -642175923, -402075595, -155149216, 94400503, + 342322888, 584392163, 816484983, 1034660863, 1235192607, 1414675018, + 1570047568, 1698683993, 1798381542, 1867461297, 1904749062, 1909622838, + 1882001675, 1822371202, 1731754856, 1611708739, 1464279918, 1291998989, + 1097800233, 885005516, 657247259, 418403559, 172550621, -76116588, + -323374830, -565003771, -796896074, -1015106272, -1215927587, -1395951522, + -1552119510, -1681791215, -1782773966, -1853368131, -1892388366, -1899186924, + -1873682131, -1816320639, -1728100774, -1610554472, -1465704675, -1296028376, + -1104443620, -894227806, -668969691, -432525248, -188924505, 57679224, + 303082074, 543110898, 773680753, 990874742, 1191013320, 1370694105, + 1526894338, 1656961319, 1758722067, 1830459298, 1870994518, 1879662164, + 1856352631, 1801500505, 1716070729, 1601552060, 1459928482, 1293641204, + 1105547943, 898884127, 677184136, 444236544, 204030905, -39343464, + -281738664, -519025295, -747170062, -962310760, -1160794862, -1339268137, + -1494721598, -1624539903, -1726553534, -1799057804, -1840866292, -1851309234, + -1830258511, -1778116140, -1695821581, -1584818150, -1447033124, -1284862132, + -1101101431, -898908590, -681765683, -453380283, -217663348, 21366067, + 259626629, 493069110, 717729127, 929798100, 1125685812, 1302090661, + 1456045329, 1584967615, 1686708061, 1759581633, 1802411603, 1814515303, + 1795749950, 1746490361, 1667630949, 1560573113, 1427192494, 1269816696, + 1091161725, 894307502, 682653795, 459821740, 229630215, -3991130, + -237055717, -465609152, -685757243, -893783125, -1086168150, -1259671175, + -1411386186, -1538775234, -1639723774, -1712577604, -1756151022, -1769776508, + -1753292116, -1707041151, -1631881051, -1529159258, -1400681659, -1248706757, + -1075861775, -885147434, -679849203, -463492936, -239788150, -12560413, + 214318410, 436985739, 651670077, 854731189, 1042749355, 1212561343, + 1361329636, 1486571568, 1586224427, 1658655883, 1702702675, 1717693933, + 1703455417, 1660303044, 1589054484, 1490989879, 1367857293, 1221819477, + 1055425710, 871558841, 673398885, 464352943, 248016103, 28083145, + -191694062, -407575006, -615898089, -813149104, -995999398, -1161377159, + -1306529815, -1429044289, -1526909689, -1598526684, -1642758694, -1658946878, + -1646894078, -1606895102, -1539711606, -1446581982, -1329160129, -1189527998, + -1030131177, -853735906, -663406443, -462421125, -254228780, -42401115, + 169451502, 377727713, 578892455, 769550429, 946492399, 1106757984, + 1247674256, 1366915397, 1462519769, 1532950547, 1577092743, 1594289529, + 1584334455, 1547501541, 1484506909, 1396511141, 1285109652, 1152267535, + 1000325188, 831938878, 650030018, 457742667, 258382869, 55359579, + -147847679, -347788933, -541079146, -724454918, -894832674, -1049365889, + -1185484078, -1300945379, -1393867499, -1462752000, -1506525019, -1524534111, + -1516573574, -1482884349, -1424138055, -1341436489, -1236269034, -1110525776, + -966421500, -806481853, -633479129, -450426376, -260462875, -66851522, + 127097697, 318089971, 502889675, 678382853, 841616839, 989876013, + 1120699644, 1231929704, 1321767154, 1388773428, 1431909652, 1450532073, + 1444440429, 1413846257, 1359367356, 1282038972, 1183278349, 1064856624, + 928864074, 777700150, 614008311, 440608109, 260508254, 76791586, + -107397743, -288930379, -464730860, -631837850, -787440176, -928960132, + -1054050908, -1160662595, -1247065451, -1311883567, -1354123178, -1373165346, + -1368802620, -1341217886, -1290981329, -1219063811, -1126791045, -1015827089, + -888150371, -746008746, -591888502, -428466615, -258572737, -85123526, + 88914651, 260589405, 426977848, 585294445, 732875277, 867275801, + 986273147, 1087921573, 1170581642, 1232944255, 1274053918, 1293320897, + 1290533012, 1265841361, 1219785598, 1153259730, 1067496103, 964053892, + 844793457, 711808351, 567446758, 414212914, 254760236, 91832935, + -71784776, -233305320, -389993434, -539216020, -678471866, -805456788, + -918066920, -1014479691, -1093137391, -1152807458, -1192573206, -1211874921, + -1210490051, -1188568015, -1146583692, -1085373537, -1006089058, -910161528, + -799331029, -675561646, -541023592, -398076238, -249186890, -96927127, + 56101333, 207288357, 354082194, 494010022, 624734728, 744083114, + 850106912, 941064500, 1015518034, 1072287608, 1110518956, 1129673954, + 1129534807, 1110224999, 1072183624, 1016175030, 943253900, 854764740, + 752304975, 637704638, 512982470, 380314468, 242013120, 100454613, + -41930954, -182719906, -319522396, -450050709, -572124797, -683715081, + -783002819, -868369891, -938459121, -992172259, -1028703484, -1047537853, + -1048477454, -1031613185, -997345311, -946374992, -879676080, -798477569, + -704258873, -598700531, -483679417, -361196098, -233396476, -102482455, + 29308002, 159719299, 286554702, 407677229, 521069555, 624855049, + 717336577, 797022777, 862641869, 913174983, 947866087, 966234173, + 968080713, 953484175, 922811838, 876683918, 816003691, 741894095, + 655709798, 559004050, 453483583, 341011967, 223540020, 103099760, + -18233260, -138395689, -255355128, -367156398, -471920516, -567930301, + -653616510, -727591722, -788690875, -835956443, -868701664, -886467574, + -889061508, -876552359, -849257612, -807750695, -752853186, -685576819, + -607171911, -519042242, -422762779, -320026739, -212630774, -102428770, + 8682967, 118812009, 226087388, 328720449, 424999500, 513333030, + 592286422, 660577795, 717148715, 761115072, 791827347, 808872127, + 812061714, 801441574, 777310902, 740181390, 690785229, 630053428, + 559110814, 479238032, 391861521, 298534506, 200878658, 100590430, + -607287, -100989423, -198849315, -292555237, -380548523, -461371351, + -533713558, -596424172, -648498641, -689151697, -717782049, -734005256, + -737643908, -728733948, -707537411, -674510484, -630317318, -575800816, + -511961435, -439971506, -361118572, -276793246, -188485832, -97722445, + -6061637, 84927343, 173708384, 258790208, 338756360, 412298791, + 478220506, 535463826, 583135683, 620504631, 647031770, 662348437, + 666300618, 658915978, 640416389, 611220585, 571908297, 523234948, + 466117071, 401592604, 330825586, 255073642, 175660907, 93972958, + 11416894, -70596785, -150687862, -227501411, -299770818, -366304718, + -426033185, -477990740, -521373453, -555521652, -579935619, -594295837, + -598441014, -592403331, -576366581, -550704622, -515936356, -472738946, + -421926566, -364421956, -301273613, -233600973, -162593440, -89496920, + -15564081, 57945801, 129777276, 198735962, 263673192, 323522023, + 377324214, 424207890, 463459128, 494471178, 516806828, 530161704, + 534390205, 529525253, 515722595, 493310268, 462743131, 424629406, + 379680615, 328731908, 272704910, 212598522, 149476632, 84436692, + 18611043, -46890106, -110946726, -172490471, -230497005, -284018193, + -332193404, -374253518, -409544375, -437542950, -457836446, -470163396, + -474396436, -470538010, -458741499, -439285478, -412576250, -379140208, + -339618079, -294740527, -245328608, -192258120, -136474880, -78950323, + -20684043, 37337800, 94123822, 148719315, 200232263, 247809979, + 290690028, 328191762, 359737003, 384846037, 403167797, 414462578, + 418612328, 415616471, 405608074, 388824822, 365627908, 336478576, + 301938852, 262645553, 219323761, 172742000, 123743307, 73167648, + 21900080, -29183756, -79218352, -127364108, -172827967, -214863012, + -252796088, -286026643, -314042942, -336429977, -352864310, -363132718, + -367129059, -364863616, -356429040, -342048284, -322028244, -296774094, + -266768316, -232579633, -194825815, -154197159, -111415846, -67221548, + -22393396, 22309840, 66124542, 108316468, 148196551, 185105519, + 218455448, 247719513, 272444601, 292265988, 306909294, 316172902, + 319976012, 318306257, 311259813, 299016336, 281847408, 260104006, + 234201035, 204634435, 171943983, 136726029, 99607937, 61229245, + 22277383, -16592151, -54723400, -91468534, -126228236, -158430959, + -187562953, -213164354, -234846478, -252284778, -265235499, -273534395, + -277099121, -275918277, -270073506, -259721509, -245096765, -226492670, + -204280869, -178875510, -150747495, -120413922, -88411837, -55306424, + -21669900, 11917494, 44880837, 76678439, 106778103, 134689892, + 159972738, 182223956, 201108612, 216348810, 227726051, 235104451, + 238398771, 237610161, 232803839, 224116370, 211735335, 195925346, + 176994801, 155311385, 131268473, 105311188, 77899862, 49524551, + 20673231, -8152563, -36466660, -63795119, -89689631, -113724103, + -135516162, -154729334, -171063592, -184287496, -194214077, -200713055, + -203732664, -203253125, -199335834, -192088497, -181685639, -168336364, + -152320108, -133926606, -113516594, -91451969, -68135088, -43975393, + -19395029, 5179829, 29338263, 52667285, 74792697, 95346363, + 114000498, 130472557, 144507874, 155901496, 164498743, 170184919, + 172911765, 172668424, 169499571, 163505275, 154819428, 143630524, + 130166712, 114681138, 97470938, 78844567, 59142464, 38718237, + 17918794, -2890238, -23353533, -43135381, -61900242, -79354061, + -95218074, -109237355, -121211123, -130960785, -138345116, -143280745, + -145714419, -145646556, -143111878, -138189432, -130990829, -121678718, + -110439552, -97488855, -83077526, -67467936, -50938253, -33790970, + -16323372, 1170024, 18382855, 35032469, 50844610, 65556934, + 78945328, 90799046, 100930128, 109201569, 115507170, 119753539, + 121907093, 121964702, 119952242, 115936776, 110019754, 102325119, + 93008244, 82261389, 70284961, 57293131, 43529865, 29234651, + 14669782, 72779, -14296826, -28212097, -41430023, -53743152, + -64955789, -74894358, -83414010, -90383998, -95716201, -99336816, + -101228066, -101364256, -99783104, -96540755, -91706720, -85398404, + -77736086, -68883213, -58999854, -48272828, -36895247, -25073075, + -13017290, -929976, 10982581, 22515118, 33483816, 43708142, + 53031199, 61303563, 68404150, 74229401, 78705238, 81769841, + 83400870, 83592764, 82367919, 79764133, 75845584, 70713662, + 64463816, 57222981, 49132592, 40343881, 31010088, 21309507, + 11408987, 1476574, -8313780, -17805847, -26834606, -35257362, + -42940370, -49768901, -55642345, -60471386, -64198025, -66767863, + -68164088, -68386583, -67440978, -65373000, -62227670, -58079637, + -53020760, -47150844, -40578759, -33434938, -25844740, -17946248, + -9882139, -1783854, 6202175, 13941288, 21315238, 28196425, + 34483059, 40077359, 44886111, 48859936, 51928205, 54068948, + 55255999, 55479035, 54764175, 53128559, 50625402, 47303227, + 43241873, 38519687, 33230138, 27466783, 21346265, 14970247, + 8455675, 1911983, -4545824, -10812044, -16774603, -22355449, + -27449074, -31989201, -35898928, -39137158, -41646925, -43408685, + -44400739, -44620314, -44085374, -42807115, -40826602, -38193991, + -34964509, -31193892, -26972036, -22367527, -17466953, -12367218, + -7146262, -1904869, 3267821, 8291041, 13080466, 17561039, + 21651499, 25306067, 28460581, 31066869, 33106592, 34537018, + 35360504, 35569033, 35167687, 34177966, 32634704, 30560883, + 28009270, 25036520, 21689186, 18040253, 14161727, 10113724, + 5974160, 1812535, -2298571, -6293363, -10098147, -13659222, + -16921043, -19827946, -22345389, -24432435, -26066901, -27223379, + -27898523, -28085752, -27792084, -27035106, -25834265, -24220063, + -22225270, -19894969, -17274748, -14414396, -11365505, -8185495, + -4931060, -1659560, 1575182, 4715237, 7711549, 10523077, + 13090914, 15387506, 17376138, 19029662, 20325401, 21250905, + 21795069, 21961365, 21753118, 21177274, 20250113, 19008061, + 17460596, 15654912, 13623473, 11397730, 9025297, 6557050, + 4019253, 1474121, -1045141, -3489662, -5831327, -8019809, + -10026099, -11818538, -13371276, -14669502, -15687477, -16419232, + -16856866, -16994403, -16845308, -16412914, -15714736, -14760202, + -13578426, -12191116, -10629600, -8921647, -7092202, -5190448, + -3239217, -1275934, 663046, 2554298, 4356076, 6044040, + 7594214, 8980359, 10182478, 11188168, 11974521, 12546254, + 12895773, 13014200, 12908086, 12587362, 12058446, 11338623, + 10439693, 9387813, 8201196, 6899320, 5509481, 4064219, + 2576865, 1080047, -400703, -1839939, -3214850, -4504065, + -5687108, -6747572, -7663672, -8435009, -9043227, -9484985, + -9753642, -9849076, -9779353, -9541923, -9151368, -8610339, + -7937707, -7149141, -6254080, -5276073, -4231361, -3138920, + -2020649, -894056, 222733, 1305993, 2340866, 3311888, + 4207117, 5005958, 5703280, 6283490, 6745544, 7082468, + 7287202, 7363976, 7317850, 7144786, 6853114, 6459652, + 5959086, 5371726, 4711175, 3985262, 3204339, 2395324, + 1564483, 723119, -105777, -909733, -1683889, -2405419, + -3074924, -3671133, -4188416, -4623151, -4966669, -5217822, + -5376505, -5438699, -5406246, -5282262, -5074698, -4786421, + -4415698, -3989649, -3503458, -2971553, -2398392, -1804213, + -1193619, -576390, 32462, 628385, 1194781, 1727140, + 2213574, 2652369, 3033564, 3352595, 3609052, 3797641, + 3911246, 3962598, 3939600, 3852699, 3701594, 3492114, + 3230424, 2916926, 2563901, 2181899, 1765468, 1336348, + 897255, 451524, 10400, -423355, -833387, -1217639, + -1571274, -1889254, -2165240, -2398526, -2581778, -2722473, + -2806177, -2843650, -2829585, -2769524, -2663939, -2516691, + -2327935, -2105389, -1854132, -1579438, -1284757, -976868, + -663162, -345625, -29806, 277631, 573265, 848377, + 1098155, 1323542, 1523169, 1692667, 1820388, 1921574, + 1980041, 2009485, 2000458, 1958506, 1882804, 1781576, + 1650184, 1491210, 1315288, 1123764, 920326, 700329, + 478507, 256533, 32026, -180003, -384095, -577687, + -756750, -917410, -1053764, -1170111, -1262779, -1332577, + -1375847, -1391609, -1392675, -1362480, -1311761, -1240430, + -1148291, -1039811, -917895, -784334, -643710, -496828, + -337593, -185408, -35103, 113070, 255859, 384329, + 506227, 617511, 714746, 795605, 860777, 906972, + 935925, 948904, 945758, 926027, 895773, 846226, + 784240, 710311, 628903, 537754, 444898, 341692, + 241505, 133447, 30958, -72515, -164395, -255320, + -334239, -410321, -475067, -526756, -573940, -605247, + -622819, -637482, -631446, -619838, -596390, -563572, + -523754, -477660, -426306, -363560, -295189, -230207, + -163718, -95093, -25083, 39224, 104809, 164493, + 216339, 268715, 307770, 343381, 376591, 393894, + 409214, 415048, 414650, 407176, 388288, 370122, + 344328, 309042, 277273, 235390, 198767, 149968, + 107391, 64774, 22734, -22484, -65777, -100024, + -134431, -168338, -196571, -218070, -239916, -252287, + -260207, -264251, -263475, -255361, -249920, -233428, + -219729, -200561, -178348, -152486, -126879, -98039, + -68509, -40108, -12510, 10116, 37364, 62735, + 83265, 105535, 122744, 134992, 146756, 157803, + 160999, 161373, 164013, 160462, 154774, 144884, + 134790, 126783, 107178, 92058, 76572, 57882, + 43557, 26865, 12612, -4122, -19611, -34312, + -50182, -64020, -71989, -80713, -88451, -93341, + -97703, -97951, -98271, -96134, -93821, -85291, + -81741, -74008, -66399, -57833, -47278, -35028, + -26476, -14656, -4700, 3292, 15438, 21244, + 29516, 33116, 42333, 47158, 49673, 56057, + 53914, 56647, 58612, 53778, 50181, 53182, + 46382, 38717, 37541, 30440, 26852, 21271, + 13076, 9386, 4881, -3217, -6456, -9167, + -14339, -21479, -24043, -24056, -31348, -29829, + -29018, -30209, -31831, -31798, -28027, -29569, + -25967, -24517, -21618, -18204, -15378, -12502, + -9278, -7266, -3404, 3091, 4309, 6623, + 9973, 9739, 10030, 12920, 16929, 18390, + 15259, 16991, 14629, 15567, 17209, 11571, + 14371, 12597, 11641, 9273, 6978, 8908, + 3725, -56, 2695, -189, -624, -3726, + -4651, -5443, -6305, -5793, -8874, -6473, + -7155, -7928, -4337, -5197, -10879, -8256, + -9328, -5819, -4801, -1061, -4140, -2848, + -5058, 450, 134, -988, -2654, -529, + 1305, -1503, 1327, 2653, 2727, 3765, + 1663, 2376, 5098, 3599, 2627, 4534, + 1709, 4472, 1626, 4200, -688, 1716, + 455, 2684, -1687, -2322, 540, 278, + 2327, 931, -1176, -108, -3519, -317, + -1225, -1108, -971, -844, -2534, -1462, + -554, -41, -29, -263, -2482, 614, + -2090, 576, -2654, -2080, 656, 174, + -297, -1757, 738, -493, 1359, 229, + 934, -956, -1365, -707, 3858, 1771, + 799, -1000, -779, -93, -1114, 804, + -1730, -1932, -731, 1052, 108, -1784, + -1167, -1073, 2003, 441, -543, -445, + -1474, 253, -2753, 1985, -2835, 1736, +}; + +static const int32_t ifft_ref_imag_3072_q31[3072] = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; diff --git a/test/cmocka/src/math/matrix/matrix.c b/test/cmocka/src/math/matrix/matrix.c index 66200bc3e632..63632ba58c4b 100644 --- a/test/cmocka/src/math/matrix/matrix.c +++ b/test/cmocka/src/math/matrix/matrix.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -23,6 +24,8 @@ #define MATRIX_MULT_16_MAX_ERROR_ABS 1.5 #define MATRIX_MULT_16_MAX_ERROR_RMS 0.5 +struct processing_module dummy; + static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, const int16_t *c_ref, int elementwise, int a_rows, int a_columns, int b_rows, int b_columns, int c_rows, int c_columns, @@ -38,20 +41,20 @@ static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, cons int16_t x; int i, j, k; - a_matrix = mat_matrix_alloc_16b(a_rows, a_columns, a_frac); + a_matrix = mod_mat_matrix_alloc_16b(&dummy, a_rows, a_columns, a_frac); if (!a_matrix) exit(EXIT_FAILURE); - b_matrix = mat_matrix_alloc_16b(b_rows, b_columns, b_frac); + b_matrix = mod_mat_matrix_alloc_16b(&dummy, b_rows, b_columns, b_frac); if (!b_matrix) { - free(a_matrix); + mod_free(&dummy, a_matrix); exit(EXIT_FAILURE); } - c_matrix = mat_matrix_alloc_16b(c_rows, c_columns, c_frac); + c_matrix = mod_mat_matrix_alloc_16b(&dummy, c_rows, c_columns, c_frac); if (!c_matrix) { - free(a_matrix); - free(b_matrix); + mod_free(&dummy, a_matrix); + mod_free(&dummy, b_matrix); exit(EXIT_FAILURE); } @@ -83,6 +86,10 @@ static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, cons assert_true(error_rms < MATRIX_MULT_16_MAX_ERROR_RMS); assert_true(delta_max < MATRIX_MULT_16_MAX_ERROR_ABS); + + mod_free(&dummy, a_matrix); + mod_free(&dummy, b_matrix); + mod_free(&dummy, c_matrix); } static void test_matrix_mult_16_test1(void **state) diff --git a/test/cmocka/src/math/window/window.c b/test/cmocka/src/math/window/window.c index 3e04c452f6bd..82e0f66a6bec 100644 --- a/test/cmocka/src/math/window/window.c +++ b/test/cmocka/src/math/window/window.c @@ -54,7 +54,7 @@ static float test_window(char *window_name, const int16_t *ref_win, int window_l if (!strcmp(window_name, "rectangular")) { win_rectangular_16b(win, window_length); } else if (!strcmp(window_name, "blackman")) { - win_blackman_16b(win, window_length, WIN_BLACKMAN_A0); + win_blackman_16b(win, window_length, WIN_BLACKMAN_A0_Q15); } else if (!strcmp(window_name, "hamming")) { win_hamming_16b(win, window_length); } else if (!strcmp(window_name, "povey")) { diff --git a/test/cmocka/src/util.h b/test/cmocka/src/util.h index 42d0700804c6..38561e81e42e 100644 --- a/test/cmocka/src/util.h +++ b/test/cmocka/src/util.h @@ -23,7 +23,7 @@ static inline struct comp_buffer *create_test_sink(struct comp_dev *dev, }, .size = buffer_size, }; - struct comp_buffer *buffer = buffer_new(&desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buffer = buffer_new(NULL, &desc, BUFFER_USAGE_NOT_SHARED); memset(buffer->stream.addr, 0, buffer_size); @@ -58,7 +58,7 @@ static inline struct comp_buffer *create_test_source(struct comp_dev *dev, }, .size = buffer_size, }; - struct comp_buffer *buffer = buffer_new(&desc, BUFFER_USAGE_NOT_SHARED); + struct comp_buffer *buffer = buffer_new(NULL, &desc, BUFFER_USAGE_NOT_SHARED); memset(buffer->stream.addr, 0, buffer_size); diff --git a/test/ztest/unit/common/alloc.c b/test/ztest/unit/common/alloc.c new file mode 100644 index 000000000000..d00dc3c7b831 --- /dev/null +++ b/test/ztest/unit/common/alloc.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright(c) 2026 Intel Corporation. All rights reserved. */ + +#include +#include + +#include +#include +#include +#include + +void *__wrap_rzalloc(uint32_t flags, size_t bytes) +{ + void *ret; + (void)flags; + + ret = malloc(bytes); + + zassert_not_null(ret, "Memory allocation should not fail"); + + memset(ret, 0, bytes); + + return ret; +} + +void __wrap_rfree(void *ptr) +{ + free(ptr); +} + +struct k_heap; +void *__wrap_sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, size_t alignment) +{ + void *ret; + + (void)flags; + (void)heap; + + if (alignment) + ret = aligned_alloc(alignment, ALIGN_UP(bytes, alignment)); + else + ret = malloc(bytes); + + zassert_not_null(ret, "Memory allocation should not fail"); + + return ret; +} + +void __wrap_sof_heap_free(struct k_heap *heap, void *ptr) +{ + (void)heap; + + free(ptr); +} + +struct k_heap *__wrap_sof_sys_heap_get(void) +{ + return NULL; +} diff --git a/test/ztest/unit/fast-get/CMakeLists.txt b/test/ztest/unit/fast-get/CMakeLists.txt index 45de96da341c..6123a9402394 100644 --- a/test/ztest/unit/fast-get/CMakeLists.txt +++ b/test/ztest/unit/fast-get/CMakeLists.txt @@ -16,16 +16,16 @@ target_include_directories(app PRIVATE # Define SOF-specific configurations for unit testing target_compile_definitions(app PRIVATE - -DCONFIG_SOF_LOG_LEVEL=CONFIG_LOG_DEFAULT_LEVEL -DCONFIG_ZEPHYR_POSIX=1 ) target_sources(app PRIVATE test_fast_get_ztest.c ${SOF_ROOT}/zephyr/lib/fast-get.c + ${SOF_ROOT}/test/ztest/unit/common/alloc.c ) -target_link_libraries(app PRIVATE "-Wl,--wrap=rzalloc,--wrap=rmalloc,--wrap=rfree") +target_link_libraries(app PRIVATE "-Wl,--wrap=rzalloc,--wrap=rfree,--wrap=sof_heap_alloc,--wrap=sof_heap_free") # Add RELATIVE_FILE definitions for SOF trace functionality sof_append_relative_path_definitions(app) diff --git a/test/ztest/unit/fast-get/prj.conf b/test/ztest/unit/fast-get/prj.conf index 9467c2926896..d34c7781cd0a 100644 --- a/test/ztest/unit/fast-get/prj.conf +++ b/test/ztest/unit/fast-get/prj.conf @@ -1 +1,2 @@ CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/fast-get/test_fast_get_ztest.c b/test/ztest/unit/fast-get/test_fast_get_ztest.c index f43f9c1bbd14..03434a026ed2 100644 --- a/test/ztest/unit/fast-get/test_fast_get_ztest.c +++ b/test/ztest/unit/fast-get/test_fast_get_ztest.c @@ -6,6 +6,7 @@ // generative artificial intelligence solutions. #include +#include #include #include @@ -55,39 +56,6 @@ static const int testdata[33][100] = { { 33 }, }; -/* Mock memory allocation functions for testing purposes */ - -void *__wrap_rzalloc(uint32_t flags, size_t bytes) -{ - void *ret; - (void)flags; - - ret = malloc(bytes); - - zassert_not_null(ret, "Memory allocation should not fail"); - - memset(ret, 0, bytes); - - return ret; -} - -void *__wrap_rmalloc(uint32_t flags, size_t bytes) -{ - void *ret; - (void)flags; - - ret = malloc(bytes); - - zassert_not_null(ret, "Memory allocation should not fail"); - - return ret; -} - -void __wrap_rfree(void *ptr) -{ - free(ptr); -} - /** * @brief Test basic fast_get and fast_put functionality * @@ -98,13 +66,13 @@ ZTEST(fast_get_suite, test_simple_fast_get_put) { const void *ret; - ret = fast_get(testdata[0], sizeof(testdata[0])); + ret = fast_get(NULL, testdata[0], sizeof(testdata[0])); zassert_not_null(ret, "fast_get should return valid pointer"); zassert_mem_equal(ret, testdata[0], sizeof(testdata[0]), "Returned data should match original data"); - fast_put(ret); + fast_put(NULL, ret); } /** @@ -117,16 +85,16 @@ ZTEST(fast_get_suite, test_fast_get_size_missmatch_test) { const void *ret[2]; - ret[0] = fast_get(testdata[0], sizeof(testdata[0])); + ret[0] = fast_get(NULL, testdata[0], sizeof(testdata[0])); zassert_not_null(ret[0], "First fast_get should succeed"); zassert_mem_equal(ret[0], testdata[0], sizeof(testdata[0]), "Returned data should match original data"); - ret[1] = fast_get(testdata[0], sizeof(testdata[0]) + 1); + ret[1] = fast_get(NULL, testdata[0], sizeof(testdata[0]) + 1); zassert_is_null(ret[1], "fast_get with different size should return NULL"); - fast_put(ret[0]); + fast_put(NULL, ret[0]); } /** @@ -141,14 +109,14 @@ ZTEST(fast_get_suite, test_over_32_fast_gets_and_puts) int i; for (i = 0; i < ARRAY_SIZE(copy); i++) - copy[i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy); i++) zassert_mem_equal(copy[i], testdata[i], sizeof(testdata[0]), "Data at index %d should match original", i); for (i = 0; i < ARRAY_SIZE(copy); i++) - fast_put(copy[i]); + fast_put(NULL, copy[i]); } /** @@ -164,10 +132,10 @@ ZTEST(fast_get_suite, test_fast_get_refcounting) int i; for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - copy[0][i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[0][i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - copy[1][i] = fast_get(testdata[i], sizeof(testdata[0])); + copy[1][i] = fast_get(NULL, testdata[i], sizeof(testdata[0])); for (i = 0; i < ARRAY_SIZE(copy[0]); i++) zassert_equal_ptr(copy[0][i], copy[1][i], @@ -179,7 +147,7 @@ ZTEST(fast_get_suite, test_fast_get_refcounting) /* Release first set of references */ for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - fast_put(copy[0][i]); + fast_put(NULL, copy[0][i]); /* Data should still be valid through second set of references */ for (i = 0; i < ARRAY_SIZE(copy[0]); i++) @@ -188,7 +156,7 @@ ZTEST(fast_get_suite, test_fast_get_refcounting) /* Release second set of references */ for (i = 0; i < ARRAY_SIZE(copy[0]); i++) - fast_put(copy[1][i]); + fast_put(NULL, copy[1][i]); } /** diff --git a/test/ztest/unit/list/prj.conf b/test/ztest/unit/list/prj.conf index 9467c2926896..d34c7781cd0a 100644 --- a/test/ztest/unit/list/prj.conf +++ b/test/ztest/unit/list/prj.conf @@ -1 +1,2 @@ CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/list/test_list_ztest.c b/test/ztest/unit/list/test_list_ztest.c index f9cd8031c41a..38dc72a3f9f5 100644 --- a/test/ztest/unit/list/test_list_ztest.c +++ b/test/ztest/unit/list/test_list_ztest.c @@ -162,4 +162,56 @@ ZTEST(sof_list_suite, test_list_item_is_last) "item2 should be the last item in the list"); } +/** + * @brief Test list_relink functionality + * + * Tests that list_relink correctly updates references when a list head is moved + */ +ZTEST(sof_list_suite, test_list_relink) +{ + struct list_item old_head; + struct list_item new_head; + struct list_item item1; + struct list_item item2; + + /* Test case 1: Empty list relinking */ + list_init(&old_head); + new_head = old_head; /* Copy the old head structure */ + + list_relink(&new_head, &old_head); + + /* After relinking empty list, new_head should be properly initialized */ + zassert_equal(&new_head, new_head.next, + "Empty list: new_head->next should point to itself"); + zassert_equal(&new_head, new_head.prev, + "Empty list: new_head->prev should point to itself"); + + /* Test case 2: Non-empty list relinking */ + list_init(&old_head); + list_item_append(&item1, &old_head); + list_item_append(&item2, &old_head); + + /* Verify initial state - items point to old_head */ + zassert_equal(&old_head, item1.prev, "Initial: item1 prev should point to old_head"); + zassert_equal(&old_head, item2.next, "Initial: item2 next should point to old_head"); + + /* Simulate moving list to new location by copying head structure */ + new_head = old_head; + /* Now new_head.next points to item1, new_head.prev points to item2 */ + /* But item1.prev and item2.next still point to &old_head */ + + /* Perform the relinking */ + list_relink(&new_head, &old_head); + + /* After relinking, items should now point to new_head instead of old_head */ + zassert_equal(&new_head, item1.prev, "After relink: item1 prev should point to new_head"); + zassert_equal(&new_head, item2.next, "After relink: item2 next should point to new_head"); + zassert_equal(&item1, new_head.next, "After relink: new_head next should point to item1"); + zassert_equal(&item2, new_head.prev, "After relink: new_head prev should point to item2"); + + /* Verify list integrity - items should still be properly linked */ + zassert_equal(&item2, item1.next, "After relink: item1 next should point to item2"); + zassert_equal(&item1, item2.prev, "After relink: item2 prev should point to item1"); +} + ZTEST_SUITE(sof_list_suite, NULL, NULL, NULL, NULL, NULL); diff --git a/test/ztest/unit/math/advanced/functions/CMakeLists.txt b/test/ztest/unit/math/advanced/functions/CMakeLists.txt new file mode 100644 index 000000000000..04fc940b916b --- /dev/null +++ b/test/ztest/unit/math/advanced/functions/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_math_advanced_functions) + +set(SOF_ROOT "${PROJECT_SOURCE_DIR}/../../../../../..") + +# Set SOF top directory for UUID registry generation +set(sof_top_dir ${SOF_ROOT}) + +# Include SOF CMake utilities for proper SOF source compilation +include(${SOF_ROOT}/scripts/cmake/misc.cmake) +include(${SOF_ROOT}/scripts/cmake/uuid-registry.cmake) + +target_include_directories(app PRIVATE + ${SOF_ROOT}/zephyr/include + ${SOF_ROOT}/src/include + ${SOF_ROOT}/src/platform/posix/include + ${SOF_ROOT}/test/cmocka/include + ${PROJECT_BINARY_DIR}/include/generated # For uuid-registry.h +) + +# Define SOF-specific configurations for unit testing +target_compile_definitions(app PRIVATE + -DCONFIG_ZEPHYR_POSIX=1 + -DCONFIG_LIBRARY=1 + -DUNIT_TEST=1 +) + +target_sources(app PRIVATE + test_scalar_power_ztest.c + ${SOF_ROOT}/src/math/power.c +) + +# Apply SOF relative path definitions for proper compilation +sof_append_relative_path_definitions(app) + +# Link math library for advanced math functions +target_link_libraries(app PRIVATE m) diff --git a/test/ztest/unit/math/advanced/functions/prj.conf b/test/ztest/unit/math/advanced/functions/prj.conf new file mode 100644 index 000000000000..d34c7781cd0a --- /dev/null +++ b/test/ztest/unit/math/advanced/functions/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/math/advanced/functions/test_scalar_power_ztest.c b/test/ztest/unit/math/advanced/functions/test_scalar_power_ztest.c new file mode 100644 index 000000000000..a3c2d6fe911c --- /dev/null +++ b/test/ztest/unit/math/advanced/functions/test_scalar_power_ztest.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// These contents may have been developed with support from one or more Intel-operated +// generative artificial intelligence solutions. +// +// Converted from CMock to Ztest +// +// Original test from sof/test/cmocka/src/math/arithmetic/scalar_power.c: +// Author: Shriram Shastry + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(test_scalar_power, LOG_LEVEL_INF); + +/* Test data tables from MATLAB-generated reference */ +#include "power_tables.h" + +/* Error tolerance: max error = 0.000034912111005, THD+N = -96.457180359025074 */ +#define CMP_TOLERANCE 0.0000150363575813f + +/** + * @brief Test scalar power function with fixed-point arithmetic + * + * This test validates the power_int32() function against MATLAB-generated + * reference values. It tests 64 base values against 6 exponent values, + * checking that the fixed-point power calculation stays within acceptable + * tolerance. + * + * Base values: Fixed-point Q6.25 format (range -1.0 to 1.0) + * Exponent values: Fixed-point Q2.29 format + * Result: Fixed-point Q16.15 format + */ +ZTEST(math_advanced_functions_suite, test_math_arithmetic_power_fixed) +{ + double p; + int i; + int j; + + for (i = 0; i < ARRAY_SIZE(b); i++) { + for (j = 0; j < ARRAY_SIZE(e); j++) { + p = power_int32(b[i], e[j]); + float delta = fabsf((float)(power_table[i][j] - (double)p / (1 << 15))); + + zassert_true(delta <= CMP_TOLERANCE, + "Power calc error: delta=%f > %f at b[%d]=%d, e[%d]=%d", + (double)delta, (double)CMP_TOLERANCE, i, b[i], j, e[j]); + } + } +} + +ZTEST_SUITE(math_advanced_functions_suite, NULL, NULL, NULL, NULL, NULL); diff --git a/test/ztest/unit/math/advanced/functions/testcase.yaml b/test/ztest/unit/math/advanced/functions/testcase.yaml new file mode 100644 index 000000000000..6c2dc68751a5 --- /dev/null +++ b/test/ztest/unit/math/advanced/functions/testcase.yaml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright(c) 2025 Intel Corporation. All rights reserved. +# +# Math advanced functions unit tests for Ztest framework +# +# These contents may have been developed with support from one or more Intel-operated +# generative artificial intelligence solutions. +# + +tests: + math.advanced.functions: + tags: math advanced functions power + platform_allow: native_sim + integration_platforms: + - native_sim + build_only: false diff --git a/test/ztest/unit/math/basic/arithmetic/CMakeLists.txt b/test/ztest/unit/math/basic/arithmetic/CMakeLists.txt index b6822ca7f2a2..8b280a0dfb49 100644 --- a/test/ztest/unit/math/basic/arithmetic/CMakeLists.txt +++ b/test/ztest/unit/math/basic/arithmetic/CMakeLists.txt @@ -12,7 +12,6 @@ target_include_directories(app PRIVATE # Define SOF-specific configurations for unit testing target_compile_definitions(app PRIVATE - -DCONFIG_SOF_LOG_LEVEL=CONFIG_LOG_DEFAULT_LEVEL -DCONFIG_ZEPHYR_POSIX=1 -DCONFIG_LIBRARY=1 -DCONFIG_NUMBERS_VECTOR_FIND=1 diff --git a/test/ztest/unit/math/basic/arithmetic/prj.conf b/test/ztest/unit/math/basic/arithmetic/prj.conf index 9467c2926896..d34c7781cd0a 100644 --- a/test/ztest/unit/math/basic/arithmetic/prj.conf +++ b/test/ztest/unit/math/basic/arithmetic/prj.conf @@ -1 +1,2 @@ CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/math/basic/trigonometry/CMakeLists.txt b/test/ztest/unit/math/basic/trigonometry/CMakeLists.txt new file mode 100644 index 000000000000..90b636fa940c --- /dev/null +++ b/test/ztest/unit/math/basic/trigonometry/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_math_trigonometry) + +set(SOF_ROOT "${PROJECT_SOURCE_DIR}/../../../../../..") + +target_include_directories(app PRIVATE + ${SOF_ROOT}/zephyr/include + ${SOF_ROOT}/src/include +) + +# Define SOF-specific configurations for unit testing +target_compile_definitions(app PRIVATE + -DCONFIG_ZEPHYR_POSIX=1 + -DCONFIG_LIBRARY=1 + -DUNIT_TEST=1 +) + +target_sources(app PRIVATE + trig_test.c + ${SOF_ROOT}/src/math/trig.c + ${SOF_ROOT}/src/math/lut_trig.c +) + +# Link math library for standard math functions +target_link_libraries(app PRIVATE m) diff --git a/test/ztest/unit/math/basic/trigonometry/prj.conf b/test/ztest/unit/math/basic/trigonometry/prj.conf new file mode 100644 index 000000000000..d34c7781cd0a --- /dev/null +++ b/test/ztest/unit/math/basic/trigonometry/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/math/basic/trigonometry/testcase.yaml b/test/ztest/unit/math/basic/trigonometry/testcase.yaml new file mode 100644 index 000000000000..037fbcaac456 --- /dev/null +++ b/test/ztest/unit/math/basic/trigonometry/testcase.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright(c) 2025 Intel Corporation. All rights reserved. +# +# Math basic trigonometry unit tests converted from CMock to Ztest +# +# These contents may have been developed with support from one or more Intel-operated +# generative artificial intelligence solutions. +# + +common: + tags: + - SOF + - unit_test + - math + - trigonometry + integration_platforms: + - native_sim + arch_exclude: xtensa # Test is for host builds only + +tests: + sof.unit.math.trigonometry: + platform_allow: + - native_sim diff --git a/test/ztest/unit/math/basic/trigonometry/trig_tables.h b/test/ztest/unit/math/basic/trigonometry/trig_tables.h new file mode 100644 index 000000000000..33405231cf48 --- /dev/null +++ b/test/ztest/unit/math/basic/trigonometry/trig_tables.h @@ -0,0 +1,371 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2025 Intel Corporation. All rights reserved. + */ + +#ifndef __SOF_ZTEST_TRIG_TABLES_H__ +#define __SOF_ZTEST_TRIG_TABLES_H__ + +/* Reference table generated by sin(), gcc-4.3.2 */ +static const float sin_ref_table[] = { + 0.0000000000, 0.0174524064, 0.0348994967, 0.0523359562, + 0.0697564737, 0.0871557427, 0.1045284633, 0.1218693434, + 0.1391731010, 0.1564344650, 0.1736481777, 0.1908089954, + 0.2079116908, 0.2249510543, 0.2419218956, 0.2588190451, + 0.2756373558, 0.2923717047, 0.3090169944, 0.3255681545, + 0.3420201433, 0.3583679495, 0.3746065934, 0.3907311285, + 0.4067366431, 0.4226182617, 0.4383711468, 0.4539904997, + 0.4694715628, 0.4848096202, 0.5000000000, 0.5150380749, + 0.5299192642, 0.5446390350, 0.5591929035, 0.5735764364, + 0.5877852523, 0.6018150232, 0.6156614753, 0.6293203910, + 0.6427876097, 0.6560590290, 0.6691306064, 0.6819983601, + 0.6946583705, 0.7071067812, 0.7193398003, 0.7313537016, + 0.7431448255, 0.7547095802, 0.7660444431, 0.7771459615, + 0.7880107536, 0.7986355100, 0.8090169944, 0.8191520443, + 0.8290375726, 0.8386705679, 0.8480480962, 0.8571673007, + 0.8660254038, 0.8746197071, 0.8829475929, 0.8910065242, + 0.8987940463, 0.9063077870, 0.9135454576, 0.9205048535, + 0.9271838546, 0.9335804265, 0.9396926208, 0.9455185756, + 0.9510565163, 0.9563047560, 0.9612616959, 0.9659258263, + 0.9702957263, 0.9743700648, 0.9781476007, 0.9816271834, + 0.9848077530, 0.9876883406, 0.9902680687, 0.9925461516, + 0.9945218954, 0.9961946981, 0.9975640503, 0.9986295348, + 0.9993908270, 0.9998476952, 1.0000000000, 0.9998476952, + 0.9993908270, 0.9986295348, 0.9975640503, 0.9961946981, + 0.9945218954, 0.9925461516, 0.9902680687, 0.9876883406, + 0.9848077530, 0.9816271834, 0.9781476007, 0.9743700648, + 0.9702957263, 0.9659258263, 0.9612616959, 0.9563047560, + 0.9510565163, 0.9455185756, 0.9396926208, 0.9335804265, + 0.9271838546, 0.9205048535, 0.9135454576, 0.9063077870, + 0.8987940463, 0.8910065242, 0.8829475929, 0.8746197071, + 0.8660254038, 0.8571673007, 0.8480480962, 0.8386705679, + 0.8290375726, 0.8191520443, 0.8090169944, 0.7986355100, + 0.7880107536, 0.7771459615, 0.7660444431, 0.7547095802, + 0.7431448255, 0.7313537016, 0.7193398003, 0.7071067812, + 0.6946583705, 0.6819983601, 0.6691306064, 0.6560590290, + 0.6427876097, 0.6293203910, 0.6156614753, 0.6018150232, + 0.5877852523, 0.5735764364, 0.5591929035, 0.5446390350, + 0.5299192642, 0.5150380749, 0.5000000000, 0.4848096202, + 0.4694715628, 0.4539904997, 0.4383711468, 0.4226182617, + 0.4067366431, 0.3907311285, 0.3746065934, 0.3583679495, + 0.3420201433, 0.3255681545, 0.3090169944, 0.2923717047, + 0.2756373558, 0.2588190451, 0.2419218956, 0.2249510543, + 0.2079116908, 0.1908089954, 0.1736481777, 0.1564344650, + 0.1391731010, 0.1218693434, 0.1045284633, 0.0871557427, + 0.0697564737, 0.0523359562, 0.0348994967, 0.0174524064, + 0.0000000000, -0.0174524064, -0.0348994967, -0.0523359562, + -0.0697564737, -0.0871557427, -0.1045284633, -0.1218693434, + -0.1391731010, -0.1564344650, -0.1736481777, -0.1908089954, + -0.2079116908, -0.2249510543, -0.2419218956, -0.2588190451, + -0.2756373558, -0.2923717047, -0.3090169944, -0.3255681545, + -0.3420201433, -0.3583679495, -0.3746065934, -0.3907311285, + -0.4067366431, -0.4226182617, -0.4383711468, -0.4539904997, + -0.4694715628, -0.4848096202, -0.5000000000, -0.5150380749, + -0.5299192642, -0.5446390350, -0.5591929035, -0.5735764364, + -0.5877852523, -0.6018150232, -0.6156614753, -0.6293203910, + -0.6427876097, -0.6560590290, -0.6691306064, -0.6819983601, + -0.6946583705, -0.7071067812, -0.7193398003, -0.7313537016, + -0.7431448255, -0.7547095802, -0.7660444431, -0.7771459615, + -0.7880107536, -0.7986355100, -0.8090169944, -0.8191520443, + -0.8290375726, -0.8386705679, -0.8480480962, -0.8571673007, + -0.8660254038, -0.8746197071, -0.8829475929, -0.8910065242, + -0.8987940463, -0.9063077870, -0.9135454576, -0.9205048535, + -0.9271838546, -0.9335804265, -0.9396926208, -0.9455185756, + -0.9510565163, -0.9563047560, -0.9612616959, -0.9659258263, + -0.9702957263, -0.9743700648, -0.9781476007, -0.9816271834, + -0.9848077530, -0.9876883406, -0.9902680687, -0.9925461516, + -0.9945218954, -0.9961946981, -0.9975640503, -0.9986295348, + -0.9993908270, -0.9998476952, -1.0000000000, -0.9998476952, + -0.9993908270, -0.9986295348, -0.9975640503, -0.9961946981, + -0.9945218954, -0.9925461516, -0.9902680687, -0.9876883406, + -0.9848077530, -0.9816271834, -0.9781476007, -0.9743700648, + -0.9702957263, -0.9659258263, -0.9612616959, -0.9563047560, + -0.9510565163, -0.9455185756, -0.9396926208, -0.9335804265, + -0.9271838546, -0.9205048535, -0.9135454576, -0.9063077870, + -0.8987940463, -0.8910065242, -0.8829475929, -0.8746197071, + -0.8660254038, -0.8571673007, -0.8480480962, -0.8386705679, + -0.8290375726, -0.8191520443, -0.8090169944, -0.7986355100, + -0.7880107536, -0.7771459615, -0.7660444431, -0.7547095802, + -0.7431448255, -0.7313537016, -0.7193398003, -0.7071067812, + -0.6946583705, -0.6819983601, -0.6691306064, -0.6560590290, + -0.6427876097, -0.6293203910, -0.6156614753, -0.6018150232, + -0.5877852523, -0.5735764364, -0.5591929035, -0.5446390350, + -0.5299192642, -0.5150380749, -0.5000000000, -0.4848096202, + -0.4694715628, -0.4539904997, -0.4383711468, -0.4226182617, + -0.4067366431, -0.3907311285, -0.3746065934, -0.3583679495, + -0.3420201433, -0.3255681545, -0.3090169944, -0.2923717047, + -0.2756373558, -0.2588190451, -0.2419218956, -0.2249510543, + -0.2079116908, -0.1908089954, -0.1736481777, -0.1564344650, + -0.1391731010, -0.1218693434, -0.1045284633, -0.0871557427, + -0.0697564737, -0.0523359562, -0.0348994967, -0.0174524064 +}; + +/* Reference table generated by cos(), gcc-4.3.2 */ +static const float cos_ref_table[] = { + 1.000000000000000, 0.999847695156391, 0.999390827019096, 0.998629534754574, + 0.997564050259824, 0.996194698091746, 0.994521895368273, 0.992546151641322, + 0.99026806874157, 0.987688340595138, 0.984807753012208, 0.981627183447664, + 0.978147600733806, 0.974370064785235, 0.970295726275996, 0.965925826289068, + 0.961261695938319, 0.956304755963035, 0.951056516295154, 0.945518575599317, + 0.939692620785908, 0.933580426497202, 0.927183854566787, 0.92050485345244, + 0.913545457642601, 0.90630778703665, 0.898794046299167, 0.891006524188368, + 0.882947592858927, 0.874619707139396, 0.866025403784439, 0.857167300702112, + 0.848048096156426, 0.838670567945424, 0.829037572555042, 0.819152044288992, + 0.809016994374947, 0.798635510047293, 0.788010753606722, 0.777145961456971, + 0.766044443118978, 0.754709580222772, 0.743144825477394, 0.731353701619171, + 0.719339800338651, 0.707106781186548, 0.694658370458997, 0.681998360062498, + 0.669130606358858, 0.656059028990507, 0.642787609686539, 0.629320391049838, + 0.615661475325658, 0.601815023152048, 0.587785252292473, 0.573576436351046, + 0.559192903470747, 0.544639035015027, 0.529919264233205, 0.515038074910054, + 0.500000000000000, 0.484809620246337, 0.469471562785891, 0.453990499739547, + 0.438371146789077, 0.422618261740699, 0.4067366430758, 0.390731128489274, + 0.374606593415912, 0.3583679495453, 0.342020143325669, 0.325568154457157, + 0.309016994374947, 0.292371704722737, 0.275637355816999, 0.258819045102521, + 0.241921895599668, 0.224951054343865, 0.207911690817759, 0.190808995376545, + 0.17364817766693, 0.156434465040231, 0.139173100960066, 0.121869343405147, + 0.104528463267653, 0.0871557427476581, 0.0697564737441255, 0.052335956242944, + 0.0348994967025011, 0.0174524064372834, 6.12323399573677e-17, -0.0174524064372835, + -0.0348994967025007, -0.0523359562429436, -0.0697564737441253, -0.0871557427476582, + -0.104528463267653, -0.121869343405147, -0.139173100960065, -0.156434465040231, + -0.17364817766693, -0.190808995376545, -0.207911690817759, -0.224951054343865, + -0.241921895599668, -0.258819045102521, -0.275637355816999, -0.292371704722737, + -0.309016994374947, -0.325568154457156, -0.342020143325669, -0.3583679495453, + -0.374606593415912, -0.390731128489274, -0.4067366430758, -0.422618261740699, + -0.438371146789078, -0.453990499739547, -0.469471562785891, -0.484809620246337, + -0.500000000000000, -0.515038074910054, -0.529919264233205, -0.544639035015027, + -0.559192903470747, -0.573576436351046, -0.587785252292473, -0.601815023152048, + -0.615661475325658, -0.629320391049837, -0.642787609686539, -0.656059028990507, + -0.669130606358858, -0.681998360062498, -0.694658370458997, -0.707106781186547, + -0.719339800338651, -0.73135370161917, -0.743144825477394, -0.754709580222772, + -0.766044443118978, -0.777145961456971, -0.788010753606722, -0.798635510047293, + -0.809016994374947, -0.819152044288992, -0.829037572555042, -0.838670567945424, + -0.848048096156426, -0.857167300702112, -0.866025403784439, -0.874619707139396, + -0.882947592858927, -0.891006524188368, -0.898794046299167, -0.90630778703665, + -0.913545457642601, -0.92050485345244, -0.927183854566787, -0.933580426497202, + -0.939692620785908, -0.945518575599317, -0.951056516295154, -0.956304755963035, + -0.961261695938319, -0.965925826289068, -0.970295726275996, -0.974370064785235, + -0.978147600733806, -0.981627183447664, -0.984807753012208, -0.987688340595138, + -0.99026806874157, -0.992546151641322, -0.994521895368273, -0.996194698091746, + -0.997564050259824, -0.998629534754574, -0.999390827019096, -0.999847695156391, + -1.000000000000000, -0.999847695156391, -0.999390827019096, -0.998629534754574, + -0.997564050259824, -0.996194698091746, -0.994521895368273, -0.992546151641322, + -0.99026806874157, -0.987688340595138, -0.984807753012208, -0.981627183447664, + -0.978147600733806, -0.974370064785235, -0.970295726275997, -0.965925826289068, + -0.961261695938319, -0.956304755963036, -0.951056516295154, -0.945518575599317, + -0.939692620785908, -0.933580426497202, -0.927183854566787, -0.92050485345244, + -0.913545457642601, -0.90630778703665, -0.898794046299167, -0.891006524188368, + -0.882947592858927, -0.874619707139396, -0.866025403784439, -0.857167300702112, + -0.848048096156426, -0.838670567945424, -0.829037572555042, -0.819152044288992, + -0.809016994374947, -0.798635510047293, -0.788010753606722, -0.777145961456971, + -0.766044443118978, -0.754709580222772, -0.743144825477394, -0.731353701619171, + -0.719339800338651, -0.707106781186548, -0.694658370458997, -0.681998360062499, + -0.669130606358858, -0.656059028990508, -0.642787609686539, -0.629320391049837, + -0.615661475325658, -0.601815023152048, -0.587785252292473, -0.573576436351046, + -0.559192903470747, -0.544639035015027, -0.529919264233205, -0.515038074910054, + -0.500000000000000, -0.484809620246337, -0.469471562785891, -0.453990499739547, + -0.438371146789078, -0.4226182617407, -0.4067366430758, -0.390731128489274, + -0.374606593415912, -0.358367949545301, -0.342020143325669, -0.325568154457157, + -0.309016994374948, -0.292371704722737, -0.275637355816999, -0.258819045102521, + -0.241921895599668, -0.224951054343865, -0.20791169081776, -0.190808995376545, + -0.17364817766693, -0.156434465040231, -0.139173100960065, -0.121869343405147, + -0.104528463267653, -0.0871557427476582, -0.0697564737441256, -0.0523359562429443, + -0.0348994967025016, -0.0174524064372835, -1.83697019872103e-16, 0.0174524064372831, + 0.0348994967025013, 0.0523359562429439, 0.0697564737441252, 0.0871557427476579, + 0.104528463267653, 0.121869343405148, 0.139173100960065, 0.156434465040231, + 0.17364817766693, 0.190808995376544, 0.207911690817759, 0.224951054343865, + 0.241921895599667, 0.258819045102521, 0.275637355816999, 0.292371704722737, + 0.309016994374947, 0.325568154457156, 0.342020143325668, 0.3583679495453, + 0.374606593415912, 0.390731128489273, 0.406736643075801, 0.4226182617407, + 0.438371146789077, 0.453990499739547, 0.46947156278589, 0.484809620246337, + 0.500000000000000, 0.515038074910054, 0.529919264233205, 0.544639035015027, + 0.559192903470746, 0.573576436351046, 0.587785252292473, 0.601815023152048, + 0.615661475325659, 0.629320391049838, 0.642787609686539, 0.656059028990507, + 0.669130606358858, 0.681998360062498, 0.694658370458997, 0.707106781186547, + 0.719339800338651, 0.731353701619171, 0.743144825477394, 0.754709580222772, + 0.766044443118978, 0.777145961456971, 0.788010753606722, 0.798635510047293, + 0.809016994374947, 0.819152044288992, 0.829037572555041, 0.838670567945424, + 0.848048096156425, 0.857167300702112, 0.866025403784438, 0.874619707139396, + 0.882947592858927, 0.891006524188368, 0.898794046299167, 0.90630778703665, + 0.913545457642601, 0.92050485345244, 0.927183854566787, 0.933580426497202, + 0.939692620785908, 0.945518575599317, 0.951056516295154, 0.956304755963036, + 0.961261695938319, 0.965925826289068, 0.970295726275996, 0.974370064785235, + 0.978147600733806, 0.981627183447664, 0.984807753012208, 0.987688340595138, + 0.99026806874157, 0.992546151641322, 0.994521895368273, 0.996194698091746, + 0.997564050259824, 0.998629534754574, 0.999390827019096, 0.999847695156391, + 1 +}; + +/* Reference table generated by asin(), gcc-4.3.2 */ +static const float asin_ref_table[] = { + -1.5707963258028030, -1.4292567726224661, -1.3704614471644163, -1.3252307642251253, + -1.2870021797716618, -1.2532358597964048, -1.2226302791386843, -1.1944128256291151, + -1.1680804640054703, -1.1432840377092361, -1.1197695024311543, -1.0973451361060143, + -1.0758621711283922, -1.0552022922784090, -1.0352696590125561, -1.0159852746874094, + -0.9972832072526217, -0.9791076704859734, -0.9614110030233860, -0.9441520925611258, + -0.9272952042520046, -0.9108089841902256, -0.8946658074855804, -0.8788411282002926, + -0.8633130993694067, -0.8480620700865984, -0.8330703470855951, -0.8183219302445650, + -0.8038023039698601, -0.7894981894642115, -0.7753974795341492, -0.7614890411496162, + -0.7477626111358404, -0.7342087719589472, -0.7208187356591225, -0.7075844295322895, + -0.6944982521235943, -0.6815531998872757, -0.6687426939606667, -0.6560605876147747, + -0.6435010936111212, -0.6310588326305151, -0.6187286712229252, -0.6065058410167694, + -0.5943857878446579, -0.5823642127215862, -0.5704370923340321, -0.5586005486547947, + -0.5468509383499622, -0.5351847745478153, -0.5235987640917301, -0.5120897386223078, + -0.5006546974182129, -0.4892907701432705, -0.4779951833188534, -0.4667653329670429, + -0.4555986635386944, -0.4444927759468555, -0.4334453158080578, -0.4224540572613478, + -0.4115168377757072, -0.4006315693259239, -0.3897962793707848, -0.3790090084075928, + -0.3682678826153278, -0.3575710840523243, -0.3469168916344643, -0.3363035582005978, + -0.3257294744253159, -0.3151930235326290, -0.3046926259994507, -0.2942268401384354, + -0.2837941013276577, -0.2733930107206106, -0.2630221955478191, -0.2526802383363247, + -0.2423658333718777, -0.2320776768028736, -0.2218144722282887, -0.2115749418735504, + -0.2013579159975052, -0.1911621354520321, -0.1809864528477192, -0.1708296611905098, + -0.1606906354427338, -0.1505682766437531, -0.1404614131897688, -0.1303689777851105, + -0.1202898658812046, -0.1102230437099934, -0.1001674197614193, -0.0901219304651022, + -0.0800855793058872, -0.0700572803616524, -0.0600360594689846, -0.0500208474695683, + -0.0400106683373451, -0.0300045013427734, -0.0200013294816017, -0.0100001543760300, + 0.0000000000000000, 0.0100001543760300, 0.0200013294816017, 0.0300045013427734, + 0.0400106683373451, 0.0500208474695683, 0.0600360594689846, 0.0700572803616524, + 0.0800855793058872, 0.0901219304651022, 0.1001674197614193, 0.1102230437099934, + 0.1202898658812046, 0.1303689777851105, 0.1404614131897688, 0.1505682766437531, + 0.1606906354427338, 0.1708296611905098, 0.1809864528477192, 0.1911621354520321, + 0.2013579159975052, 0.2115749418735504, 0.2218144722282887, 0.2320776768028736, + 0.2423658333718777, 0.2526802383363247, 0.2630221955478191, 0.2733930107206106, + 0.2837941013276577, 0.2942268401384354, 0.3046926259994507, 0.3151930235326290, + 0.3257294744253159, 0.3363035582005978, 0.3469168916344643, 0.3575710840523243, + 0.3682678826153278, 0.3790090084075928, 0.3897962793707848, 0.4006315693259239, + 0.4115168377757072, 0.4224540572613478, 0.4334453158080578, 0.4444927759468555, + 0.4555986635386944, 0.4667653329670429, 0.4779951833188534, 0.4892907701432705, + 0.5006546974182129, 0.5120897386223078, 0.5235987640917301, 0.5351847745478153, + 0.5468509383499622, 0.5586005486547947, 0.5704370923340321, 0.5823642127215862, + 0.5943857878446579, 0.6065058410167694, 0.6187286712229252, 0.6310588326305151, + 0.6435010936111212, 0.6560605876147747, 0.6687426939606667, 0.6815531998872757, + 0.6944982521235943, 0.7075844295322895, 0.7208187356591225, 0.7342087719589472, + 0.7477626111358404, 0.7614890411496162, 0.7753974795341492, 0.7894981894642115, + 0.8038023039698601, 0.8183219302445650, 0.8330703470855951, 0.8480620700865984, + 0.8633130993694067, 0.8788411282002926, 0.8946658074855804, 0.9108089841902256, + 0.9272952042520046, 0.9441520925611258, 0.9614110030233860, 0.9791076704859734, + 0.9972832072526217, 1.0159852746874094, 1.0352696590125561, 1.0552022922784090, + 1.0758621711283922, 1.0973451361060143, 1.1197695024311543, 1.1432840377092361, + 1.1680804640054703, 1.1944128256291151, 1.2226302791386843, 1.2532358597964048, + 1.2870021797716618, 1.3252307642251253, 1.3704614471644163, 1.4292567726224661, + 1.5707963258028030, +}; + +/* Reference table generated by acos(), gcc-4.3.2 */ +static const float acos_ref_table[] = { + 3.1415926534682512, 3.0000531002879143, 2.9412577748298645, 2.8960270918905735, + 2.8577985074371099, 2.8240321874618530, 2.7934266068041325, 2.7652091532945633, + 2.7388767916709185, 2.7140803653746843, 2.6905658300966024, 2.6681414637714624, + 2.6466584987938404, 2.6259986199438572, 2.6060659866780043, 2.5867816023528576, + 2.5680795349180698, 2.5499039981514215, 2.5322073306888342, 2.5149484202265739, + 2.4980915319174528, 2.4816053118556738, 2.4654621351510286, 2.4496374558657408, + 2.4341094270348549, 2.4188583977520466, 2.4038666747510433, 2.3891182579100132, + 2.3745986316353083, 2.3602945171296597, 2.3461938071995974, 2.3322853688150644, + 2.3185589388012886, 2.3050050996243954, 2.2916150633245707, 2.2783807571977377, + 2.2652945797890425, 2.2523495275527239, 2.2395390216261148, 2.2268569152802229, + 2.2142974212765694, 2.2018551602959633, 2.1895249988883734, 2.1773021686822176, + 2.1651821155101061, 2.1531605403870344, 2.1412334199994802, 2.1293968763202429, + 2.1176472660154104, 2.1059811022132635, 2.0943950917571783, 2.0828860662877560, + 2.0714510250836611, 2.0600870978087187, 2.0487915109843016, 2.0375616606324911, + 2.0263949912041426, 2.0152891036123037, 2.0042416434735060, 1.9932503849267960, + 1.9823131654411554, 1.9714278969913721, 1.9605926070362329, 1.9498053360730410, + 1.9390642102807760, 1.9283674117177725, 1.9177132192999125, 1.9070998858660460, + 1.8965258020907640, 1.8859893511980772, 1.8754889536648989, 1.8650231678038836, + 1.8545904289931059, 1.8441893383860588, 1.8338185232132673, 1.8234765660017729, + 1.8131621610373259, 1.8028740044683218, 1.7926107998937368, 1.7823712695389986, + 1.7721542436629534, 1.7619584631174803, 1.7517827805131674, 1.7416259888559580, + 1.7314869631081820, 1.7213646043092012, 1.7112577408552170, 1.7011653054505587, + 1.6910861935466528, 1.6810193713754416, 1.6709637474268675, 1.6609182581305504, + 1.6508819069713354, 1.6408536080271006, 1.6308323871344328, 1.6208171751350164, + 1.6108069960027933, 1.6008008290082216, 1.5907976571470499, 1.5807964820414782, + 1.5707963258028030, 1.5607961714267731, 1.5507949963212013, 1.5407918244600296, + 1.5307856574654579, 1.5207754783332348, 1.5107602663338184, 1.5007390454411507, + 1.4907107464969158, 1.4806743953377008, 1.4706289060413837, 1.4605732820928097, + 1.4505064599215984, 1.4404273480176926, 1.4303349126130342, 1.4202280491590500, + 1.4101056903600693, 1.3999666646122932, 1.3898098729550838, 1.3796341903507710, + 1.3694384098052979, 1.3592213839292526, 1.3489818535745144, 1.3387186489999294, + 1.3284304924309254, 1.3181160874664783, 1.3077741302549839, 1.2974033150821924, + 1.2870022244751453, 1.2765694856643677, 1.2661036998033524, 1.2556033022701740, + 1.2450668513774872, 1.2344927676022053, 1.2238794341683388, 1.2132252417504787, + 1.2025284431874752, 1.1917872473952103, 1.1810000464320183, 1.1701647564768791, + 1.1592794880270958, 1.1483422685414553, 1.1373510099947453, 1.1263035498559475, + 1.1151976622641087, 1.1040309928357601, 1.0928011424839497, 1.0815055556595325, + 1.0701416283845901, 1.0587065871804953, 1.0471975617110729, 1.0356115512549877, + 1.0239453874528408, 1.0121957771480083, 1.0003592334687710, 0.9884321130812168, + 0.9764105379581451, 0.9642904847860336, 0.9520676545798779, 0.9397374931722879, + 0.9272952321916819, 0.9147357381880283, 0.9020536318421364, 0.8892431259155273, + 0.8762980736792088, 0.8632118962705135, 0.8499775901436806, 0.8365875538438559, + 0.8230337146669626, 0.8093072846531868, 0.7953988462686539, 0.7812981363385916, + 0.7669940218329430, 0.7524743955582380, 0.7377259787172079, 0.7227342557162046, + 0.7074832264333963, 0.6919551976025105, 0.6761305183172226, 0.6599873416125774, + 0.6435011215507984, 0.6266442332416773, 0.6093853227794170, 0.5916886553168297, + 0.5735131185501814, 0.5548110511153936, 0.5355266667902470, 0.5155940335243940, + 0.4949341546744108, 0.4734511896967888, 0.4510268233716488, 0.4275122880935669, + 0.4027158617973328, 0.3763835001736879, 0.3481660466641188, 0.3175604660063982, + 0.2837941460311413, 0.2455655615776777, 0.2003348786383867, 0.1415395531803370, + 0.0000000000000000 +}; + +/* Reference degree table generated for acos(),asin() in range of [-1:1e-2:1]*/ +static const double degree_table[] = { + -57.2957795262336731, -56.7228217124938965, -56.1498639285564423, -55.5769061148166656, + -55.0039483308792114, -54.4309905469417572, -53.8580327332019806, -53.2850749492645264, + -52.7121171653270721, -52.1391593515872955, -51.5662015676498413, -50.9932437539100647, + -50.4202859699726105, -49.8473281860351562, -49.2743703722953796, -48.7014125883579254, + -48.1284548044204712, -47.5554969906806946, -46.9825392067432404, -46.4095813930034637, + -45.8366236090660095, -45.2636658251285553, -44.6907080113887787, -44.1177502274513245, + -43.5447924435138702, -42.9718346297740936, -42.3988768458366394, -41.8259190320968628, + -41.2529612481594086, -40.6800034642219543, -40.1070456504821777, -39.5340878665447235, + -38.9611300826072693, -38.3881722688674927, -37.8152144849300385, -37.2422566711902618, + -36.6692988872528076, -36.0963411033153534, -35.5233832895755768, -34.9504255056381226, + -34.3774677217006683, -33.8045099079608917, -33.2315521240234375, -32.6585943102836609, + -32.0856365263462067, -31.5126787424087524, -30.9397209286689758, -30.3667631447315216, + -29.7938053607940674, -29.2208475470542908, -28.6478897631168365, -28.0749319493770599, + -27.5019741654396057, -26.9290163815021515, -26.3560585677623749, -25.7831007838249207, + -25.2101429998874664, -24.6371851861476898, -24.0642274022102356, -23.4912695884704590, + -22.9183118045330048, -22.3453540205955505, -21.7723962068557739, -21.1994384229183197, + -20.6264806389808655, -20.0535228252410889, -19.4805650413036346, -18.9076072275638580, + -18.3346494436264038, -17.7616916596889496, -17.1887338459491730, -16.6157760620117188, + -16.0428182780742645, -15.4698604643344879, -14.8969026803970337, -14.3239448666572571, + -13.7509870827198029, -13.1780292987823486, -12.6050714850425720, -12.0321137011051178, + -11.4591559171676636, -10.8861981034278870, -10.3132403194904327, -9.7402825057506561, + -9.1673247218132019, -8.5943669378757477, -8.0214091241359711, -7.4484513401985168, + -6.8754935562610626, -6.3025357425212860, -5.7295779585838318, -5.1566201448440552, + -4.5836623609066010, -4.0107045769691467, -3.4377467632293701, -2.8647889792919159, + -2.2918311953544617, -1.7188733816146851, -1.1459155976772308, -0.5729577839374542, + 0.0000000000000000, 0.5729577839374542, 1.1459155976772308, 1.7188733816146851, + 2.2918311953544617, 2.8647889792919159, 3.4377467632293701, 4.0107045769691467, + 4.5836623609066010, 5.1566201448440552, 5.7295779585838318, 6.3025357425212860, + 6.8754935562610626, 7.4484513401985168, 8.0214091241359711, 8.5943669378757477, + 9.1673247218132019, 9.7402825057506561, 10.3132403194904327, 10.8861981034278870, + 11.4591559171676636, 12.0321137011051178, 12.6050714850425720, 13.1780292987823486, + 13.7509870827198029, 14.3239448666572571, 14.8969026803970337, 15.4698604643344879, + 16.0428182780742645, 16.6157760620117188, 17.1887338459491730, 17.7616916596889496, + 18.3346494436264038, 18.9076072275638580, 19.4805650413036346, 20.0535228252410889, + 20.6264806389808655, 21.1994384229183197, 21.7723962068557739, 22.3453540205955505, + 22.9183118045330048, 23.4912695884704590, 24.0642274022102356, 24.6371851861476898, + 25.2101429998874664, 25.7831007838249207, 26.3560585677623749, 26.9290163815021515, + 27.5019741654396057, 28.0749319493770599, 28.6478897631168365, 29.2208475470542908, + 29.7938053607940674, 30.3667631447315216, 30.9397209286689758, 31.5126787424087524, + 32.0856365263462067, 32.6585943102836609, 33.2315521240234375, 33.8045099079608917, + 34.3774677217006683, 34.9504255056381226, 35.5233832895755768, 36.0963411033153534, + 36.6692988872528076, 37.2422566711902618, 37.8152144849300385, 38.3881722688674927, + 38.9611300826072693, 39.5340878665447235, 40.1070456504821777, 40.6800034642219543, + 41.2529612481594086, 41.8259190320968628, 42.3988768458366394, 42.9718346297740936, + 43.5447924435138702, 44.1177502274513245, 44.6907080113887787, 45.2636658251285553, + 45.8366236090660095, 46.4095813930034637, 46.9825392067432404, 47.5554969906806946, + 48.1284548044204712, 48.7014125883579254, 49.2743703722953796, 49.8473281860351562, + 50.4202859699726105, 50.9932437539100647, 51.5662015676498413, 52.1391593515872955, + 52.7121171653270721, 53.2850749492645264, 53.8580327332019806, 54.4309905469417572, + 55.0039483308792114, 55.5769061148166656, 56.1498639285564423, 56.7228217124938965, + 57.2957795262336731 +}; + +#define CMP_TOLERANCE_32B 0.0000000611175871f +#define CMP_TOLERANCE_16B 0.000065f +#define CMP_TOLERANCE_ASIN_32B 0.000000068141916f +#define CMP_TOLERANCE_ACOS_32B 0.000000060077032f +#define CMP_TOLERANCE_ASIN_16B 0.0001152158f +#define CMP_TOLERANCE_ACOS_16B 0.0001196862f +#define CMP_TOLERANCE_SIN 3.1e-5f + +#endif /* __SOF_ZTEST_TRIG_TABLES_H__ */ diff --git a/test/ztest/unit/math/basic/trigonometry/trig_test.c b/test/ztest/unit/math/basic/trigonometry/trig_test.c new file mode 100644 index 000000000000..61cb19ef6142 --- /dev/null +++ b/test/ztest/unit/math/basic/trigonometry/trig_test.c @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. All rights reserved. +// +// These contents may have been developed with support from one or more Intel-operated +// generative artificial intelligence solutions. +// +// Converted from CMock to Ztest +// +// Original tests from sof/test/cmocka/src/math/trig/: +// - sin_32b_fixed.c (Author: Slawomir Blauciak ) +// - sin_16b_fixed.c (Author: Shriram Shastry ) +// - cos_32b_fixed.c (Author: Shriram Shastry ) +// - cos_16b_fixed.c (Author: Shriram Shastry ) +// - asin_32b_fixed.c (Author: Shriram Shastry ) +// - asin_16b_fixed.c (Author: Shriram Shastry ) +// - acos_32b_fixed.c (Author: Shriram Shastry ) +// - acos_16b_fixed.c (Author: Shriram Shastry ) +// - lut_sin_16b_fixed.c (Authors: Slawomir Blauciak , +// Seppo Ingalsuo ) + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "trig_tables.h" + +/* Define M_PI if not available */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* Conversion factor from degrees to radians (PI/180) */ +#define DEGREES_TO_RADIANS 0.017453292519943295 + +/* + * Helper function for rounding double values to nearest integer + * Implements custom rounding: round to 0 if absolute value < 0.5, otherwise round normally + */ +static inline int32_t round_to_nearest_int(double value) +{ + double abs_value = fabs(value); + + return (int32_t) (abs_value >= 0.5) ? floor(value + 0.5) : 0.0; +} + +/* Test sin_32b_fixed function */ +ZTEST(trigonometry, test_sin_32b_fixed) +{ + int theta; + float delta; + double rad; + int32_t sin_val; + + for (theta = 0; theta < ARRAY_SIZE(sin_ref_table); ++theta) { + rad = M_PI * ((double)theta / 180.0); + sin_val = sin_fixed_32b(Q_CONVERT_FLOAT(rad, 28)); + delta = fabsf(sin_ref_table[theta] - Q_CONVERT_QTOF(sin_val, 31)); + zassert_true(delta <= CMP_TOLERANCE_32B, + "sin_32b_fixed failed for angle %d", theta); + } +} + +/* Test sin_16b_fixed function */ +ZTEST(trigonometry, test_sin_16b_fixed) +{ + int theta; + float delta; + double rad; + int16_t sin_val; + + for (theta = 0; theta < ARRAY_SIZE(sin_ref_table); ++theta) { + rad = M_PI * ((double)theta / 180.0); + sin_val = sin_fixed_16b(Q_CONVERT_FLOAT(rad, 28)); + delta = fabsf(sin_ref_table[theta] - Q_CONVERT_QTOF(sin_val, 15)); + zassert_true(delta <= CMP_TOLERANCE_16B, + "sin_16b_fixed failed for angle %d", theta); + } +} + +/* Test cos_32b_fixed function */ +ZTEST(trigonometry, test_cos_32b_fixed) +{ + int theta; + float delta; + double rad; + int32_t cos_val; + + for (theta = 0; theta < ARRAY_SIZE(cos_ref_table); ++theta) { + rad = M_PI * ((double)theta / 180.0); + cos_val = cos_fixed_32b(Q_CONVERT_FLOAT(rad, 28)); + delta = fabsf(cos_ref_table[theta] - Q_CONVERT_QTOF(cos_val, 31)); + zassert_true(delta <= CMP_TOLERANCE_32B, + "cos_32b_fixed failed for angle %d", theta); + } +} + +/* Test cos_16b_fixed function */ +ZTEST(trigonometry, test_cos_16b_fixed) +{ + int theta; + float delta; + double rad; + int16_t cos_val; + + for (theta = 0; theta < ARRAY_SIZE(cos_ref_table); ++theta) { + rad = M_PI * ((double)theta / 180.0); + cos_val = cos_fixed_16b(Q_CONVERT_FLOAT(rad, 28)); + delta = fabsf(cos_ref_table[theta] - Q_CONVERT_QTOF(cos_val, 15)); + zassert_true(delta <= CMP_TOLERANCE_16B, + "cos_16b_fixed failed for angle %d", theta); + } +} + +/* Test asin_32b_fixed function */ +ZTEST(trigonometry, test_asin_32b_fixed) +{ + int index; + float delta; + double u; + int32_t asin_val, input_val; + + for (index = 0; index < ARRAY_SIZE(degree_table); ++index) { + /* Convert degree to input value in Q2.30 format like original test */ + /* angleInRadians = PI/180 * angleInDegrees & const Q2.30 format */ + u = (DEGREES_TO_RADIANS * degree_table[index] * 0x40000000); + input_val = round_to_nearest_int(u); + + asin_val = asin_fixed_32b(input_val); + delta = fabsf(asin_ref_table[index] - Q_CONVERT_QTOF(asin_val, 29)); + zassert_true(delta <= CMP_TOLERANCE_ASIN_32B, + "asin_32b_fixed failed for index %d", index); + } +} + +/* Test asin_16b_fixed function */ +ZTEST(trigonometry, test_asin_16b_fixed) +{ + int index; + float delta; + double u; + int16_t asin_val; + int32_t input_val; + + for (index = 0; index < ARRAY_SIZE(degree_table); ++index) { + /* Convert degree to input value in Q2.30 format like original test */ + /* angleInRadians = PI/180 * angleInDegrees & const Q2.30 format */ + u = (DEGREES_TO_RADIANS * degree_table[index] * 0x40000000); + input_val = round_to_nearest_int(u); + + asin_val = asin_fixed_16b(input_val); + delta = fabsf(asin_ref_table[index] - Q_CONVERT_QTOF(asin_val, 13)); + zassert_true(delta <= CMP_TOLERANCE_ASIN_16B, + "asin_16b_fixed failed for index %d", index); + } +} + +/* Test acos_32b_fixed function */ +ZTEST(trigonometry, test_acos_32b_fixed) +{ + int index; + float delta; + double u; + int32_t acos_val, input_val; + + for (index = 0; index < ARRAY_SIZE(degree_table); ++index) { + /* Convert degree to input value in Q2.30 format like original test */ + /* angleInRadians = PI/180 * angleInDegrees & const Q2.30 format */ + u = (DEGREES_TO_RADIANS * degree_table[index] * 0x40000000); + input_val = round_to_nearest_int(u); + + acos_val = acos_fixed_32b(input_val); + delta = fabsf(acos_ref_table[index] - Q_CONVERT_QTOF(acos_val, 29)); + zassert_true(delta <= CMP_TOLERANCE_ACOS_32B, + "acos_32b_fixed failed for index %d", index); + } +} + +/* Test acos_16b_fixed function */ +ZTEST(trigonometry, test_acos_16b_fixed) +{ + int index; + float delta; + double u; + int16_t acos_val; + int32_t input_val; + + for (index = 0; index < ARRAY_SIZE(degree_table); ++index) { + /* Convert degree to input value in Q2.30 format like original test */ + /* angleInRadians = PI/180 * angleInDegrees & const Q2.30 format */ + u = (DEGREES_TO_RADIANS * degree_table[index] * 0x40000000); + input_val = round_to_nearest_int(u); + + acos_val = acos_fixed_16b(input_val); + delta = fabsf(acos_ref_table[index] - Q_CONVERT_QTOF(acos_val, 13)); + zassert_true(delta <= CMP_TOLERANCE_ACOS_16B, + "acos_16b_fixed failed for index %d", index); + } +} + +/* Test sin lookup table function */ +ZTEST(trigonometry, test_sin_lut_16b_fixed) +{ + int theta; + float delta; + double rad; + int16_t sin_val; + + for (theta = 0; theta < ARRAY_SIZE(sin_ref_table); ++theta) { + rad = M_PI * (double)theta / 180.0; + sin_val = sofm_lut_sin_fixed_16b(Q_CONVERT_FLOAT(rad, 28)); + delta = fabsf(sin_ref_table[theta] - Q_CONVERT_QTOF(sin_val, 15)); + zassert_true(delta <= CMP_TOLERANCE_SIN, + "sin_lut_16b_fixed failed for angle %d", theta); + } +} + +ZTEST_SUITE(trigonometry, NULL, NULL, NULL, NULL, NULL); diff --git a/test/ztest/unit/objpool/CMakeLists.txt b/test/ztest/unit/objpool/CMakeLists.txt new file mode 100644 index 000000000000..2ce499607463 --- /dev/null +++ b/test/ztest/unit/objpool/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_objpool) + +set(SOF_ROOT "${PROJECT_SOURCE_DIR}/../../../..") + +# Include SOF CMake functions +include(${SOF_ROOT}/scripts/cmake/misc.cmake) + +target_include_directories(app PRIVATE + ${SOF_ROOT}/zephyr/include + ${SOF_ROOT}/src/include + ${SOF_ROOT}/src/platform/posix/include +) + +# Define SOF-specific configurations for unit testing +target_compile_definitions(app PRIVATE + -DCONFIG_ZEPHYR_POSIX=1 +) + +target_sources(app PRIVATE + test_objpool_ztest.c + ${SOF_ROOT}/test/ztest/unit/common/alloc.c + ${SOF_ROOT}/src/lib/objpool.c +) + +target_link_libraries(app PRIVATE "-Wl,--wrap=rzalloc,--wrap=sof_heap_alloc,--wrap=sof_heap_free,--wrap=sof_sys_heap_get") + +# Add RELATIVE_FILE definitions for SOF trace functionality +sof_append_relative_path_definitions(app) diff --git a/test/ztest/unit/objpool/prj.conf b/test/ztest/unit/objpool/prj.conf new file mode 100644 index 000000000000..d34c7781cd0a --- /dev/null +++ b/test/ztest/unit/objpool/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_SOF_FULL_ZEPHYR_APPLICATION=n diff --git a/test/ztest/unit/objpool/test_objpool_ztest.c b/test/ztest/unit/objpool/test_objpool_ztest.c new file mode 100644 index 000000000000..596fb3accd70 --- /dev/null +++ b/test/ztest/unit/objpool/test_objpool_ztest.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2025 Intel Corporation. + +#define DATA_SIZE 5 +#define ALIGNED_SIZE ALIGN_UP(DATA_SIZE, sizeof(int)) + +#include +#include +#include +#include + +#include + +#include +#include + +ZTEST(objpool_suite, test_objpool_wrong_size) +{ + struct objpool_head head = {.list = LIST_INIT(head.list)}; + /* new object pool of 2 blocks */ + uint8_t *block1 = objpool_alloc(&head, DATA_SIZE, 0); + /* should fail because of a different size */ + uint8_t *block2 = objpool_alloc(&head, DATA_SIZE + 1, 0); + /* second block in the first object pool */ + uint8_t *block3 = objpool_alloc(&head, DATA_SIZE, 0); + /* new object pool of 4 blocks */ + uint8_t *block4 = objpool_alloc(&head, DATA_SIZE, 0); + /* should fail because of a different size */ + uint8_t *block5 = objpool_alloc(&head, DATA_SIZE * 2, 0); + /* should fail because of different flags */ + uint8_t *block6 = objpool_alloc(&head, DATA_SIZE * 2, SOF_MEM_FLAG_COHERENT); + + zassert_not_null(block1); + zassert_is_null(block2); + zassert_not_null(block3); + zassert_not_null(block4); + zassert_is_null(block5); + zassert_is_null(block6); + + zassert_not_ok(objpool_free(&head, block1 + 1)); + zassert_ok(objpool_free(&head, block1)); + zassert_not_ok(objpool_free(&head, block3 + 1)); + zassert_ok(objpool_free(&head, block3)); + zassert_not_ok(objpool_free(&head, block4 + 1)); + zassert_ok(objpool_free(&head, block4)); +} + +ZTEST(objpool_suite, test_objpool) +{ + struct objpool_head head = {.list = LIST_INIT(head.list)}; + void *blocks[62]; /* 2 + 4 + 8 + 16 + 32 */ + unsigned int k = 0; + + /* Loop over all powers: 2^1..2^5 */ + for (unsigned int i = 1; i <= 5; i++) { + unsigned int n = 1 << i; + uint8_t *start; + + for (unsigned int j = 0; j < n; j++) { + uint8_t *block = objpool_alloc(&head, DATA_SIZE, 0); + + zassert_not_null(block, "allocation failed loop %u iter %u", i, j); + + if (!j) + start = block; + else + zassert_equal(block, start + ALIGNED_SIZE * j, "wrong pointer"); + + blocks[k++] = block; + } + } + + while (k--) + zassert_ok(objpool_free(&head, blocks[k]), "free failed"); +} + +struct test_objpool_data { + char cnt; + uint8_t reserved[DATA_SIZE - sizeof(char)]; +} __packed; + +static unsigned int test_objpool_check; + +static bool test_objpool_cb(void *data, void *arg) +{ + struct test_objpool_data *odata = data; + + zassert_equal(test_objpool_check++, odata->cnt, "Counter mismatch"); + zassert_equal((unsigned int)arg, 2, "Wrong argument"); + + return odata->cnt == (unsigned int)arg; +} + +ZTEST(objpool_suite, test_objpool_iterate) +{ + struct objpool_head head = {.list = LIST_INIT(head.list)}; + unsigned int i; + + for (i = 0; i < 4; i++) { + struct test_objpool_data *odata = objpool_alloc(&head, sizeof(*odata), 0); + + zassert_not_null(odata, "allocation failed loop %u", i); + + odata->cnt = i; + } + + int ret = objpool_iterate(&head, test_objpool_cb, (void *)2); + + zassert_equal(test_objpool_check, 3); + + zassert_ok(ret); + + /* Reset for a possible rerun */ + test_objpool_check = 0; +} + +ZTEST_SUITE(objpool_suite, NULL, NULL, NULL, NULL, NULL); diff --git a/test/ztest/unit/objpool/testcase.yaml b/test/ztest/unit/objpool/testcase.yaml new file mode 100644 index 000000000000..dc137a22adc4 --- /dev/null +++ b/test/ztest/unit/objpool/testcase.yaml @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright(c) 2025 Intel Corporation. +# +# Object pool allocator unit tests for Ztest framework + +tests: + sof.objpool: + tags: unit + platform_allow: native_sim + integration_platforms: + - native_sim + build_only: false diff --git a/third_party/include/dax_inf.h b/third_party/include/dax_inf.h new file mode 100644 index 000000000000..54464f7590b6 --- /dev/null +++ b/third_party/include/dax_inf.h @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE + * + * Copyright(c) 2025 Dolby Laboratories. All rights reserved. + * + * Author: Jun Lai + */ + +#ifndef DAX_INF_H +#define DAX_INF_H + +#include +#include +#include + +enum dax_frame_fmt { + DAX_FMT_UNSUPPORTED = -1, + DAX_FMT_SHORT_16 = 4, + DAX_FMT_INT = 5, + DAX_FMT_FLOAT = 7, +}; + +enum dax_sample_rate { + DAX_RATE_UNSUPPORTED = -1, +}; + +enum dax_channels { + DAX_CHANNLES_UNSUPPORTED = -1, +}; + +enum dax_buffer_fmt { + DAX_BUFFER_LAYOUT_UNSUPPORTED = -1, + DAX_BUFFER_LAYOUT_INTERLEAVED, + DAX_BUFFER_LAYOUT_NONINTERLEAVED, +}; + +enum dax_param_id { + DAX_PARAM_ID_ENABLE = 0x08001026, + DAX_PARAM_ID_TUNING_FILE = 0x08001027, + DAX_PARAM_ID_PROFILE = 0x08001028, + DAX_PARAM_ID_ENDPOINT = 0x08001029, + DAX_PARAM_ID_TUNING_DEVICE = 0x08001030, + DAX_PARAM_ID_CP_ENABLE = 0x08001031, + DAX_PARAM_ID_OUT_DEVICE = 0x08001032, + DAX_PARAM_ID_ABSOLUTE_VOLUME = 0x08001033, + DAX_PARAM_ID_CTC_ENABLE = 0x08001034, +}; + +struct dax_media_fmt { + enum dax_frame_fmt data_format; + uint32_t sampling_rate; + uint32_t num_channels; + enum dax_buffer_fmt layout; + uint32_t bytes_per_sample; +}; + +struct dax_buffer { + void *addr; + uint32_t size; /* Total buffer size in bytes */ + uint32_t avail; /* Available bytes for reading */ + uint32_t free; /* Free bytes for writing */ +}; + +struct sof_dax { + /* SOF module parameters */ + uint32_t sof_period_bytes; + + /* DAX state parameters */ + uint32_t period_bytes; + uint32_t period_us; + int32_t endpoint; + int32_t tuning_device; + void *blob_handler; + void *p_dax; + struct dax_media_fmt input_media_format; + struct dax_media_fmt output_media_format; + + /* DAX control parameters */ + int32_t enable; + int32_t profile; + int32_t out_device; + int32_t ctc_enable; + int32_t content_processing_enable; + int32_t volume; + uint32_t update_flags; + + /* DAX buffers */ + struct dax_buffer persist_buffer; /* Used for dax instance */ + struct dax_buffer scratch_buffer; /* Used for dax process */ + struct dax_buffer input_buffer; + struct dax_buffer output_buffer; + struct dax_buffer tuning_file_buffer; +}; + +/** + * @brief Query the persistent memory requirements for the DAX module + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return Size of required persistent memory in bytes + */ +uint32_t dax_query_persist_memory(struct sof_dax *dax_ctx); + +/** + * @brief Query the scratch memory requirements for the DAX module + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return Size of required scratch memory in bytes + */ +uint32_t dax_query_scratch_memory(struct sof_dax *dax_ctx); + +/** + * @brief Query the number of frames in a processing period + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return Number of frames per period + */ +uint32_t dax_query_period_frames(struct sof_dax *dax_ctx); + +/** + * @brief Free the DAX module + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * This function free all resources built on persistent buffer. + * DO NOT USE THE INSTANCE AFTER CALLING FREE. + * + * @return 0 on success, negative error code on failure + */ +int dax_free(struct sof_dax *dax_ctx); + +/** + * @brief Initialize the DAX module + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 on success, negative error code on failure + */ +int dax_init(struct sof_dax *dax_ctx); + +/** + * @brief Process audio data through the DAX module + * + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return Bytes of processed. negative error code on failure + */ +int dax_process(struct sof_dax *dax_ctx); + +/** + * @brief Set a parameter value for the DAX module + * + * @param[in] id Parameter identifier + * @param[in] val Pointer to parameter value + * @param[in] val_sz Size of parameter value in bytes + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 on success, negative error code on failure + */ +int dax_set_param(uint32_t id, const void *val, uint32_t val_sz, struct sof_dax *dax_ctx); + +/** + * @brief Enable/Disable the DAX module + * + * @param[in] enable 0:disable, 1:enable. + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 on success, negative error code on failure + */ +int dax_set_enable(int32_t enable, struct sof_dax *dax_ctx); + +/** + * @brief Set the volume for the DAX module + * + * @param[in] volume Value to apply + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 or positive code on success, negative error code on failure + */ +int dax_set_volume(int32_t volume, struct sof_dax *dax_ctx); + +/** + * @brief Update the output device configuration + * + * @param[in] out_device Output device identifier. Supported devices: + * 0: speaker + * 1: headphone + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 on success, negative error code on failure + */ +int dax_set_device(int32_t out_device, struct sof_dax *dax_ctx); + +/** + * @brief Enable/Disable crosstalk cancellation feature + * + * @param[in] enable 0:disable, 1:enable. + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return 0 on success, negative error code on failure + */ +int dax_set_ctc_enable(int32_t enable, struct sof_dax *dax_ctx); + +/** + * @brief Get the DAX module version string + * + * @return Pointer to null-terminated version string + */ +const char *dax_get_version(void); + +/** + * @brief Find parameters in a buffer based on query criteria + * + * @param[in] query_id ID of the parameter to search for. Supported query IDs: + * - DAX_PARAM_ID_PROFILE + * - DAX_PARAM_ID_TUNING_DEVICE + * - DAX_PARAM_ID_CP_ENABLE + * @param[in] query_val Value to match when searching + * @param[out] query_sz Pointer to store the size of the found parameters + * @param[in] dax_ctx Pointer to the DAX context structure + * + * @return Pointer to the found parameters, or NULL if not found + */ +void *dax_find_params(uint32_t query_id, + int32_t query_val, + uint32_t *query_sz, + struct sof_dax *dax_ctx); + +#endif /* DAX_INF_H */ diff --git a/tools/ctl/ipc4/drc/generic_notebook_speaker.txt b/tools/ctl/ipc4/drc/generic_notebook_speaker.txt deleted file mode 100644 index 104210eec4d9..000000000000 --- a/tools/ctl/ipc4/drc/generic_notebook_speaker.txt +++ /dev/null @@ -1 +0,0 @@ -877023059,0,108,50438144,0,0,0,0,108,0,0,0,0,1,3875536896,251658240,167772160,6442451,60380940,107374182,12708444,2327743,4292230659,5305422,162898102,73470028,7456540,4286019447,2062296,5,4423680,294359,2477728,622039,46513, diff --git a/tools/ctl/ipc4/drc/speaker_default.txt b/tools/ctl/ipc4/drc/speaker_default.txt new file mode 100644 index 000000000000..03d17e103040 --- /dev/null +++ b/tools/ctl/ipc4/drc/speaker_default.txt @@ -0,0 +1 @@ +3,140,877023059,0,108,50450433,0,0,0,0,108,0,0,0,0,1,3791650816,335544320,167772160,6442451,33954698,107374182,12228399,1969176,4292887072,5305422,137666458,81276115,7456540,4286019447,2062296,5,4423680,294359,2477728,622039,46513 diff --git a/tools/debug_stream/debug_stream.py b/tools/debug_stream/debug_stream.py index 9c3706d90f99..0191c5cd7be7 100644 --- a/tools/debug_stream/debug_stream.py +++ b/tools/debug_stream/debug_stream.py @@ -46,7 +46,6 @@ class DebugStreamRecord(ctypes.Structure): ("size_words", ctypes.c_uint), ] - class CPUInfo(ctypes.Structure): """ Thread Info record header @@ -73,6 +72,17 @@ class ThreadInfo(ctypes.Structure): ] +class TextMsg(ctypes.Structure): + """ + Text Msg record header + """ + + _pack_ = 1 + _fields_ = [ + ("hdr", DebugStreamRecord), + ] + + WSIZE = ctypes.sizeof(ctypes.c_uint) @@ -83,6 +93,7 @@ class RecordPrinter: RECORD_ID_UNINITIALIZED = 0 RECORD_ID_THREAD_INFO = 1 + RECORD_ID_TEXT_MSG = 2 def print_record(self, record, cpu): """prints debug-stream record""" @@ -92,7 +103,9 @@ def print_record(self, record, cpu): ) if recp.contents.id == self.RECORD_ID_THREAD_INFO: return self.print_thread_info(record, cpu) - logging.warning("cpu %u: Unsupported recodrd type %u", cpu, recp.contents.id) + if recp.contents.id == self.RECORD_ID_TEXT_MSG: + return self.print_text_msg(record, cpu) + logging.warning("cpu %u: Unsupported record type %u", cpu, recp.contents.id) return True def print_thread_info(self, record, cpu): @@ -141,6 +154,17 @@ def print_thread_info(self, record, cpu): ) return True + def print_text_msg(self, record, cpu): + """prints text-msg record""" + if len(record) - ctypes.sizeof(TextMsg) < 0: + logging.info("Buffer end reached, parsing failed") + return False + buffer = ( + ctypes.c_ubyte * (len(record) - ctypes.sizeof(TextMsg)) + ).from_address(ctypes.addressof(record) + ctypes.sizeof(TextMsg)) + msg = bytearray(buffer).decode("utf-8") + print("CPU %u: %s" % (cpu, msg)) + return True class DebugStreamSectionDescriptor(ctypes.Structure): """ diff --git a/tools/rimage/config/lnl.toml.h b/tools/rimage/config/lnl.toml.h index 5fc7008bfbe8..7a574d4ae906 100644 --- a/tools/rimage/config/lnl.toml.h +++ b/tools/rimage/config/lnl.toml.h @@ -62,6 +62,10 @@ #include