mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-25 14:39:15 +00:00
Compare commits
9 Commits
Canary-1.3
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9824c9053 | ||
|
|
d2037da65f | ||
|
|
8fe7d54f85 | ||
|
|
b8f9f3e16a | ||
|
|
7b1c8717ef | ||
|
|
6122fa204f | ||
|
|
217fd90568 | ||
|
|
95157c0cfd | ||
|
|
8a3ccaafe3 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,4 +2,3 @@
|
|||||||
# Set default behavior to automatically normalize line endings.
|
# Set default behavior to automatically normalize line endings.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
*.json text eol=lf
|
|
||||||
|
|||||||
81
.github/workflows/canary.yml
vendored
81
.github/workflows/canary.yml
vendored
@@ -102,46 +102,51 @@ jobs:
|
|||||||
chmod +x Ryujinx.sh Ryujinx
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
|
||||||
run: |
|
# - name: Build AppImage (Linux)
|
||||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
# if: matrix.platform.os == 'ubuntu-latest'
|
||||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
# run: |
|
||||||
|
# BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
sudo apt install -y zsync desktop-file-utils appstream
|
# PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
#
|
||||||
mkdir -p tools
|
# sudo apt install -y zsync desktop-file-utils appstream
|
||||||
export PATH="$PATH:$(readlink -f tools)"
|
#
|
||||||
|
# mkdir -p tools
|
||||||
# Setup appimagetool
|
# export PATH="$PATH:$(readlink -f tools)"
|
||||||
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
#
|
||||||
chmod +x tools/appimagetool
|
# # Setup appimagetool
|
||||||
chmod +x distribution/linux/appimage/build-appimage.sh
|
# wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
# chmod +x tools/appimagetool
|
||||||
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
# chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
#
|
||||||
ARCH_NAME=x64
|
# # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
export ARCH=x86_64
|
# if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
# ARCH_NAME=x64
|
||||||
ARCH_NAME=arm64
|
# export ARCH=x86_64
|
||||||
export ARCH=aarch64
|
# elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
else
|
# ARCH_NAME=arm64
|
||||||
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
# export ARCH=aarch64
|
||||||
exit 1
|
# else
|
||||||
fi
|
# echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
# exit 1
|
||||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
# fi
|
||||||
|
#
|
||||||
pushd publish_appimage
|
# export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
# BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
popd
|
#
|
||||||
|
# pushd publish_appimage
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
# mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
shell: bash
|
# mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
|
# popd
|
||||||
|
#
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
# shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
|
|||||||
79
.github/workflows/release.yml
vendored
79
.github/workflows/release.yml
vendored
@@ -96,43 +96,48 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
|
||||||
run: |
|
# - name: Build AppImage (Linux)
|
||||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
# if: matrix.platform.os == 'ubuntu-latest'
|
||||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
# run: |
|
||||||
|
# BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
sudo apt install -y zsync desktop-file-utils appstream
|
# PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
#
|
||||||
mkdir -p tools
|
# sudo apt install -y zsync desktop-file-utils appstream
|
||||||
export PATH="$PATH:$(readlink -f tools)"
|
#
|
||||||
|
# mkdir -p tools
|
||||||
# Setup appimagetool
|
# export PATH="$PATH:$(readlink -f tools)"
|
||||||
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
#
|
||||||
chmod +x tools/appimagetool
|
# # Setup appimagetool
|
||||||
chmod +x distribution/linux/appimage/build-appimage.sh
|
# wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
# chmod +x tools/appimagetool
|
||||||
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
# chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
#
|
||||||
ARCH_NAME=x64
|
# # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
export ARCH=x86_64
|
# if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
# ARCH_NAME=x64
|
||||||
ARCH_NAME=arm64
|
# export ARCH=x86_64
|
||||||
export ARCH=aarch64
|
# elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
else
|
# ARCH_NAME=arm64
|
||||||
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
# export ARCH=aarch64
|
||||||
exit 1
|
# else
|
||||||
fi
|
# echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
# exit 1
|
||||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
# fi
|
||||||
|
#
|
||||||
pushd publish_appimage
|
# export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
# BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
popd
|
#
|
||||||
|
# pushd publish_appimage
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
# mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
shell: bash
|
# mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
|
# popd
|
||||||
|
#
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
# shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
|
|||||||
18
BuildAndPushLibraries.sh
Normal file
18
BuildAndPushLibraries.sh
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
function pub {
|
||||||
|
dotnet publish -c release
|
||||||
|
}
|
||||||
|
|
||||||
|
function package {
|
||||||
|
cd src/$1
|
||||||
|
pub
|
||||||
|
mv bin/Release/$1.1.0.0.nupkg ../../pkgs/$1.1.0.0.nupkg
|
||||||
|
cd ../../
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf pkgs
|
||||||
|
mkdir pkgs
|
||||||
|
|
||||||
|
package ARMeilleure
|
||||||
|
package Ryujinx.Memory
|
||||||
|
|
||||||
|
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs
|
||||||
40
CHANGELOG.md
40
CHANGELOG.md
@@ -21,8 +21,8 @@ Additionally, 1.2.74 & 75 were fixes for uploading Windows build artifacts.
|
|||||||
|
|
||||||
1.2.76 fixes a rare crash on startup.
|
1.2.76 fixes a rare crash on startup.
|
||||||
|
|
||||||
## [1.2.72](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.72>) - 2024-11-03
|
## [1.2.72](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.72>) - 2024-11-03
|
||||||
PRs [#163](<https://web.archive.org/web/20241123015123/https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://web.archive.org/web/20250307192526/https://github.com/Ryubing/Ryujinx/pull/164>), [#139](<https://web.archive.org/web/20250306123457/https://github.com/Ryubing/Ryujinx/pull/139>)
|
PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://github.com/GreemDev/Ryujinx/pull/164>), [#139](<https://github.com/GreemDev/Ryujinx/pull/139>)
|
||||||
### HLE:
|
### HLE:
|
||||||
- Add DebugMouse HID device.
|
- Add DebugMouse HID device.
|
||||||
- Fixes "Clock Tower Rewind" crashing while loading.
|
- Fixes "Clock Tower Rewind" crashing while loading.
|
||||||
@@ -32,7 +32,7 @@ PRs [#163](<https://web.archive.org/web/20241123015123/https://github.com/GreemD
|
|||||||
### misc:
|
### misc:
|
||||||
- Update macOS distribution .icns.
|
- Update macOS distribution .icns.
|
||||||
|
|
||||||
## [1.2.69](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.69>) - 2024-11-01
|
## [1.2.69](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.69>) - 2024-11-01
|
||||||
### Infra:
|
### Infra:
|
||||||
- Compile the native libraries into the Ryujinx executable.
|
- Compile the native libraries into the Ryujinx executable.
|
||||||
- Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only)
|
- Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only)
|
||||||
@@ -42,8 +42,8 @@ PRs [#163](<https://web.archive.org/web/20241123015123/https://github.com/GreemD
|
|||||||
- Replace "" with `string.Empty`.
|
- Replace "" with `string.Empty`.
|
||||||
- Code cleanups & simplifications.
|
- Code cleanups & simplifications.
|
||||||
|
|
||||||
## [1.2.67](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.67>) - 2024-11-01
|
## [1.2.67](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.67>) - 2024-11-01
|
||||||
PRs [#36](<https://web.archive.org/web/20250306215917/https://github.com/Ryubing/Ryujinx/pull/36>), [#135](<https://web.archive.org/web/20241122135125/https://github.com/GreemDev/Ryujinx/pull/135>)
|
PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github.com/GreemDev/Ryujinx/pull/135>)
|
||||||
|
|
||||||
### GUI:
|
### GUI:
|
||||||
- Set UseFloatingWatermark to false when watermark is empty
|
- Set UseFloatingWatermark to false when watermark is empty
|
||||||
@@ -54,8 +54,8 @@ PRs [#36](<https://web.archive.org/web/20250306215917/https://github.com/Ryubing
|
|||||||
- Fix homebrew loading.
|
- Fix homebrew loading.
|
||||||
|
|
||||||
|
|
||||||
## [1.2.64](https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.64) - 2024-10-30
|
## [1.2.64](https://github.com/GreemDev/Ryujinx/releases/tag/1.2.64) - 2024-10-30
|
||||||
PRs [#92](https://web.archive.org/web/20241118052724/https://github.com/GreemDev/Ryujinx/pull/92), ~~[#96](https://github.com/GreemDev/Ryujinx/pull/96)~~, ~~[#97](https://github.com/GreemDev/Ryujinx/pull/97)~~, [#101](https://web.archive.org/web/20250306223605/https://github.com/Ryubing/Ryujinx/pull/101), ~~[#103](https://github.com/GreemDev/Ryujinx/pull/103)~~
|
PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com/GreemDev/Ryujinx/pull/96), [#97](https://github.com/GreemDev/Ryujinx/pull/97), [#101](https://github.com/GreemDev/Ryujinx/pull/101), [#103](https://github.com/GreemDev/Ryujinx/pull/103)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Option to show classic-style title bar. Requires restart of emulator to take effect.
|
- Option to show classic-style title bar. Requires restart of emulator to take effect.
|
||||||
- This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place.
|
- This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place.
|
||||||
@@ -71,14 +71,14 @@ PRs [#92](https://web.archive.org/web/20241118052724/https://github.com/GreemDev
|
|||||||
|
|
||||||
## 1.2.59 - 2024-10-27
|
## 1.2.59 - 2024-10-27
|
||||||
|
|
||||||
PRs ~~[#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)~~
|
PRs [#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)
|
||||||
### i18n:
|
### i18n:
|
||||||
- fr_FR:
|
- fr_FR:
|
||||||
- Add missing translations for new features & fix a couple wrong ones.
|
- Add missing translations for new features & fix a couple wrong ones.
|
||||||
- Fix Ignore Missing Services / Ignore Applet tooltip.
|
- Fix Ignore Missing Services / Ignore Applet tooltip.
|
||||||
|
|
||||||
## 1.2.57 - 2024-10-27
|
## 1.2.57 - 2024-10-27
|
||||||
PRs ~~[#60](https://github.com/GreemDev/Ryujinx/pull/60)~~, [#42](https://web.archive.org/web/20241126203614/https://github.com/GreemDev/Ryujinx/pull/42)
|
PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com/GreemDev/Ryujinx/pull/42)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Automatically remove invalid DLC & updates as part of autoload.
|
- Automatically remove invalid DLC & updates as part of autoload.
|
||||||
- Added Thai translation for Ignore Applet hover tooltip.
|
- Added Thai translation for Ignore Applet hover tooltip.
|
||||||
@@ -104,7 +104,7 @@ PRs ~~[#60](https://github.com/GreemDev/Ryujinx/pull/60)~~, [#42](https://web.ar
|
|||||||
- Code cleanup.
|
- Code cleanup.
|
||||||
|
|
||||||
## 1.2.44 - 2024-10-25
|
## 1.2.44 - 2024-10-25
|
||||||
PR [#59](https://web.archive.org/web/20241125060420/https://github.com/GreemDev/Ryujinx/pull/59)
|
PR [#59](https://github.com/GreemDev/Ryujinx/pull/59)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Add descriptions for "ignoring applet" translated into other languages.
|
- Add descriptions for "ignoring applet" translated into other languages.
|
||||||
|
|
||||||
@@ -117,9 +117,9 @@ NOTE: The translation isn't referenced in the code yet, it will be in the next u
|
|||||||
## 1.2.42 - 2024-10-24
|
## 1.2.42 - 2024-10-24
|
||||||
Sources:
|
Sources:
|
||||||
|
|
||||||
Init function: [archive of github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9](https://web.archive.org/web/20241122193401/https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9)
|
Init function: https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9
|
||||||
|
|
||||||
Shader counter: ~~https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357~~ Original commit has been lost
|
Shader counter: https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357
|
||||||
|
|
||||||
Thanks MutantAura :D
|
Thanks MutantAura :D
|
||||||
### GUI:
|
### GUI:
|
||||||
@@ -127,14 +127,14 @@ Thanks MutantAura :D
|
|||||||
- Remove graphics backend / GPU name event logic in favor of a single init function.
|
- Remove graphics backend / GPU name event logic in favor of a single init function.
|
||||||
|
|
||||||
## 1.2.41 - 2024-10-24
|
## 1.2.41 - 2024-10-24
|
||||||
PR ~~[#54](https://github.com/GreemDev/Ryujinx/pull/54)~~
|
PR [#54](https://github.com/GreemDev/Ryujinx/pull/54)
|
||||||
|
|
||||||
Thanks Whitescatz!
|
Thanks Whitescatz!
|
||||||
### i18n:
|
### i18n:
|
||||||
- th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar.
|
- th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar.
|
||||||
|
|
||||||
## 1.2.40 - 2024-10-23
|
## 1.2.40 - 2024-10-23
|
||||||
PR ~~[#40](https://github.com/GreemDev/Ryujinx/pull/40)~~
|
PR [#40](https://github.com/GreemDev/Ryujinx/pull/40)
|
||||||
|
|
||||||
Thanks Вова С!
|
Thanks Вова С!
|
||||||
### GUI:
|
### GUI:
|
||||||
@@ -148,30 +148,30 @@ Thanks Вова С!
|
|||||||
- Should prevent crashing on config loads in some circumstances.
|
- Should prevent crashing on config loads in some circumstances.
|
||||||
|
|
||||||
## 1.2.38 - 2024-10-23
|
## 1.2.38 - 2024-10-23
|
||||||
PR [#51](https://web.archive.org/web/20241127022413/https://github.com/GreemDev/Ryujinx/pull/51)
|
PR [#51](https://github.com/GreemDev/Ryujinx/pull/51)
|
||||||
### i18n:
|
### i18n:
|
||||||
- zh_CH (Simplified Chinese): Add some missing translations.
|
- zh_CH (Simplified Chinese): Add some missing translations.
|
||||||
|
|
||||||
## 1.2.37 - 2024-10-23
|
## 1.2.37 - 2024-10-23
|
||||||
PR [#37](https://web.archive.org/web/20241123010103/https://github.com/GreemDev/Ryujinx/pull/37)
|
PR [#37](https://github.com/GreemDev/Ryujinx/pull/37)
|
||||||
|
|
||||||
Thanks Last Breath!
|
Thanks Last Breath!
|
||||||
### GUI:
|
### GUI:
|
||||||
- Set the default controller to the Pro Controller.
|
- Set the default controller to the Pro Controller.
|
||||||
|
|
||||||
## 1.2.36 - 2024-10-21
|
## 1.2.36 - 2024-10-21
|
||||||
PR ~~[#30](https://github.com/GreemDev/Ryujinx/pull/30)~~
|
PR [#30](https://github.com/GreemDev/Ryujinx/pull/30)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file.
|
- Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file.
|
||||||
|
|
||||||
## 1.2.35 - 2024-10-21
|
## 1.2.35 - 2024-10-21
|
||||||
PR [#32](https://web.archive.org/web/20241127010942/https://github.com/GreemDev/Ryujinx/pull/32)
|
PR [#32](https://github.com/GreemDev/Ryujinx/pull/32)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Replace "expand DRAM" option with a DRAM size dropdown.
|
- Replace "expand DRAM" option with a DRAM size dropdown.
|
||||||
- Allows for using mods which require a ridiculous amount of memory to allocate from.
|
- Allows for using mods which require a ridiculous amount of memory to allocate from.
|
||||||
|
|
||||||
## 1.2.34 - 2024-10-21
|
## 1.2.34 - 2024-10-21
|
||||||
PR [#29](https://web.archive.org/web/20241125093029/https://github.com/GreemDev/Ryujinx/pull/29)
|
PR [#29](https://github.com/GreemDev/Ryujinx/pull/29)
|
||||||
### GUI:
|
### GUI:
|
||||||
- Fix duplicate controller names when 2 controllers of the same type are connected.
|
- Fix duplicate controller names when 2 controllers of the same type are connected.
|
||||||
### INPUT:
|
### INPUT:
|
||||||
@@ -248,7 +248,7 @@ Added Low-power PPTC mode strings to the translation files.
|
|||||||
## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11
|
## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11
|
||||||
### GUI/INFRA/MISC:
|
### GUI/INFRA/MISC:
|
||||||
- Remove GTK UI.
|
- Remove GTK UI.
|
||||||
- Autoload DLC/Updates from dir ([#12](https://web.archive.org/web/20241127004005/https://github.com/GreemDev/Ryujinx/pull/12)).
|
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)).
|
||||||
- Changed executable icon to rainbow logo.
|
- Changed executable icon to rainbow logo.
|
||||||
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
|
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
|
||||||
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.
|
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Make sure your SDK version is higher or equal to the required version specified
|
|||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
|
|
||||||
Either use `git clone https://git.ryujinx.app/ryubing/ryujinx.git` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
Either use `git clone https://github.com/Ryubing/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
||||||
|
|
||||||
### Step 3
|
### Step 3
|
||||||
|
|
||||||
|
|||||||
@@ -3,26 +3,25 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="11.3.6" />
|
<PackageVersion Include="Avalonia" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.13" />
|
||||||
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.6.2" />
|
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.19" />
|
||||||
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.6.2" />
|
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.19" />
|
||||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.6.2" />
|
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.4.0" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.6.2" />
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.6.2" />
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||||
<PackageVersion Include="ppy.SDL3-CS" Version="2025.920.0" />
|
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||||
<PackageVersion Include="Concentus" Version="2.2.2" />
|
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI.NoAnim" Version="2.4.0-build3" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||||
@@ -41,12 +40,13 @@
|
|||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.126" />
|
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
|
||||||
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
|
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
|
||||||
<PackageVersion Include="Gommon" Version="2.8.0.1" />
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
|
||||||
|
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.11.1" />
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
||||||
@@ -55,8 +55,9 @@
|
|||||||
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
|
<PackageVersion Include="Starscript.Net" Version="1.0.36" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
||||||
<PackageVersion Include="System.Management" Version="9.0.2" />
|
<PackageVersion Include="System.Management" Version="9.0.2" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ If you are planning to contribute or just want to learn more about this project
|
|||||||
- **Audio**
|
- **Audio**
|
||||||
|
|
||||||
Audio output is entirely supported, audio input (microphone) isn't supported.
|
Audio output is entirely supported, audio input (microphone) isn't supported.
|
||||||
We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL3](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks.
|
We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL2](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks.
|
||||||
|
|
||||||
- **CPU**
|
- **CPU**
|
||||||
|
|
||||||
|
|||||||
346
Ryujinx.sln
346
Ryujinx.sln
@@ -45,15 +45,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vic", "src
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "src\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "src\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL3", "src\Ryujinx.Audio.Backends.SDL3\Ryujinx.Audio.Backends.SDL3.csproj", "{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "src\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "src\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SoundIo", "src\Ryujinx.Audio.Backends.SoundIo\Ryujinx.Audio.Backends.SoundIo.csproj", "{716364DE-B988-41A6-BAB4-327964266ECC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SoundIo", "src\Ryujinx.Audio.Backends.SoundIo\Ryujinx.Audio.Backends.SoundIo.csproj", "{716364DE-B988-41A6-BAB4-327964266ECC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input", "src\Ryujinx.Input\Ryujinx.Input.csproj", "{C16F112F-38C3-40BC-9F5F-4791112063D6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input", "src\Ryujinx.Input\Ryujinx.Input.csproj", "{C16F112F-38C3-40BC-9F5F-4791112063D6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input.SDL3", "src\Ryujinx.Input.SDL3\Ryujinx.Input.SDL3.csproj", "{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input.SDL2", "src\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj", "{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\Ryujinx.SDL2.Common\Ryujinx.SDL2.Common.csproj", "{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -77,8 +79,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "s
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL3.Common", "src\Ryujinx.SDL3.Common\Ryujinx.SDL3.Common.csproj", "{F6F9826A-BC58-4D78-A700-F358A66B2B06}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
@@ -92,468 +92,164 @@ EndProject
|
|||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
Release|x64 = Release|x64
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.Build.0 = Release|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x64.ActiveCfg = Release|Any CPU
|
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x64.Build.0 = Release|Any CPU
|
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x86.ActiveCfg = Release|Any CPU
|
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x86.Build.0 = Release|Any CPU
|
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x64.ActiveCfg = Release|Any CPU
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x64.Build.0 = Release|Any CPU
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x86.ActiveCfg = Release|Any CPU
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x86.Build.0 = Release|Any CPU
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.Build.0 = Release|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
8578
assets/locales.json
8578
assets/locales.json
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL3" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
|
||||||
RYUJINX_BIN="Ryujinx.Headless.SDL3"
|
RYUJINX_BIN="Ryujinx.Headless.SDL2"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ cd "$ROOTDIR"
|
|||||||
|
|
||||||
BUILDDIR=${BUILDDIR:-publish}
|
BUILDDIR=${BUILDDIR:-publish}
|
||||||
OUTDIR=${OUTDIR:-publish_appimage}
|
OUTDIR=${OUTDIR:-publish_appimage}
|
||||||
|
UFLAG=${UFLAG:-"gh-releases-zsync|Ryubing|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||||
|
|
||||||
rm -rf AppDir
|
rm -rf AppDir
|
||||||
mkdir -p AppDir/usr/bin
|
mkdir -p AppDir/usr/bin
|
||||||
@@ -22,5 +23,11 @@ chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
|
|||||||
|
|
||||||
mkdir -p "$OUTDIR"
|
mkdir -p "$OUTDIR"
|
||||||
|
|
||||||
appimagetool -n --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
|
appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
|
||||||
|
-u "$UFLAG" \
|
||||||
AppDir "$OUTDIR"/Ryujinx.AppImage
|
AppDir "$OUTDIR"/Ryujinx.AppImage
|
||||||
|
|
||||||
|
# Move zsync file needed for delta updates
|
||||||
|
if [ "$RELEASE" = "1" ]; then
|
||||||
|
mv ./*.AppImage.zsync "$OUTDIR"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleLongVersionString</key>
|
<key>CFBundleLongVersionString</key>
|
||||||
<string>%%RYUJINX_BUILD_VERSION%%-%%RYUJINX_BUILD_GIT_HASH%%</string>
|
<string>%%RYUJINX_BUILD_VERSION%%-%%RYUJINX_BUILD_GIT_HASH%%"</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Ryujinx</string>
|
<string>Ryujinx</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
@@ -44,13 +44,13 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>%%RYUJINX_BUILD_VERSION%%</string>
|
<string>1.2.0</string>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2018 - 2024 Ryujinx Team and Contributors. Copyright © 2024 - 2025 Ryubing and Contributors.</string>
|
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ fi
|
|||||||
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
||||||
X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
|
X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
|
||||||
UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
|
UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
|
||||||
EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL3
|
EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2
|
||||||
|
|
||||||
rm -rf "$TEMP_DIRECTORY"
|
rm -rf "$TEMP_DIRECTORY"
|
||||||
mkdir -p "$TEMP_DIRECTORY"
|
mkdir -p "$TEMP_DIRECTORY"
|
||||||
@@ -51,9 +51,9 @@ mkdir -p "$TEMP_DIRECTORY"
|
|||||||
DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
|
DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
|
||||||
|
|
||||||
dotnet restore
|
dotnet restore
|
||||||
dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL3
|
dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2
|
||||||
dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL3
|
dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
||||||
dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL3
|
dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
||||||
|
|
||||||
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
|
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
|
||||||
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
|
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
|
||||||
@@ -115,8 +115,8 @@ fi
|
|||||||
|
|
||||||
echo "Creating archive"
|
echo "Creating archive"
|
||||||
pushd "$OUTPUT_DIRECTORY"
|
pushd "$OUTPUT_DIRECTORY"
|
||||||
tar --exclude "publish/Ryujinx.Headless.SDL3" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
|
tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
|
||||||
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL3" "publish/Ryujinx.Headless.SDL3"
|
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
|
||||||
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
||||||
rm "$RELEASE_TAR_FILE_NAME"
|
rm "$RELEASE_TAR_FILE_NAME"
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Intro to Ryujinx
|
|||||||
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
||||||
* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions.
|
* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions.
|
||||||
* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
||||||
* Audio output is entirely supported via C# wrappers for SDL3, with OpenAL & libsoundio as fallbacks.
|
* Audio output is entirely supported via C# wrappers for SDL2, with OpenAL & libsoundio as fallbacks.
|
||||||
|
|
||||||
Getting Started
|
Getting Started
|
||||||
===============
|
===============
|
||||||
|
|||||||
@@ -188,8 +188,6 @@
|
|||||||
01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27
|
01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27
|
||||||
01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18
|
01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18
|
||||||
01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12
|
01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12
|
||||||
01009E8012976000,"AKIBA'S TRIP: Hellbound & Debriefed",,playable,2025-07-30 23:22:47
|
|
||||||
0100D74019A0E000,"AKIBA'S TRIP: Undead & Undressed Director's Cut",,playable,2025-07-31 13:58:42
|
|
||||||
010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35
|
010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35
|
||||||
0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36
|
0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36
|
||||||
010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27
|
010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27
|
||||||
@@ -978,7 +976,7 @@
|
|||||||
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
||||||
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
|
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
|
||||||
01008CB01E52E000,"DOOM + DOOM II",opengl;ldn-untested;LAN,playable,2024-09-12 07:06:01
|
01008CB01E52E000,"DOOM + DOOM II",opengl;ldn-untested;LAN,playable,2024-09-12 07:06:01
|
||||||
010029D00E740000,"DOOM 3",crash;slow,menus,2024-08-03 05:25:47
|
010029D00E740000,"DOOM 3",crash,menus,2024-08-03 05:25:47
|
||||||
01005D700E742000,"DOOM 64",nvdec;vulkan,playable,2020-10-13 23:47:28
|
01005D700E742000,"DOOM 64",nvdec;vulkan,playable,2020-10-13 23:47:28
|
||||||
0100D4F00DD02000,"DOOM II (Classic)",nvdec;online,playable,2021-06-03 20:10:01
|
0100D4F00DD02000,"DOOM II (Classic)",nvdec;online,playable,2021-06-03 20:10:01
|
||||||
0100B1A00D8CE000,"DOOM® Eternal",gpu;slow;nvdec;online-broken,ingame,2024-08-28 15:57:17
|
0100B1A00D8CE000,"DOOM® Eternal",gpu;slow;nvdec;online-broken,ingame,2024-08-28 15:57:17
|
||||||
@@ -1097,7 +1095,6 @@
|
|||||||
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
|
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
|
||||||
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
|
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
|
||||||
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
|
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
|
||||||
010018F01E0A0000,"Eternights",,playable,2025-07-30 12:10:24
|
|
||||||
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
|
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
|
||||||
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
|
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
|
||||||
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
|
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
|
||||||
@@ -1175,7 +1172,6 @@
|
|||||||
0100EB100AB42000,"FINAL FANTASY XII THE ZODIAC AGE",opengl;vulkan-backend-bug,playable,2024-08-11 07:01:54
|
0100EB100AB42000,"FINAL FANTASY XII THE ZODIAC AGE",opengl;vulkan-backend-bug,playable,2024-08-11 07:01:54
|
||||||
010068F00AA78000,"FINAL FANTASY XV POCKET EDITION HD",,playable,2021-01-05 17:52:08
|
010068F00AA78000,"FINAL FANTASY XV POCKET EDITION HD",,playable,2021-01-05 17:52:08
|
||||||
0100CE4010AAC000,"FINAL FANTASY® CRYSTAL CHRONICLES™ Remastered Edition",,playable,2023-04-02 23:39:12
|
0100CE4010AAC000,"FINAL FANTASY® CRYSTAL CHRONICLES™ Remastered Edition",,playable,2023-04-02 23:39:12
|
||||||
010038B015560000,FINAL FANTASY TACTICS - The Ivalice Chronicles,gpu,boots,2024-09-30 02:59:00
|
|
||||||
01001BA00AE4E000,"Final Light, The Prison",,playable,2020-07-31 21:48:44
|
01001BA00AE4E000,"Final Light, The Prison",,playable,2020-07-31 21:48:44
|
||||||
0100FF100FB68000,"Finding Teddy 2 : Definitive Edition",gpu,ingame,2024-04-19 16:51:33
|
0100FF100FB68000,"Finding Teddy 2 : Definitive Edition",gpu,ingame,2024-04-19 16:51:33
|
||||||
0100F4E013AAE000,"Fire & Water",,playable,2020-12-15 15:43:20
|
0100F4E013AAE000,"Fire & Water",,playable,2020-12-15 15:43:20
|
||||||
@@ -1244,8 +1240,6 @@
|
|||||||
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
|
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
|
||||||
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
|
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
|
||||||
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
|
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
|
||||||
0100C4E018A24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
|
|
||||||
01007E6019872000,"FRONT MISSION 3: Remake",,playable,2025-07-30 12:12:02
|
|
||||||
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
|
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
|
||||||
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
|
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
|
||||||
010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33
|
010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33
|
||||||
@@ -1441,7 +1435,6 @@
|
|||||||
0100C2700E338000,"Heroland",,playable,2020-08-05 15:35:39
|
0100C2700E338000,"Heroland",,playable,2020-08-05 15:35:39
|
||||||
01007AC00E012000,"HexaGravity",,playable,2021-05-28 13:47:48
|
01007AC00E012000,"HexaGravity",,playable,2021-05-28 13:47:48
|
||||||
01004E800F03C000,"Hidden",slow,ingame,2022-10-05 10:56:53
|
01004E800F03C000,"Hidden",slow,ingame,2022-10-05 10:56:53
|
||||||
0100C1101EE5A000,"High on Life",,menus,2025-08-26 19:11:00
|
|
||||||
0100F6A00A684000,"Higurashi no Naku Koro ni Hō",audio,ingame,2021-09-18 14:40:28
|
0100F6A00A684000,"Higurashi no Naku Koro ni Hō",audio,ingame,2021-09-18 14:40:28
|
||||||
0100F8D0129F4000,"Himehibi 1 gakki - Princess Days",crash,nothing,2021-11-03 08:34:19
|
0100F8D0129F4000,"Himehibi 1 gakki - Princess Days",crash,nothing,2021-11-03 08:34:19
|
||||||
0100F3D008436000,"Hiragana Pixel Party",,playable,2021-01-14 08:36:50
|
0100F3D008436000,"Hiragana Pixel Party",,playable,2021-01-14 08:36:50
|
||||||
@@ -1451,7 +1444,6 @@
|
|||||||
0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35
|
0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35
|
||||||
0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58
|
0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58
|
||||||
0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56
|
0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56
|
||||||
010013C00E930000,"Hollow Knight: Silksong",,playable,2025-09-04 17:23:22
|
|
||||||
0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56
|
0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56
|
||||||
0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56
|
0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56
|
||||||
010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38
|
010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38
|
||||||
@@ -1526,7 +1518,6 @@
|
|||||||
010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53
|
010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53
|
||||||
0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15
|
0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15
|
||||||
0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22
|
0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22
|
||||||
010059801B736000,"IronFall: Invasion",,playable,2025-07-30 11:42:30
|
|
||||||
01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57
|
01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57
|
||||||
01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29
|
01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29
|
||||||
0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37
|
0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37
|
||||||
@@ -1890,7 +1881,7 @@
|
|||||||
010097800EA20000,"Monster Energy Supercross - The Official Videogame 3",UE4;audout;nvdec;online,playable,2021-06-14 12:37:54
|
010097800EA20000,"Monster Energy Supercross - The Official Videogame 3",UE4;audout;nvdec;online,playable,2021-06-14 12:37:54
|
||||||
0100E9900ED74000,"Monster Farm",32-bit;nvdec,playable,2021-05-05 19:29:13
|
0100E9900ED74000,"Monster Farm",32-bit;nvdec,playable,2021-05-05 19:29:13
|
||||||
0100770008DD8000,"Monster Hunter Generations Ultimate™",32-bit;online-broken;ldn-works,playable,2024-03-18 14:35:36
|
0100770008DD8000,"Monster Hunter Generations Ultimate™",32-bit;online-broken;ldn-works,playable,2024-03-18 14:35:36
|
||||||
0100B04011742000,"MONSTER HUNTER RISE",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59
|
0100B04011742000,"Monster Hunter Rise",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59
|
||||||
010093A01305C000,"Monster Hunter Rise Demo",online-broken;ldn-works;demo,playable,2022-10-18 23:04:17
|
010093A01305C000,"Monster Hunter Rise Demo",online-broken;ldn-works;demo,playable,2022-10-18 23:04:17
|
||||||
0100E21011446000,"Monster Hunter Stories 2: Wings of Ruin",services,ingame,2022-07-10 19:27:30
|
0100E21011446000,"Monster Hunter Stories 2: Wings of Ruin",services,ingame,2022-07-10 19:27:30
|
||||||
010042501329E000,"MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version",demo,playable,2022-11-13 22:20:26
|
010042501329E000,"MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version",demo,playable,2022-11-13 22:20:26
|
||||||
@@ -2272,7 +2263,6 @@
|
|||||||
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
||||||
01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20
|
01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20
|
||||||
0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
||||||
010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
|
||||||
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
|
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
|
||||||
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
|
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
|
||||||
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
|
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
|
||||||
@@ -2280,7 +2270,6 @@
|
|||||||
01008F6008C5E000,"Pokémon™ Violet",gpu;nvdec;ldn-works;amd-vendor-bug;mac-bug,ingame,2024-07-30 02:51:48
|
01008F6008C5E000,"Pokémon™ Violet",gpu;nvdec;ldn-works;amd-vendor-bug;mac-bug,ingame,2024-07-30 02:51:48
|
||||||
0100187003A36000,"Pokémon™: Let’s Go, Eevee!",crash;nvdec;online-broken;ldn-broken,ingame,2024-06-01 15:03:04
|
0100187003A36000,"Pokémon™: Let’s Go, Eevee!",crash;nvdec;online-broken;ldn-broken,ingame,2024-06-01 15:03:04
|
||||||
010003F003A34000,"Pokémon™: Let’s Go, Pikachu!",crash;nvdec;online-broken;ldn-broken,ingame,2024-03-15 07:55:41
|
010003F003A34000,"Pokémon™: Let’s Go, Pikachu!",crash;nvdec;online-broken;ldn-broken,ingame,2024-03-15 07:55:41
|
||||||
0100F43008C44000,"Pokémon Legends: Z-A",gpu;crash;ldn-broken,ingame,2025-10-16 19:13:00
|
|
||||||
0100B3F000BE2000,"Pokkén Tournament™ DX",nvdec;ldn-works;opengl-backend-bug;LAN;amd-vendor-bug;intel-vendor-bug,playable,2024-07-18 23:11:08
|
0100B3F000BE2000,"Pokkén Tournament™ DX",nvdec;ldn-works;opengl-backend-bug;LAN;amd-vendor-bug;intel-vendor-bug,playable,2024-07-18 23:11:08
|
||||||
010030D005AE6000,"Pokkén Tournament™ DX Demo",demo;opengl-backend-bug,playable,2022-08-10 12:03:19
|
010030D005AE6000,"Pokkén Tournament™ DX Demo",demo;opengl-backend-bug,playable,2022-08-10 12:03:19
|
||||||
0100A3500B4EC000,"Polandball: Can Into Space",,playable,2020-06-25 15:13:26
|
0100A3500B4EC000,"Polandball: Can Into Space",,playable,2020-06-25 15:13:26
|
||||||
@@ -2317,7 +2306,6 @@
|
|||||||
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
|
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
|
||||||
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
|
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
|
||||||
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
|
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
|
||||||
0100C3A017834000,"Prodeus",,playable,2025-07-30 12:07:52
|
|
||||||
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
|
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
|
||||||
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
|
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
|
||||||
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
|
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
|
||||||
@@ -2583,7 +2571,6 @@
|
|||||||
0100C610154CA000,"Shadowrun: Hong Kong - Extended Edition",gpu;Needs Update,ingame,2022-10-04 20:53:09
|
0100C610154CA000,"Shadowrun: Hong Kong - Extended Edition",gpu;Needs Update,ingame,2022-10-04 20:53:09
|
||||||
010000000EEF0000,"Shadows 2: Perfidia",,playable,2020-08-07 12:43:46
|
010000000EEF0000,"Shadows 2: Perfidia",,playable,2020-08-07 12:43:46
|
||||||
0100AD700CBBE000,"Shadows of Adam",,playable,2021-01-11 13:35:58
|
0100AD700CBBE000,"Shadows of Adam",,playable,2021-01-11 13:35:58
|
||||||
010037A01F96C000,"Shadows of the Damned: Hella Remastered",,playable,2025-09-05 11:34:32
|
|
||||||
01002A800C064000,"Shadowverse Champions Battle",,playable,2022-10-02 22:59:29
|
01002A800C064000,"Shadowverse Champions Battle",,playable,2022-10-02 22:59:29
|
||||||
01003B90136DA000,"Shadowverse: Champion's Battle",crash,nothing,2023-03-06 00:31:50
|
01003B90136DA000,"Shadowverse: Champion's Battle",crash,nothing,2023-03-06 00:31:50
|
||||||
0100820013612000,"Shady Part of Me",,playable,2022-10-20 11:31:55
|
0100820013612000,"Shady Part of Me",,playable,2022-10-20 11:31:55
|
||||||
@@ -2710,8 +2697,6 @@
|
|||||||
01008F701C074000,"SONIC SUPERSTARS",gpu;nvdec,ingame,2023-10-28 17:48:07
|
01008F701C074000,"SONIC SUPERSTARS",gpu;nvdec,ingame,2023-10-28 17:48:07
|
||||||
010088801C150000,"Sonic Superstars Digital Art Book with Mini Digital Soundtrack",,playable,2024-08-20 13:26:56
|
010088801C150000,"Sonic Superstars Digital Art Book with Mini Digital Soundtrack",,playable,2024-08-20 13:26:56
|
||||||
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
|
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
|
||||||
010064B0242BE000,"Sonic Racing: CrossWorlds - Demo",gpu;vulkan-backend-bug;demo,ingame,2024-09-25 11:27:53
|
|
||||||
01006E001823C000,"Sonic Racing: CrossWorlds",gpu;vulkan-backend-bug;ldn-broken,ingame,2024-09-30 17:23:00
|
|
||||||
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
|
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
|
||||||
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
|
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
|
||||||
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken;vulkan-backend-bug;gpu,ingame,2025-01-21 17:35:10
|
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken;vulkan-backend-bug;gpu,ingame,2025-01-21 17:35:10
|
||||||
@@ -2783,7 +2768,7 @@
|
|||||||
0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51
|
0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51
|
||||||
01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19
|
01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19
|
||||||
0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19
|
0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19
|
||||||
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",,playable,2025-07-30 12:09:37
|
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",services-horizon;crash;Needs Update,nothing,2024-05-05 17:25:11
|
||||||
010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43
|
010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43
|
||||||
01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55
|
01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55
|
||||||
010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05
|
010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05
|
||||||
@@ -2869,13 +2854,11 @@
|
|||||||
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
|
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
|
||||||
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
|
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
|
||||||
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
|
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
|
||||||
010099C022B96000,"Super Mario Galaxy",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug,ingame,2025-10-01 15:30:00
|
|
||||||
0100FD8022DAA000,"Super Mario Galaxy 2",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug;deadlock,ingame,2025-10-04 18:50:00
|
|
||||||
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
|
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
|
||||||
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
|
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
|
||||||
01009C200D60E000,"Super Meat Boy Forever",gpu,boots,2021-04-26 14:25:39
|
01009C200D60E000,"Super Meat Boy Forever",gpu,boots,2021-04-26 14:25:39
|
||||||
0100BDD00EC5C000,"Super Mega Space Blaster Special Turbo",online,playable,2020-08-06 12:13:25
|
0100BDD00EC5C000,"Super Mega Space Blaster Special Turbo",online,playable,2020-08-06 12:13:25
|
||||||
010031F019294000,"Super Monkey Ball Banana Rumble",ldn-broken,playable,2025-10-01 18:03:00
|
010031F019294000,"Super Monkey Ball Banana Rumble",,playable,2024-06-28 10:39:18
|
||||||
0100B2A00E1E0000,"Super Monkey Ball: Banana Blitz HD",online-broken,playable,2022-09-16 13:16:25
|
0100B2A00E1E0000,"Super Monkey Ball: Banana Blitz HD",online-broken,playable,2022-09-16 13:16:25
|
||||||
01006D000D2A0000,"Super Mutant Alien Assault",,playable,2020-06-07 23:32:45
|
01006D000D2A0000,"Super Mutant Alien Assault",,playable,2020-06-07 23:32:45
|
||||||
01004D600AC14000,"Super Neptunia RPG",nvdec,playable,2022-08-17 16:38:52
|
01004D600AC14000,"Super Neptunia RPG",nvdec,playable,2022-08-17 16:38:52
|
||||||
@@ -2941,7 +2924,6 @@
|
|||||||
0100B76011DAA000,"Taxi Chaos",slow;online-broken;UE4,playable,2022-10-25 19:13:00
|
0100B76011DAA000,"Taxi Chaos",slow;online-broken;UE4,playable,2022-10-25 19:13:00
|
||||||
0100F43011E5A000,"Tcheco in the Castle of Lucio",,playable,2020-06-27 13:35:43
|
0100F43011E5A000,"Tcheco in the Castle of Lucio",,playable,2020-06-27 13:35:43
|
||||||
010092B0091D0000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
|
010092B0091D0000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
|
||||||
010084B00B36E000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
|
|
||||||
0100FE701475A000,"Teenage Mutant Ninja Turtles: Shredder's Revenge",deadlock;crash,boots,2024-09-28 09:31:39
|
0100FE701475A000,"Teenage Mutant Ninja Turtles: Shredder's Revenge",deadlock;crash,boots,2024-09-28 09:31:39
|
||||||
01005CF01E784000,"Teenage Mutant Ninja Turtles: Splintered Fate",,playable,2024-08-03 13:50:42
|
01005CF01E784000,"Teenage Mutant Ninja Turtles: Splintered Fate",,playable,2024-08-03 13:50:42
|
||||||
0100FDB0154E4000,"Teenage Mutant Ninja Turtles: The Cowabunga Collection",,playable,2024-01-22 19:39:04
|
0100FDB0154E4000,"Teenage Mutant Ninja Turtles: The Cowabunga Collection",,playable,2024-01-22 19:39:04
|
||||||
@@ -2987,7 +2969,6 @@
|
|||||||
0100EBA01548E000,"The Cruel King and the Great Hero",gpu;services,ingame,2022-12-02 07:02:08
|
0100EBA01548E000,"The Cruel King and the Great Hero",gpu;services,ingame,2022-12-02 07:02:08
|
||||||
010051800E922000,"The Dark Crystal: Age of Resistance Tactics",,playable,2020-08-11 13:43:41
|
010051800E922000,"The Dark Crystal: Age of Resistance Tactics",,playable,2020-08-11 13:43:41
|
||||||
01003DE00918E000,"The Darkside Detective",,playable,2020-06-03 22:16:18
|
01003DE00918E000,"The Darkside Detective",,playable,2020-06-03 22:16:18
|
||||||
010032B015D66000,"The DioField Chronicle",,playable,2025-09-05 11:35:50
|
|
||||||
01000A10041EA000,"The Elder Scrolls V: Skyrim",gpu;crash,ingame,2024-07-14 03:21:31
|
01000A10041EA000,"The Elder Scrolls V: Skyrim",gpu;crash,ingame,2024-07-14 03:21:31
|
||||||
01004A9006B84000,"The End Is Nigh",,playable,2020-06-01 11:26:45
|
01004A9006B84000,"The End Is Nigh",,playable,2020-06-01 11:26:45
|
||||||
0100CA100489C000,"The Escapists 2",nvdec,playable,2020-09-24 12:31:31
|
0100CA100489C000,"The Escapists 2",nvdec,playable,2020-09-24 12:31:31
|
||||||
@@ -2995,7 +2976,6 @@
|
|||||||
0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28
|
0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28
|
||||||
01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35
|
01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35
|
||||||
0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06
|
0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06
|
||||||
0100BA5013E52000,"The Falconeer: Warrior Edition",,playable,2025-07-30 12:04:50
|
|
||||||
01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16
|
01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16
|
||||||
01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08
|
01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08
|
||||||
0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39
|
0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39
|
||||||
@@ -3218,7 +3198,6 @@
|
|||||||
010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05
|
010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05
|
||||||
0100752011628000,"TTV2",,playable,2020-11-27 13:21:36
|
0100752011628000,"TTV2",,playable,2020-11-27 13:21:36
|
||||||
0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20
|
0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20
|
||||||
0100D1A01D7BA000,"Turbo Overkill",,playable,2025-07-30 12:08:57
|
|
||||||
010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24
|
010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24
|
||||||
0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05
|
0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05
|
||||||
010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56
|
010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56
|
||||||
@@ -3228,7 +3207,6 @@
|
|||||||
010038400C2FE000,"TY the Tasmanian Tiger™ HD",32-bit;crash;nvdec,menus,2020-12-17 21:15:00
|
010038400C2FE000,"TY the Tasmanian Tiger™ HD",32-bit;crash;nvdec,menus,2020-12-17 21:15:00
|
||||||
010073A00C4B2000,"Tyd wag vir Niemand",,playable,2021-03-02 13:39:53
|
010073A00C4B2000,"Tyd wag vir Niemand",,playable,2021-03-02 13:39:53
|
||||||
0100D5B00D6DA000,"Type:Rider",,playable,2021-01-06 13:12:55
|
0100D5B00D6DA000,"Type:Rider",,playable,2021-01-06 13:12:55
|
||||||
01008AF01AD22000,"The Patrick Star Game",,playable,2025-10-01 17:55:30
|
|
||||||
010040D01222C000,"UBERMOSH: SANTICIDE",,playable,2020-11-27 15:05:01
|
010040D01222C000,"UBERMOSH: SANTICIDE",,playable,2020-11-27 15:05:01
|
||||||
0100992010BF8000,"Ubongo",,playable,2021-02-04 21:15:01
|
0100992010BF8000,"Ubongo",,playable,2021-02-04 21:15:01
|
||||||
010079000B56C000,"UglyDolls: An Imperfect Adventure",nvdec;UE4,playable,2022-08-25 14:42:16
|
010079000B56C000,"UglyDolls: An Imperfect Adventure",nvdec;UE4,playable,2022-08-25 14:42:16
|
||||||
@@ -3243,8 +3221,6 @@
|
|||||||
0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56
|
0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56
|
||||||
01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45
|
01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45
|
||||||
010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18
|
010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18
|
||||||
01009B700D0B8000,"Undead Horde",,playable,2025-07-30 12:05:05
|
|
||||||
0100FC301A878000,"Undead Horde 2: Necropolis",,playable,2025-07-30 12:06:07
|
|
||||||
01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58
|
01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58
|
||||||
010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46
|
010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46
|
||||||
01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00
|
01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00
|
||||||
@@ -3475,6 +3451,3 @@
|
|||||||
0100F4401940A000,"超探偵事件簿 レインコード (Master Detective Archives: Rain Code)",crash,ingame,2024-02-12 20:58:31
|
0100F4401940A000,"超探偵事件簿 レインコード (Master Detective Archives: Rain Code)",crash,ingame,2024-02-12 20:58:31
|
||||||
010064801A01C000,"超次元ゲイム ネプテューヌ GameMaker R:Evolution",crash,nothing,2023-10-30 22:37:40
|
010064801A01C000,"超次元ゲイム ネプテューヌ GameMaker R:Evolution",crash,nothing,2023-10-30 22:37:40
|
||||||
0100F3400332C000,"ゼノブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
|
0100F3400332C000,"ゼノブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
|
||||||
010075000ECBE000,"超级马力欧 奥德赛",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
|
|
||||||
010075100E8EC000,"马力欧卡丁车8 豪华版",32-bit;ldn-works;LAN;amd-vendor-bug,playable,2024-09-19 11:55:17
|
|
||||||
0100E8C00F506000,"新 超级马力欧兄弟U 豪华版",32-bit,playable,2023-10-08 02:06:37
|
|
||||||
|
|||||||
|
@@ -1107,17 +1107,17 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((flags & InstructionFlags.Prefix66) != 0)
|
if (flags.HasFlag(InstructionFlags.Prefix66))
|
||||||
{
|
{
|
||||||
WriteByte(0x66);
|
WriteByte(0x66);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & InstructionFlags.PrefixF2) != 0f)
|
if (flags.HasFlag(InstructionFlags.PrefixF2))
|
||||||
{
|
{
|
||||||
WriteByte(0xf2);
|
WriteByte(0xf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & InstructionFlags.PrefixF3) != 0f)
|
if (flags.HasFlag(InstructionFlags.PrefixF3))
|
||||||
{
|
{
|
||||||
WriteByte(0xf3);
|
WriteByte(0xf3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen.RegisterAllocators;
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using Microsoft.IO;
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
enum X86Register
|
enum X86Register
|
||||||
|
|||||||
@@ -143,12 +143,6 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void EmitCall(ArmEmitterContext context, ulong immediate)
|
public static void EmitCall(ArmEmitterContext context, ulong immediate)
|
||||||
{
|
{
|
||||||
if (context.IsSingleStep)
|
|
||||||
{
|
|
||||||
context.Return(Const(immediate));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isRecursive = immediate == context.EntryAddress;
|
bool isRecursive = immediate == context.EntryAddress;
|
||||||
|
|
||||||
if (isRecursive)
|
if (isRecursive)
|
||||||
@@ -163,24 +157,12 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
|
public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
|
||||||
{
|
{
|
||||||
if (context.IsSingleStep)
|
EmitTableBranch(context, target, isJump: false);
|
||||||
{
|
|
||||||
if (target.Type == OperandType.I32)
|
|
||||||
{
|
|
||||||
target = context.ZeroExtend32(OperandType.I64, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Return(target);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EmitTableBranch(context, target, isJump: false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
|
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
|
||||||
{
|
{
|
||||||
if (isReturn || context.IsSingleStep)
|
if (isReturn)
|
||||||
{
|
{
|
||||||
if (target.Type == OperandType.I32)
|
if (target.Type == OperandType.I32)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using ARMeilleure.Decoders;
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using ARMeilleure.State;
|
|||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using ExecutionContext = ARMeilleure.State.ExecutionContext;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace ARMeilleure.IntermediateRepresentation
|
namespace ARMeilleure.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace ARMeilleure
|
|||||||
|
|
||||||
public static bool AllowLcqInFunctionTable { get; set; } = true;
|
public static bool AllowLcqInFunctionTable { get; set; } = true;
|
||||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||||
public static bool EnableDebugging { get; set; } = false;
|
|
||||||
|
|
||||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||||
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace ARMeilleure.State
|
namespace ARMeilleure.State
|
||||||
{
|
{
|
||||||
@@ -11,7 +10,7 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
internal nint NativeContextPtr => _nativeContext.BasePtr;
|
internal nint NativeContextPtr => _nativeContext.BasePtr;
|
||||||
|
|
||||||
internal bool Interrupted { get; private set; }
|
private bool _interrupted;
|
||||||
|
|
||||||
private readonly ICounter _counter;
|
private readonly ICounter _counter;
|
||||||
|
|
||||||
@@ -66,8 +65,6 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
public bool IsAarch32 { get; set; }
|
public bool IsAarch32 { get; set; }
|
||||||
|
|
||||||
public ulong ThreadUid { get; set; }
|
|
||||||
|
|
||||||
internal ExecutionMode ExecutionMode
|
internal ExecutionMode ExecutionMode
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -93,19 +90,14 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
private readonly ExceptionCallbackNoArgs _interruptCallback;
|
private readonly ExceptionCallbackNoArgs _interruptCallback;
|
||||||
private readonly ExceptionCallback _breakCallback;
|
private readonly ExceptionCallback _breakCallback;
|
||||||
private readonly ExceptionCallbackNoArgs _stepCallback;
|
|
||||||
private readonly ExceptionCallback _supervisorCallback;
|
private readonly ExceptionCallback _supervisorCallback;
|
||||||
private readonly ExceptionCallback _undefinedCallback;
|
private readonly ExceptionCallback _undefinedCallback;
|
||||||
|
|
||||||
internal int ShouldStep;
|
|
||||||
public ulong DebugPc { get; set; }
|
|
||||||
|
|
||||||
public ExecutionContext(
|
public ExecutionContext(
|
||||||
IJitMemoryAllocator allocator,
|
IJitMemoryAllocator allocator,
|
||||||
ICounter counter,
|
ICounter counter,
|
||||||
ExceptionCallbackNoArgs interruptCallback = null,
|
ExceptionCallbackNoArgs interruptCallback = null,
|
||||||
ExceptionCallback breakCallback = null,
|
ExceptionCallback breakCallback = null,
|
||||||
ExceptionCallbackNoArgs stepCallback = null,
|
|
||||||
ExceptionCallback supervisorCallback = null,
|
ExceptionCallback supervisorCallback = null,
|
||||||
ExceptionCallback undefinedCallback = null)
|
ExceptionCallback undefinedCallback = null)
|
||||||
{
|
{
|
||||||
@@ -113,7 +105,6 @@ namespace ARMeilleure.State
|
|||||||
_counter = counter;
|
_counter = counter;
|
||||||
_interruptCallback = interruptCallback;
|
_interruptCallback = interruptCallback;
|
||||||
_breakCallback = breakCallback;
|
_breakCallback = breakCallback;
|
||||||
_stepCallback = stepCallback;
|
|
||||||
_supervisorCallback = supervisorCallback;
|
_supervisorCallback = supervisorCallback;
|
||||||
_undefinedCallback = undefinedCallback;
|
_undefinedCallback = undefinedCallback;
|
||||||
|
|
||||||
@@ -136,9 +127,9 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
internal void CheckInterrupt()
|
internal void CheckInterrupt()
|
||||||
{
|
{
|
||||||
if (Interrupted)
|
if (_interrupted)
|
||||||
{
|
{
|
||||||
Interrupted = false;
|
_interrupted = false;
|
||||||
|
|
||||||
_interruptCallback?.Invoke(this);
|
_interruptCallback?.Invoke(this);
|
||||||
}
|
}
|
||||||
@@ -148,37 +139,16 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
public void RequestInterrupt()
|
public void RequestInterrupt()
|
||||||
{
|
{
|
||||||
Interrupted = true;
|
_interrupted = true;
|
||||||
}
|
|
||||||
|
|
||||||
public void StepHandler()
|
|
||||||
{
|
|
||||||
_stepCallback?.Invoke(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RequestDebugStep()
|
|
||||||
{
|
|
||||||
Interlocked.Exchange(ref ShouldStep, 1);
|
|
||||||
RequestInterrupt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnBreak(ulong address, int imm)
|
internal void OnBreak(ulong address, int imm)
|
||||||
{
|
{
|
||||||
if (Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
DebugPc = Pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
_breakCallback?.Invoke(this, address, imm);
|
_breakCallback?.Invoke(this, address, imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnSupervisorCall(ulong address, int imm)
|
internal void OnSupervisorCall(ulong address, int imm)
|
||||||
{
|
{
|
||||||
if (Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
DebugPc = Pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
_supervisorCallback?.Invoke(this, address, imm);
|
_supervisorCallback?.Invoke(this, address, imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,6 @@ namespace ARMeilleure.State
|
|||||||
public ulong ExclusiveValueHigh;
|
public ulong ExclusiveValueHigh;
|
||||||
public int Running;
|
public int Running;
|
||||||
public long Tpidr2El0;
|
public long Tpidr2El0;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Precise PC value used for debugging.
|
|
||||||
/// This will only be set when Optimizations.EnableDebugging is true.
|
|
||||||
/// </summary>
|
|
||||||
public ulong DebugPrecisePc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeCtxStorage _dummyStorage = new();
|
private static NativeCtxStorage _dummyStorage = new();
|
||||||
@@ -45,11 +39,6 @@ namespace ARMeilleure.State
|
|||||||
|
|
||||||
public ulong GetPc()
|
public ulong GetPc()
|
||||||
{
|
{
|
||||||
if (Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
return GetStorage().DebugPrecisePc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: More precise tracking of PC value.
|
// TODO: More precise tracking of PC value.
|
||||||
return GetStorage().DispatchAddress;
|
return GetStorage().DispatchAddress;
|
||||||
}
|
}
|
||||||
@@ -279,11 +268,6 @@ namespace ARMeilleure.State
|
|||||||
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
|
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetDebugPrecisePcOffset()
|
|
||||||
{
|
|
||||||
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
|
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
|
||||||
{
|
{
|
||||||
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
|
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ namespace ARMeilleure.Translation
|
|||||||
public bool HighCq { get; }
|
public bool HighCq { get; }
|
||||||
public bool HasPtc { get; }
|
public bool HasPtc { get; }
|
||||||
public Aarch32Mode Mode { get; }
|
public Aarch32Mode Mode { get; }
|
||||||
public bool IsSingleStep { get; }
|
|
||||||
|
|
||||||
private int _ifThenBlockStateIndex = 0;
|
private int _ifThenBlockStateIndex = 0;
|
||||||
private Condition[] _ifThenBlockState = [];
|
private Condition[] _ifThenBlockState = [];
|
||||||
@@ -67,8 +66,7 @@ namespace ARMeilleure.Translation
|
|||||||
ulong entryAddress,
|
ulong entryAddress,
|
||||||
bool highCq,
|
bool highCq,
|
||||||
bool hasPtc,
|
bool hasPtc,
|
||||||
Aarch32Mode mode,
|
Aarch32Mode mode)
|
||||||
bool isSingleStep)
|
|
||||||
{
|
{
|
||||||
Memory = memory;
|
Memory = memory;
|
||||||
CountTable = countTable;
|
CountTable = countTable;
|
||||||
@@ -78,7 +76,6 @@ namespace ARMeilleure.Translation
|
|||||||
HighCq = highCq;
|
HighCq = highCq;
|
||||||
HasPtc = hasPtc;
|
HasPtc = hasPtc;
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
IsSingleStep = isSingleStep;
|
|
||||||
|
|
||||||
_labels = new Dictionary<ulong, Operand>();
|
_labels = new Dictionary<ulong, Operand>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 7009; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 7008; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
@@ -303,13 +303,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outerHeader.DebuggerMode != Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
InvalidateCompressedStream(compressedStream);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nint intPtr = nint.Zero;
|
nint intPtr = nint.Zero;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -486,7 +479,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
MemoryManagerMode = GetMemoryManagerMode(),
|
MemoryManagerMode = GetMemoryManagerMode(),
|
||||||
OSPlatform = GetOSPlatform(),
|
OSPlatform = GetOSPlatform(),
|
||||||
Architecture = (uint)RuntimeInformation.ProcessArchitecture,
|
Architecture = (uint)RuntimeInformation.ProcessArchitecture,
|
||||||
DebuggerMode = Optimizations.EnableDebugging,
|
|
||||||
|
|
||||||
UncompressedStreamSize =
|
UncompressedStreamSize =
|
||||||
(long)Unsafe.SizeOf<InnerHeader>() +
|
(long)Unsafe.SizeOf<InnerHeader>() +
|
||||||
@@ -1076,7 +1068,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return osPlatform;
|
return osPlatform;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 87*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 86*/)]
|
||||||
private struct OuterHeader
|
private struct OuterHeader
|
||||||
{
|
{
|
||||||
public ulong Magic;
|
public ulong Magic;
|
||||||
@@ -1088,7 +1080,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
public byte MemoryManagerMode;
|
public byte MemoryManagerMode;
|
||||||
public uint OSPlatform;
|
public uint OSPlatform;
|
||||||
public uint Architecture;
|
public uint Architecture;
|
||||||
public bool DebuggerMode;
|
|
||||||
|
|
||||||
public long UncompressedStreamSize;
|
public long UncompressedStreamSize;
|
||||||
|
|
||||||
|
|||||||
@@ -119,25 +119,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
NativeInterface.RegisterThread(context, Memory, this);
|
NativeInterface.RegisterThread(context, Memory, this);
|
||||||
|
|
||||||
if (Optimizations.EnableDebugging)
|
if (Optimizations.UseUnmanagedDispatchLoop)
|
||||||
{
|
|
||||||
context.DebugPc = address;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
|
|
||||||
{
|
|
||||||
context.DebugPc = Step(context, context.DebugPc);
|
|
||||||
context.StepHandler();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context.DebugPc = ExecuteSingle(context, context.DebugPc);
|
|
||||||
}
|
|
||||||
context.CheckInterrupt();
|
|
||||||
}
|
|
||||||
while (context.Running && context.DebugPc != 0);
|
|
||||||
}
|
|
||||||
else if (Optimizations.UseUnmanagedDispatchLoop)
|
|
||||||
{
|
{
|
||||||
Stubs.DispatchLoop(context.NativeContextPtr, address);
|
Stubs.DispatchLoop(context.NativeContextPtr, address);
|
||||||
}
|
}
|
||||||
@@ -193,7 +175,7 @@ namespace ARMeilleure.Translation
|
|||||||
return nextAddr;
|
return nextAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong Step(State.ExecutionContext context, ulong address)
|
public ulong Step(State.ExecutionContext context, ulong address)
|
||||||
{
|
{
|
||||||
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
|
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
|
||||||
|
|
||||||
@@ -204,8 +186,6 @@ namespace ARMeilleure.Translation
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
|
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
|
||||||
{
|
{
|
||||||
if (!Functions.TryGetValue(address, out TranslatedFunction func))
|
if (!Functions.TryGetValue(address, out TranslatedFunction func))
|
||||||
@@ -249,8 +229,7 @@ namespace ARMeilleure.Translation
|
|||||||
address,
|
address,
|
||||||
highCq,
|
highCq,
|
||||||
_ptc.State != PtcState.Disabled,
|
_ptc.State != PtcState.Disabled,
|
||||||
mode: Aarch32Mode.User,
|
mode: Aarch32Mode.User);
|
||||||
isSingleStep: singleStep);
|
|
||||||
|
|
||||||
Logger.StartPass(PassName.Decoding);
|
Logger.StartPass(PassName.Decoding);
|
||||||
|
|
||||||
@@ -388,13 +367,9 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
if (block.Exit)
|
if (block.Exit)
|
||||||
{
|
{
|
||||||
// Return to managed rather than tail call.
|
// Left option here as it may be useful if we need to return to managed rather than tail call in
|
||||||
bool useReturns = Optimizations.EnableDebugging;
|
// future. (eg. for debug)
|
||||||
|
bool useReturns = false;
|
||||||
if (Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
EmitDebugPrecisePcUpdate(context, block.Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
|
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
|
||||||
}
|
}
|
||||||
@@ -418,11 +393,6 @@ namespace ARMeilleure.Translation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
EmitDebugPrecisePcUpdate(context, opCode.Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
Operand lblPredicateSkip = default;
|
Operand lblPredicateSkip = default;
|
||||||
|
|
||||||
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
|
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
|
||||||
@@ -519,14 +489,6 @@ namespace ARMeilleure.Translation
|
|||||||
context.MarkLabel(lblExit);
|
context.MarkLabel(lblExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void EmitDebugPrecisePcUpdate(EmitterContext context, ulong address)
|
|
||||||
{
|
|
||||||
long debugPrecisePcOffs = NativeContext.GetDebugPrecisePcOffset();
|
|
||||||
|
|
||||||
Operand debugPrecisePcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(debugPrecisePcOffs));
|
|
||||||
context.Store(debugPrecisePcAddr, Const(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
ulong[] overlapAddresses = [];
|
ulong[] overlapAddresses = [];
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
|
<ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.SDL3.Common\Ryujinx.SDL3.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.SDL2.Common\Ryujinx.SDL2.Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
namespace Ryujinx.Audio.Backends.SDL3
|
namespace Ryujinx.Audio.Backends.SDL2
|
||||||
{
|
{
|
||||||
class SDL3AudioBuffer
|
class SDL2AudioBuffer
|
||||||
{
|
{
|
||||||
public readonly ulong DriverIdentifier;
|
public readonly ulong DriverIdentifier;
|
||||||
public readonly ulong SampleCount;
|
public readonly ulong SampleCount;
|
||||||
public ulong SamplePlayed;
|
public ulong SamplePlayed;
|
||||||
|
|
||||||
public SDL3AudioBuffer(ulong driverIdentifier, ulong sampleCount)
|
public SDL2AudioBuffer(ulong driverIdentifier, ulong sampleCount)
|
||||||
{
|
{
|
||||||
DriverIdentifier = driverIdentifier;
|
DriverIdentifier = driverIdentifier;
|
||||||
SampleCount = sampleCount;
|
SampleCount = sampleCount;
|
||||||
@@ -2,41 +2,42 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Integration;
|
using Ryujinx.Audio.Integration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using Ryujinx.SDL3.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
||||||
using SDL;
|
using static SDL2.SDL;
|
||||||
using static SDL.SDL3;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
|
namespace Ryujinx.Audio.Backends.SDL2
|
||||||
namespace Ryujinx.Audio.Backends.SDL3
|
|
||||||
{
|
{
|
||||||
|
public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
using unsafe SDL_AudioStreamCallbackPointer = delegate* unmanaged[Cdecl]<nint, SDL_AudioStream*, int, int, void>;
|
|
||||||
|
|
||||||
public class SDL3HardwareDeviceDriver : IHardwareDeviceDriver
|
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent;
|
||||||
private readonly ManualResetEvent _pauseEvent;
|
private readonly ManualResetEvent _pauseEvent;
|
||||||
private readonly ConcurrentDictionary<SDL3HardwareDeviceSession, byte> _sessions;
|
private readonly ConcurrentDictionary<SDL2HardwareDeviceSession, byte> _sessions;
|
||||||
|
|
||||||
private readonly bool _supportSurroundConfiguration;
|
private readonly bool _supportSurroundConfiguration;
|
||||||
|
|
||||||
public float Volume { get; set; }
|
public float Volume { get; set; }
|
||||||
|
|
||||||
public unsafe SDL3HardwareDeviceDriver()
|
// TODO: Add this to SDL2-CS
|
||||||
|
// NOTE: We use a DllImport here because of marshaling issue for spec.
|
||||||
|
[DllImport("SDL2")]
|
||||||
|
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture);
|
||||||
|
|
||||||
|
public SDL2HardwareDeviceDriver()
|
||||||
{
|
{
|
||||||
_updateRequiredEvent = new ManualResetEvent(false);
|
_updateRequiredEvent = new ManualResetEvent(false);
|
||||||
_pauseEvent = new ManualResetEvent(true);
|
_pauseEvent = new ManualResetEvent(true);
|
||||||
_sessions = new ConcurrentDictionary<SDL3HardwareDeviceSession, byte>();
|
_sessions = new ConcurrentDictionary<SDL2HardwareDeviceSession, byte>();
|
||||||
|
|
||||||
SDL3Driver.Instance.Initialize();
|
SDL2Driver.Instance.Initialize();
|
||||||
|
|
||||||
SDL_AudioSpec spec;
|
int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
|
||||||
if (!SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, null))
|
|
||||||
|
if (res != 0)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application,
|
Logger.Error?.Print(LogClass.Application,
|
||||||
$"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\"");
|
$"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\"");
|
||||||
@@ -53,16 +54,16 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
|
|
||||||
public static bool IsSupported => IsSupportedInternal();
|
public static bool IsSupported => IsSupportedInternal();
|
||||||
|
|
||||||
private unsafe static bool IsSupportedInternal()
|
private static bool IsSupportedInternal()
|
||||||
{
|
{
|
||||||
SDL_AudioStream* device = OpenStream(SampleFormat.PcmInt16, Constants.TargetSampleRate, Constants.ChannelCountMax, Constants.TargetSampleCount, null);
|
uint device = OpenStream(SampleFormat.PcmInt16, Constants.TargetSampleRate, Constants.ChannelCountMax, Constants.TargetSampleCount, null);
|
||||||
|
|
||||||
if (device != null)
|
if (device != 0)
|
||||||
{
|
{
|
||||||
SDL_DestroyAudioStream(device);
|
SDL_CloseAudioDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
return device != null;
|
return device != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManualResetEvent GetUpdateRequiredEvent()
|
public ManualResetEvent GetUpdateRequiredEvent()
|
||||||
@@ -89,68 +90,67 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
|
|
||||||
if (direction != Direction.Output)
|
if (direction != Direction.Output)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Input direction is currently not implemented on SDL3 backend!");
|
throw new NotImplementedException("Input direction is currently not implemented on SDL2 backend!");
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL3HardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
SDL2HardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
||||||
|
|
||||||
_sessions.TryAdd(session, 0);
|
_sessions.TryAdd(session, 0);
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Unregister(SDL3HardwareDeviceSession session)
|
internal bool Unregister(SDL2HardwareDeviceSession session)
|
||||||
{
|
{
|
||||||
return _sessions.TryRemove(session, out _);
|
return _sessions.TryRemove(session, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SDL_AudioSpec GetSDL3Spec(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount)
|
private static SDL_AudioSpec GetSDL2Spec(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount)
|
||||||
{
|
{
|
||||||
return new SDL_AudioSpec
|
return new SDL_AudioSpec
|
||||||
{
|
{
|
||||||
channels = (byte)requestedChannelCount,
|
channels = (byte)requestedChannelCount,
|
||||||
format = GetSDL3Format(requestedSampleFormat),
|
format = GetSDL2Format(requestedSampleFormat),
|
||||||
freq = (int)requestedSampleRate,
|
freq = (int)requestedSampleRate,
|
||||||
|
samples = (ushort)sampleCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static SDL_AudioFormat GetSDL3Format(SampleFormat format)
|
internal static ushort GetSDL2Format(SampleFormat format)
|
||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
SampleFormat.PcmInt8 => SDL_AudioFormat.SDL_AUDIO_S8,
|
SampleFormat.PcmInt8 => AUDIO_S8,
|
||||||
SampleFormat.PcmInt16 => SDL_AudioFormat.SDL_AUDIO_S16LE,
|
SampleFormat.PcmInt16 => AUDIO_S16,
|
||||||
SampleFormat.PcmInt32 => SDL_AudioFormat.SDL_AUDIO_S32LE,
|
SampleFormat.PcmInt32 => AUDIO_S32,
|
||||||
SampleFormat.PcmFloat => SDL_AudioFormat.SDL_AUDIO_F32LE,
|
SampleFormat.PcmFloat => AUDIO_F32,
|
||||||
_ => throw new ArgumentException($"Unsupported sample format {format}"),
|
_ => throw new ArgumentException($"Unsupported sample format {format}"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe static SDL_AudioStream* OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount, SDL3HardwareDeviceSession.SDL_AudioStreamCallback callback)
|
internal static uint OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount, SDL_AudioCallback callback)
|
||||||
{
|
{
|
||||||
SDL_AudioSpec desired = GetSDL3Spec(requestedSampleFormat, requestedSampleRate, requestedChannelCount);
|
SDL_AudioSpec desired = GetSDL2Spec(requestedSampleFormat, requestedSampleRate, requestedChannelCount, sampleCount);
|
||||||
SDL_AudioSpec got = desired;
|
|
||||||
var pCallback = callback != null ? (SDL_AudioStreamCallbackPointer)Marshal.GetFunctionPointerForDelegate(callback) : null;
|
|
||||||
|
|
||||||
// From SDL 3 and on, SDL requires us to set this as a hint
|
desired.callback = callback;
|
||||||
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, $"{sampleCount}");
|
|
||||||
SDL_AudioStream* device = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &got, pCallback, 0);
|
|
||||||
|
|
||||||
if (device == null)
|
uint device = SDL_OpenAudioDevice(nint.Zero, 0, ref desired, out SDL_AudioSpec got, 0);
|
||||||
|
|
||||||
|
if (device == 0)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, $"SDL3 open audio device initialization failed with error \"{SDL_GetError()}\"");
|
Logger.Error?.Print(LogClass.Application, $"SDL2 open audio device initialization failed with error \"{SDL_GetError()}\"");
|
||||||
|
|
||||||
return null;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid = got.format == desired.format && got.freq == desired.freq && got.channels == desired.channels;
|
bool isValid = got.format == desired.format && got.freq == desired.freq && got.channels == desired.channels;
|
||||||
|
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, "SDL3 open audio device is not valid");
|
Logger.Error?.Print(LogClass.Application, "SDL2 open audio device is not valid");
|
||||||
SDL_DestroyAudioStream(device);
|
SDL_CloseAudioDevice(device);
|
||||||
|
|
||||||
return null;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
@@ -166,12 +166,12 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
foreach (SDL3HardwareDeviceSession session in _sessions.Keys)
|
foreach (SDL2HardwareDeviceSession session in _sessions.Keys)
|
||||||
{
|
{
|
||||||
session.Dispose();
|
session.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL3Driver.Instance.Dispose();
|
SDL2Driver.Instance.Dispose();
|
||||||
|
|
||||||
_pauseEvent.Dispose();
|
_pauseEvent.Dispose();
|
||||||
}
|
}
|
||||||
@@ -6,43 +6,36 @@ using Ryujinx.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using SDL;
|
|
||||||
using static SDL.SDL3;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.SDL3
|
using static SDL2.SDL;
|
||||||
|
|
||||||
|
namespace Ryujinx.Audio.Backends.SDL2
|
||||||
{
|
{
|
||||||
|
class SDL2HardwareDeviceSession : HardwareDeviceSessionOutputBase
|
||||||
|
|
||||||
|
|
||||||
unsafe class SDL3HardwareDeviceSession : HardwareDeviceSessionOutputBase
|
|
||||||
{
|
{
|
||||||
private readonly SDL3HardwareDeviceDriver _driver;
|
private readonly SDL2HardwareDeviceDriver _driver;
|
||||||
private readonly ConcurrentQueue<SDL3AudioBuffer> _queuedBuffers;
|
private readonly ConcurrentQueue<SDL2AudioBuffer> _queuedBuffers;
|
||||||
private readonly DynamicRingBuffer _ringBuffer;
|
private readonly DynamicRingBuffer _ringBuffer;
|
||||||
private ulong _playedSampleCount;
|
private ulong _playedSampleCount;
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent;
|
||||||
private SDL_AudioStream* _outputStream;
|
private uint _outputStream;
|
||||||
private bool _hasSetupError;
|
private bool _hasSetupError;
|
||||||
private readonly SDL_AudioStreamCallback _callbackDelegate;
|
private readonly SDL_AudioCallback _callbackDelegate;
|
||||||
private readonly int _bytesPerFrame;
|
private readonly int _bytesPerFrame;
|
||||||
private uint _sampleCount;
|
private uint _sampleCount;
|
||||||
private bool _started;
|
private bool _started;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private readonly SDL_AudioFormat _nativeSampleFormat;
|
private readonly ushort _nativeSampleFormat;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
public SDL2HardwareDeviceSession(SDL2HardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||||
internal delegate void SDL_AudioStreamCallback(nint session, SDL_AudioStream* stream, int stream_count, int device_count);
|
|
||||||
|
|
||||||
public SDL3HardwareDeviceSession(SDL3HardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
|
||||||
{
|
{
|
||||||
_driver = driver;
|
_driver = driver;
|
||||||
_updateRequiredEvent = _driver.GetUpdateRequiredEvent();
|
_updateRequiredEvent = _driver.GetUpdateRequiredEvent();
|
||||||
_queuedBuffers = new ConcurrentQueue<SDL3AudioBuffer>();
|
_queuedBuffers = new ConcurrentQueue<SDL2AudioBuffer>();
|
||||||
_ringBuffer = new DynamicRingBuffer();
|
_ringBuffer = new DynamicRingBuffer();
|
||||||
_callbackDelegate = Update;
|
_callbackDelegate = Update;
|
||||||
_bytesPerFrame = BackendHelper.GetSampleSize(RequestedSampleFormat) * (int)RequestedChannelCount;
|
_bytesPerFrame = BackendHelper.GetSampleSize(RequestedSampleFormat) * (int)RequestedChannelCount;
|
||||||
_nativeSampleFormat = SDL3HardwareDeviceDriver.GetSDL3Format(RequestedSampleFormat);
|
_nativeSampleFormat = SDL2HardwareDeviceDriver.GetSDL2Format(RequestedSampleFormat);
|
||||||
_sampleCount = uint.MaxValue;
|
_sampleCount = uint.MaxValue;
|
||||||
_started = false;
|
_started = false;
|
||||||
_volume = 1f;
|
_volume = 1f;
|
||||||
@@ -51,51 +44,45 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
private void EnsureAudioStreamSetup(AudioBuffer buffer)
|
private void EnsureAudioStreamSetup(AudioBuffer buffer)
|
||||||
{
|
{
|
||||||
uint bufferSampleCount = (uint)GetSampleCount(buffer);
|
uint bufferSampleCount = (uint)GetSampleCount(buffer);
|
||||||
bool needAudioSetup = (_outputStream == null && !_hasSetupError) ||
|
bool needAudioSetup = (_outputStream == 0 && !_hasSetupError) ||
|
||||||
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
|
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
|
||||||
|
|
||||||
if (needAudioSetup)
|
if (needAudioSetup)
|
||||||
{
|
{
|
||||||
_sampleCount = Math.Max(Constants.TargetSampleCount, bufferSampleCount);
|
_sampleCount = Math.Max(Constants.TargetSampleCount, bufferSampleCount);
|
||||||
|
|
||||||
SDL_AudioStream* newOutputStream = SDL3HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
|
uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
|
||||||
|
|
||||||
_hasSetupError = newOutputStream == null;
|
_hasSetupError = newOutputStream == 0;
|
||||||
|
|
||||||
if (!_hasSetupError)
|
if (!_hasSetupError)
|
||||||
{
|
{
|
||||||
if (_outputStream != null)
|
if (_outputStream != 0)
|
||||||
{
|
{
|
||||||
SDL_DestroyAudioStream(_outputStream);
|
SDL_CloseAudioDevice(_outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_outputStream = newOutputStream;
|
_outputStream = newOutputStream;
|
||||||
|
|
||||||
if (_started) {
|
SDL_PauseAudioDevice(_outputStream, _started ? 0 : 1);
|
||||||
SDL_ResumeAudioStreamDevice(_outputStream);
|
|
||||||
} else {
|
|
||||||
SDL_PauseAudioStreamDevice(_outputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Audio, $"New audio stream setup with a target sample count of {_sampleCount}");
|
Logger.Info?.Print(LogClass.Audio, $"New audio stream setup with a target sample count of {_sampleCount}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void Update(nint userdata, SDL_AudioStream* streamDevice, int additionalAmount, int totalAmmount)
|
private unsafe void Update(nint userdata, nint stream, int streamLength)
|
||||||
{
|
{
|
||||||
using SpanOwner<byte> stream = SpanOwner<byte>.Rent(additionalAmount);
|
Span<byte> streamSpan = new((void*)stream, streamLength);
|
||||||
Span<byte> streamSpan = stream.Span;
|
|
||||||
|
|
||||||
|
int maxFrameCount = (int)GetSampleCount(streamLength);
|
||||||
int maxFrameCount = (int)GetSampleCount(additionalAmount);
|
|
||||||
int bufferedFrames = _ringBuffer.Length / _bytesPerFrame;
|
int bufferedFrames = _ringBuffer.Length / _bytesPerFrame;
|
||||||
|
|
||||||
int frameCount = Math.Min(bufferedFrames, maxFrameCount);
|
int frameCount = Math.Min(bufferedFrames, maxFrameCount);
|
||||||
|
|
||||||
if (frameCount == 0)
|
if (frameCount == 0)
|
||||||
{
|
{
|
||||||
// SDL3 left the responsibility to the user to clear the buffer.
|
// SDL2 left the responsibility to the user to clear the buffer.
|
||||||
streamSpan.Clear();
|
streamSpan.Clear();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -107,17 +94,15 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
|
|
||||||
_ringBuffer.Read(samples, 0, samples.Length);
|
_ringBuffer.Read(samples, 0, samples.Length);
|
||||||
|
|
||||||
// Zero the dest buffer
|
fixed (byte* p = samples)
|
||||||
streamSpan.Clear();
|
{
|
||||||
|
nint pStreamSrc = (nint)p;
|
||||||
|
|
||||||
fixed (byte* pStreamDst = streamSpan) {
|
// Zero the dest buffer
|
||||||
fixed (byte* pStreamSrc = samples)
|
streamSpan.Clear();
|
||||||
{
|
|
||||||
|
|
||||||
// Apply volume to written data
|
// Apply volume to written data
|
||||||
SDL_MixAudio(pStreamDst, pStreamSrc, _nativeSampleFormat, (uint)samples.Length, _driver.Volume * _volume);
|
SDL_MixAudioFormat(stream, pStreamSrc, _nativeSampleFormat, (uint)samples.Length, (int)(_driver.Volume * _volume * SDL_MIX_MAXVOLUME));
|
||||||
SDL_PutAudioStreamData(streamDevice, (nint)pStreamDst, additionalAmount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong sampleCount = GetSampleCount(samples.Length);
|
ulong sampleCount = GetSampleCount(samples.Length);
|
||||||
@@ -126,7 +111,7 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
|
|
||||||
bool needUpdate = false;
|
bool needUpdate = false;
|
||||||
|
|
||||||
while (availaibleSampleCount > 0 && _queuedBuffers.TryPeek(out SDL3AudioBuffer driverBuffer))
|
while (availaibleSampleCount > 0 && _queuedBuffers.TryPeek(out SDL2AudioBuffer driverBuffer))
|
||||||
{
|
{
|
||||||
ulong sampleStillNeeded = driverBuffer.SampleCount - Interlocked.Read(ref driverBuffer.SamplePlayed);
|
ulong sampleStillNeeded = driverBuffer.SampleCount - Interlocked.Read(ref driverBuffer.SamplePlayed);
|
||||||
ulong playedAudioBufferSampleCount = Math.Min(sampleStillNeeded, availaibleSampleCount);
|
ulong playedAudioBufferSampleCount = Math.Min(sampleStillNeeded, availaibleSampleCount);
|
||||||
@@ -167,9 +152,9 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
{
|
{
|
||||||
EnsureAudioStreamSetup(buffer);
|
EnsureAudioStreamSetup(buffer);
|
||||||
|
|
||||||
if (_outputStream != null)
|
if (_outputStream != 0)
|
||||||
{
|
{
|
||||||
SDL3AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
|
SDL2AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
|
||||||
|
|
||||||
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
|
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
|
||||||
|
|
||||||
@@ -192,9 +177,9 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
{
|
{
|
||||||
if (!_started)
|
if (!_started)
|
||||||
{
|
{
|
||||||
if (_outputStream != null)
|
if (_outputStream != 0)
|
||||||
{
|
{
|
||||||
SDL_ResumeAudioStreamDevice(_outputStream);
|
SDL_PauseAudioDevice(_outputStream, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_started = true;
|
_started = true;
|
||||||
@@ -205,9 +190,9 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
{
|
{
|
||||||
if (_started)
|
if (_started)
|
||||||
{
|
{
|
||||||
if (_outputStream != null)
|
if (_outputStream != 0)
|
||||||
{
|
{
|
||||||
SDL_PauseAudioStreamDevice(_outputStream);
|
SDL_PauseAudioDevice(_outputStream, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_started = false;
|
_started = false;
|
||||||
@@ -218,7 +203,7 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
|
|
||||||
public override bool WasBufferFullyConsumed(AudioBuffer buffer)
|
public override bool WasBufferFullyConsumed(AudioBuffer buffer)
|
||||||
{
|
{
|
||||||
if (!_queuedBuffers.TryPeek(out SDL3AudioBuffer driverBuffer))
|
if (!_queuedBuffers.TryPeek(out SDL2AudioBuffer driverBuffer))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -233,9 +218,9 @@ namespace Ryujinx.Audio.Backends.SDL3
|
|||||||
PrepareToClose();
|
PrepareToClose();
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
if (_outputStream != null)
|
if (_outputStream != 0)
|
||||||
{
|
{
|
||||||
SDL_DestroyAudioStream(_outputStream);
|
SDL_CloseAudioDevice(_outputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using Ryujinx.Audio.Renderer.Server;
|
|
||||||
using Ryujinx.Audio.Renderer.Server.MemoryPool;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Common
|
namespace Ryujinx.Audio.Renderer.Common
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the input parameter for <see cref="BehaviourInfo"/>.
|
/// Represents the input parameter for <see cref="Server.BehaviourContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct BehaviourParameter
|
public struct BehaviourParameter
|
||||||
@@ -23,7 +21,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The flags given controlling behaviour of the audio renderer
|
/// The flags given controlling behaviour of the audio renderer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>See <see cref="BehaviourInfo.UpdateFlags(ulong)"/> and <see cref="BehaviourInfo.IsMemoryPoolForceMappingEnabled"/>.</remarks>
|
/// <remarks>See <see cref="Server.BehaviourContext.UpdateFlags(ulong)"/> and <see cref="Server.BehaviourContext.IsMemoryPoolForceMappingEnabled"/>.</remarks>
|
||||||
public ulong Flags;
|
public ulong Flags;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -45,7 +43,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extra information given with the <see cref="ResultCode"/>
|
/// Extra information given with the <see cref="ResultCode"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This is usually used to report a faulting cpu address when a <see cref="MemoryPoolInfo"/> mapping fail.</remarks>
|
/// <remarks>This is usually used to report a faulting cpu address when a <see cref="Server.MemoryPool.MemoryPoolState"/> mapping fail.</remarks>
|
||||||
public ulong ExtraErrorInfo;
|
public ulong ExtraErrorInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
@@ -12,7 +11,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This is shared between the server and audio processor.</remarks>
|
/// <remarks>This is shared between the server and audio processor.</remarks>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = Align)]
|
[StructLayout(LayoutKind.Sequential, Pack = Align)]
|
||||||
public struct VoiceState
|
public struct VoiceUpdateState
|
||||||
{
|
{
|
||||||
public const int Align = 0x10;
|
public const int Align = 0x10;
|
||||||
public const int BiquadStateOffset = 0x0;
|
public const int BiquadStateOffset = 0x0;
|
||||||
@@ -26,7 +25,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// The total amount of samples that was played.
|
/// The total amount of samples that was played.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This is reset to 0 when a <see cref="WaveBuffer"/> finishes playing and <see cref="WaveBuffer.IsEndOfStream"/> is set.</remarks>
|
/// <remarks>This is reset to 0 when a <see cref="WaveBuffer"/> finishes playing and <see cref="WaveBuffer.IsEndOfStream"/> is set.</remarks>
|
||||||
/// <remarks>This is reset to 0 when looping while <see cref="VoiceInParameter1.DecodingBehaviour.PlayedSampleCountResetWhenLooping"/> is set.</remarks>
|
/// <remarks>This is reset to 0 when looping while <see cref="Parameter.VoiceInParameter.DecodingBehaviour.PlayedSampleCountResetWhenLooping"/> is set.</remarks>
|
||||||
public ulong PlayedSampleCount;
|
public ulong PlayedSampleCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -81,14 +81,14 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static short GetCoefficientAtIndex(ReadOnlySpan<short> coefficients, int index)
|
private static short GetCoefficientAtIndex(ReadOnlySpan<short> coefficients, int index)
|
||||||
{
|
{
|
||||||
if ((uint)index >= (uint)coefficients.Length)
|
if ((uint)index < (uint)coefficients.Length)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.AudioRenderer, $"Out of bound read for coefficient at index {index}");
|
return coefficients[index];
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return coefficients[index];
|
Logger.Error?.Print(LogClass.AudioRenderer, $"Out of bound read for coefficient at index {index}");
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using Ryujinx.Audio.Renderer.Parameter;
|
||||||
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
|
||||||
using Ryujinx.Common.Memory;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
@@ -11,112 +9,6 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
{
|
{
|
||||||
private const int FixedPointPrecisionForParameter = 14;
|
private const int FixedPointPrecisionForParameter = 14;
|
||||||
|
|
||||||
public static BiquadFilterParameter1 ToBiquadFilterParameter1(BiquadFilterParameter2 parameter)
|
|
||||||
{
|
|
||||||
BiquadFilterParameter1 result = new()
|
|
||||||
{
|
|
||||||
Enable = parameter.Enable, Numerator = new Array3<short>(), Denominator = new Array2<short>()
|
|
||||||
};
|
|
||||||
|
|
||||||
Span<short> resultNumeratorSpan = result.Numerator.AsSpan();
|
|
||||||
Span<short> resultDenominatorSpan = result.Denominator.AsSpan();
|
|
||||||
|
|
||||||
Span<float> parameterNumeratorSpan = parameter.Numerator.AsSpan();
|
|
||||||
Span<float> parameterDenominatorSpan = parameter.Denominator.AsSpan();
|
|
||||||
|
|
||||||
|
|
||||||
resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BiquadFilterParameter2 ToBiquadFilterParameter2(BiquadFilterParameter1 parameter)
|
|
||||||
{
|
|
||||||
BiquadFilterParameter2 result = new()
|
|
||||||
{
|
|
||||||
Enable = parameter.Enable, Numerator = new Array3<float>(), Denominator = new Array2<float>()
|
|
||||||
};
|
|
||||||
|
|
||||||
Span<float> resultNumeratorSpan = result.Numerator.AsSpan();
|
|
||||||
Span<float> resultDenominatorSpan = result.Denominator.AsSpan();
|
|
||||||
|
|
||||||
Span<short> parameterNumeratorSpan = parameter.Numerator.AsSpan();
|
|
||||||
Span<short> parameterDenominatorSpan = parameter.Denominator.AsSpan();
|
|
||||||
|
|
||||||
|
|
||||||
resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BiquadFilterEffectParameter1 ToBiquadFilterEffectParameter1(BiquadFilterEffectParameter2 parameter)
|
|
||||||
{
|
|
||||||
BiquadFilterEffectParameter1 result = new()
|
|
||||||
{
|
|
||||||
Input = parameter.Input,
|
|
||||||
Output = parameter.Output,
|
|
||||||
Numerator = new Array3<short>(),
|
|
||||||
Denominator = new Array2<short>(),
|
|
||||||
ChannelCount = parameter.ChannelCount,
|
|
||||||
Status = parameter.Status,
|
|
||||||
};
|
|
||||||
|
|
||||||
Span<short> resultNumeratorSpan = result.Numerator.AsSpan();
|
|
||||||
Span<short> resultDenominatorSpan = result.Denominator.AsSpan();
|
|
||||||
|
|
||||||
Span<float> parameterNumeratorSpan = parameter.Numerator.AsSpan();
|
|
||||||
Span<float> parameterDenominatorSpan = parameter.Denominator.AsSpan();
|
|
||||||
|
|
||||||
|
|
||||||
resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BiquadFilterEffectParameter2 ToBiquadFilterEffectParameter2(BiquadFilterEffectParameter1 parameter)
|
|
||||||
{
|
|
||||||
BiquadFilterEffectParameter2 result = new()
|
|
||||||
{
|
|
||||||
Input = parameter.Input,
|
|
||||||
Output = parameter.Output,
|
|
||||||
Numerator = new Array3<float>(),
|
|
||||||
Denominator = new Array2<float>(),
|
|
||||||
ChannelCount = parameter.ChannelCount,
|
|
||||||
Status = parameter.Status,
|
|
||||||
};
|
|
||||||
|
|
||||||
Span<float> resultNumeratorSpan = result.Numerator.AsSpan();
|
|
||||||
Span<float> resultDenominatorSpan = result.Denominator.AsSpan();
|
|
||||||
|
|
||||||
Span<short> parameterNumeratorSpan = parameter.Numerator.AsSpan();
|
|
||||||
Span<short> parameterDenominatorSpan = parameter.Denominator.AsSpan();
|
|
||||||
|
|
||||||
|
|
||||||
resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
|
|
||||||
resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply a single biquad filter.
|
/// Apply a single biquad filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -128,21 +20,18 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <param name="sampleCount">The count of samples to process</param>
|
/// <param name="sampleCount">The count of samples to process</param>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProcessBiquadFilter(
|
public static void ProcessBiquadFilter(
|
||||||
ref BiquadFilterParameter2 parameter,
|
ref BiquadFilterParameter parameter,
|
||||||
ref BiquadFilterState state,
|
ref BiquadFilterState state,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
ReadOnlySpan<float> inputBuffer,
|
ReadOnlySpan<float> inputBuffer,
|
||||||
uint sampleCount)
|
uint sampleCount)
|
||||||
{
|
{
|
||||||
Span<float> numeratorSpan = parameter.Numerator.AsSpan();
|
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominatorSpan = parameter.Denominator.AsSpan();
|
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
|
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
float a0 = numeratorSpan[0];
|
|
||||||
float a1 = numeratorSpan[1];
|
|
||||||
float a2 = numeratorSpan[2];
|
|
||||||
|
|
||||||
float b1 = denominatorSpan[0];
|
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b2 = denominatorSpan[1];
|
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
for (int i = 0; i < sampleCount; i++)
|
for (int i = 0; i < sampleCount; i++)
|
||||||
{
|
{
|
||||||
@@ -168,22 +57,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <param name="volume">Mix volume</param>
|
/// <param name="volume">Mix volume</param>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProcessBiquadFilterAndMix(
|
public static void ProcessBiquadFilterAndMix(
|
||||||
ref BiquadFilterParameter2 parameter,
|
ref BiquadFilterParameter parameter,
|
||||||
ref BiquadFilterState state,
|
ref BiquadFilterState state,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
ReadOnlySpan<float> inputBuffer,
|
ReadOnlySpan<float> inputBuffer,
|
||||||
uint sampleCount,
|
uint sampleCount,
|
||||||
float volume)
|
float volume)
|
||||||
{
|
{
|
||||||
Span<float> numeratorSpan = parameter.Numerator.AsSpan();
|
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominatorSpan = parameter.Denominator.AsSpan();
|
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
|
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
float a0 = numeratorSpan[0];
|
|
||||||
float a1 = numeratorSpan[1];
|
|
||||||
float a2 = numeratorSpan[2];
|
|
||||||
|
|
||||||
float b1 = denominatorSpan[0];
|
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b2 = denominatorSpan[1];
|
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
for (int i = 0; i < sampleCount; i++)
|
for (int i = 0; i < sampleCount; i++)
|
||||||
{
|
{
|
||||||
@@ -213,7 +99,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <returns>Last filtered sample value</returns>
|
/// <returns>Last filtered sample value</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float ProcessBiquadFilterAndMixRamp(
|
public static float ProcessBiquadFilterAndMixRamp(
|
||||||
ref BiquadFilterParameter2 parameter,
|
ref BiquadFilterParameter parameter,
|
||||||
ref BiquadFilterState state,
|
ref BiquadFilterState state,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
ReadOnlySpan<float> inputBuffer,
|
ReadOnlySpan<float> inputBuffer,
|
||||||
@@ -221,15 +107,12 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
float volume,
|
float volume,
|
||||||
float ramp)
|
float ramp)
|
||||||
{
|
{
|
||||||
Span<float> numeratorSpan = parameter.Numerator.AsSpan();
|
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominatorSpan = parameter.Denominator.AsSpan();
|
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
|
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
float a0 = numeratorSpan[0];
|
|
||||||
float a1 = numeratorSpan[1];
|
|
||||||
float a2 = numeratorSpan[2];
|
|
||||||
|
|
||||||
float b1 = denominatorSpan[0];
|
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b2 = denominatorSpan[1];
|
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float mixState = 0f;
|
float mixState = 0f;
|
||||||
|
|
||||||
@@ -263,7 +146,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <param name="sampleCount">The count of samples to process</param>
|
/// <param name="sampleCount">The count of samples to process</param>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProcessBiquadFilter(
|
public static void ProcessBiquadFilter(
|
||||||
ReadOnlySpan<BiquadFilterParameter2> parameters,
|
ReadOnlySpan<BiquadFilterParameter> parameters,
|
||||||
Span<BiquadFilterState> states,
|
Span<BiquadFilterState> states,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
ReadOnlySpan<float> inputBuffer,
|
ReadOnlySpan<float> inputBuffer,
|
||||||
@@ -271,19 +154,16 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
{
|
{
|
||||||
for (int stageIndex = 0; stageIndex < parameters.Length; stageIndex++)
|
for (int stageIndex = 0; stageIndex < parameters.Length; stageIndex++)
|
||||||
{
|
{
|
||||||
BiquadFilterParameter2 parameter = parameters[stageIndex];
|
BiquadFilterParameter parameter = parameters[stageIndex];
|
||||||
|
|
||||||
ref BiquadFilterState state = ref states[stageIndex];
|
ref BiquadFilterState state = ref states[stageIndex];
|
||||||
|
|
||||||
Span<float> numeratorSpan = parameter.Numerator.AsSpan();
|
|
||||||
Span<float> denominatorSpan = parameter.Denominator.AsSpan();
|
|
||||||
|
|
||||||
float a0 = numeratorSpan[0];
|
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
float a1 = numeratorSpan[1];
|
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
float a2 = numeratorSpan[2];
|
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float b1 = denominatorSpan[0];
|
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b2 = denominatorSpan[1];
|
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
for (int i = 0; i < sampleCount; i++)
|
for (int i = 0; i < sampleCount; i++)
|
||||||
{
|
{
|
||||||
@@ -312,8 +192,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <param name="volume">Mix volume</param>
|
/// <param name="volume">Mix volume</param>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProcessDoubleBiquadFilterAndMix(
|
public static void ProcessDoubleBiquadFilterAndMix(
|
||||||
ref BiquadFilterParameter2 parameter0,
|
ref BiquadFilterParameter parameter0,
|
||||||
ref BiquadFilterParameter2 parameter1,
|
ref BiquadFilterParameter parameter1,
|
||||||
ref BiquadFilterState state0,
|
ref BiquadFilterState state0,
|
||||||
ref BiquadFilterState state1,
|
ref BiquadFilterState state1,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
@@ -321,25 +201,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
uint sampleCount,
|
uint sampleCount,
|
||||||
float volume)
|
float volume)
|
||||||
{
|
{
|
||||||
Span<float> numerator0Span = parameter0.Numerator.AsSpan();
|
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
Span<float> numerator1Span = parameter1.Numerator.AsSpan();
|
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominator0Span = parameter0.Denominator.AsSpan();
|
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominator1Span = parameter1.Denominator.AsSpan();
|
|
||||||
|
|
||||||
|
|
||||||
float a00 = numerator0Span[0];
|
|
||||||
float a10 = numerator0Span[1];
|
|
||||||
float a20 = numerator0Span[2];
|
|
||||||
|
|
||||||
float b10 = denominator0Span[0];
|
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b20 = denominator0Span[1];
|
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float a01 = numerator1Span[0];
|
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
float a11 = numerator1Span[1];
|
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
float a21 = numerator1Span[2];
|
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float b11 = denominator1Span[0];
|
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b21 = denominator1Span[1];
|
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
for (int i = 0; i < sampleCount; i++)
|
for (int i = 0; i < sampleCount; i++)
|
||||||
{
|
{
|
||||||
@@ -377,8 +251,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
/// <returns>Last filtered sample value</returns>
|
/// <returns>Last filtered sample value</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float ProcessDoubleBiquadFilterAndMixRamp(
|
public static float ProcessDoubleBiquadFilterAndMixRamp(
|
||||||
ref BiquadFilterParameter2 parameter0,
|
ref BiquadFilterParameter parameter0,
|
||||||
ref BiquadFilterParameter2 parameter1,
|
ref BiquadFilterParameter parameter1,
|
||||||
ref BiquadFilterState state0,
|
ref BiquadFilterState state0,
|
||||||
ref BiquadFilterState state1,
|
ref BiquadFilterState state1,
|
||||||
Span<float> outputBuffer,
|
Span<float> outputBuffer,
|
||||||
@@ -387,24 +261,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
float volume,
|
float volume,
|
||||||
float ramp)
|
float ramp)
|
||||||
{
|
{
|
||||||
Span<float> numerator0Span = parameter0.Numerator.AsSpan();
|
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
Span<float> numerator1Span = parameter1.Numerator.AsSpan();
|
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominator0Span = parameter0.Denominator.AsSpan();
|
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
Span<float> denominator1Span = parameter1.Denominator.AsSpan();
|
|
||||||
|
|
||||||
float a00 = numerator0Span[0];
|
|
||||||
float a10 = numerator0Span[1];
|
|
||||||
float a20 = numerator0Span[2];
|
|
||||||
|
|
||||||
float b10 = denominator0Span[0];
|
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b20 = denominator0Span[1];
|
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float a01 = numerator1Span[0];
|
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
|
||||||
float a11 = numerator1Span[1];
|
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
|
||||||
float a21 = numerator1Span[2];
|
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float b11 = denominator1Span[0];
|
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
|
||||||
float b21 = denominator1Span[1];
|
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
|
||||||
|
|
||||||
float mixState = 0f;
|
float mixState = 0f;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
using Ryujinx.Audio.Renderer.Common;
|
||||||
using Ryujinx.Audio.Renderer.Server.Voice;
|
using Ryujinx.Audio.Renderer.Server.Voice;
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
@@ -11,55 +11,48 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.AdpcmDataSourceVersion1;
|
public CommandType CommandType => CommandType.AdpcmDataSourceVersion1;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
public uint SampleRate { get; private set; }
|
public uint SampleRate { get; }
|
||||||
|
|
||||||
public float Pitch { get; private set; }
|
public float Pitch { get; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public ulong AdpcmParameter { get; private set; }
|
public ulong AdpcmParameter { get; }
|
||||||
public ulong AdpcmParameterSize { get; private set; }
|
public ulong AdpcmParameterSize { get; }
|
||||||
|
|
||||||
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
public DecodingBehaviour DecodingBehaviour { get; }
|
||||||
|
|
||||||
public AdpcmDataSourceCommandVersion1()
|
public AdpcmDataSourceCommandVersion1(ref VoiceState serverState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, int nodeId)
|
||||||
{
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AdpcmDataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
OutputBufferIndex = outputBufferIndex;
|
OutputBufferIndex = outputBufferIndex;
|
||||||
SampleRate = serverInfo.SampleRate;
|
SampleRate = serverState.SampleRate;
|
||||||
Pitch = serverInfo.Pitch;
|
Pitch = serverState.Pitch;
|
||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
|
||||||
|
|
||||||
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdpcmParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
|
AdpcmParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
|
||||||
AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
|
AdpcmParameterSize = serverState.DataSourceStateAddressInfo.Size;
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverState.DecodingBehaviour;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -12,31 +12,26 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.AuxiliaryBuffer;
|
public CommandType CommandType => CommandType.AuxiliaryBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint InputBufferIndex { get; private set; }
|
public uint InputBufferIndex { get; }
|
||||||
public uint OutputBufferIndex { get; private set; }
|
public uint OutputBufferIndex { get; }
|
||||||
|
|
||||||
public AuxiliaryBufferAddresses BufferInfo { get; private set; }
|
public AuxiliaryBufferAddresses BufferInfo { get; }
|
||||||
|
|
||||||
public CpuAddress InputBuffer { get; private set; }
|
public CpuAddress InputBuffer { get; }
|
||||||
public CpuAddress OutputBuffer { get; private set; }
|
public CpuAddress OutputBuffer { get; }
|
||||||
public uint CountMax { get; private set; }
|
public uint CountMax { get; }
|
||||||
public uint UpdateCount { get; private set; }
|
public uint UpdateCount { get; }
|
||||||
public uint WriteOffset { get; private set; }
|
public uint WriteOffset { get; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
public AuxiliaryBufferCommand()
|
public AuxiliaryBufferCommand(
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuxiliaryBufferCommand Initialize(
|
|
||||||
uint bufferOffset,
|
uint bufferOffset,
|
||||||
byte inputBufferOffset,
|
byte inputBufferOffset,
|
||||||
byte outputBufferOffset,
|
byte outputBufferOffset,
|
||||||
@@ -60,8 +55,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
UpdateCount = updateCount;
|
UpdateCount = updateCount;
|
||||||
WriteOffset = writeOffset;
|
WriteOffset = writeOffset;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -9,44 +9,39 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.BiquadFilterAndMix;
|
public CommandType CommandType => CommandType.BiquadFilterAndMix;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
private BiquadFilterParameter2 _parameter;
|
private BiquadFilterParameter _parameter;
|
||||||
|
|
||||||
public Memory<BiquadFilterState> BiquadFilterState { get; private set; }
|
public Memory<BiquadFilterState> BiquadFilterState { get; }
|
||||||
public Memory<BiquadFilterState> PreviousBiquadFilterState { get; private set; }
|
public Memory<BiquadFilterState> PreviousBiquadFilterState { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public int LastSampleIndex { get; private set; }
|
public int LastSampleIndex { get; }
|
||||||
|
|
||||||
public float Volume0 { get; private set; }
|
public float Volume0 { get; }
|
||||||
public float Volume1 { get; private set; }
|
public float Volume1 { get; }
|
||||||
|
|
||||||
public bool NeedInitialization { get; private set; }
|
public bool NeedInitialization { get; }
|
||||||
public bool HasVolumeRamp { get; private set; }
|
public bool HasVolumeRamp { get; }
|
||||||
public bool IsFirstMixBuffer { get; private set; }
|
public bool IsFirstMixBuffer { get; }
|
||||||
|
|
||||||
public BiquadFilterAndMixCommand()
|
public BiquadFilterAndMixCommand(
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiquadFilterAndMixCommand Initialize(
|
|
||||||
float volume0,
|
float volume0,
|
||||||
float volume1,
|
float volume1,
|
||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
uint outputBufferIndex,
|
uint outputBufferIndex,
|
||||||
int lastSampleIndex,
|
int lastSampleIndex,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
ref BiquadFilterParameter2 filter,
|
ref BiquadFilterParameter filter,
|
||||||
Memory<BiquadFilterState> biquadFilterState,
|
Memory<BiquadFilterState> biquadFilterState,
|
||||||
Memory<BiquadFilterState> previousBiquadFilterState,
|
Memory<BiquadFilterState> previousBiquadFilterState,
|
||||||
bool needInitialization,
|
bool needInitialization,
|
||||||
@@ -73,8 +68,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
NeedInitialization = needInitialization;
|
NeedInitialization = needInitialization;
|
||||||
HasVolumeRamp = hasVolumeRamp;
|
HasVolumeRamp = hasVolumeRamp;
|
||||||
IsFirstMixBuffer = isFirstMixBuffer;
|
IsFirstMixBuffer = isFirstMixBuffer;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -8,27 +8,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.BiquadFilter;
|
public CommandType CommandType => CommandType.BiquadFilter;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public Memory<BiquadFilterState> BiquadFilterState { get; private set; }
|
public Memory<BiquadFilterState> BiquadFilterState { get; }
|
||||||
public int InputBufferIndex { get; private set; }
|
public int InputBufferIndex { get; }
|
||||||
public int OutputBufferIndex { get; private set; }
|
public int OutputBufferIndex { get; }
|
||||||
public bool NeedInitialization { get; private set; }
|
public bool NeedInitialization { get; }
|
||||||
|
|
||||||
private BiquadFilterParameter2 _parameter;
|
private BiquadFilterParameter _parameter;
|
||||||
|
|
||||||
public BiquadFilterCommand()
|
public BiquadFilterCommand(
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiquadFilterCommand Initialize(
|
|
||||||
int baseIndex,
|
int baseIndex,
|
||||||
ref BiquadFilterParameter2 filter,
|
ref BiquadFilterParameter filter,
|
||||||
Memory<BiquadFilterState> biquadFilterStateMemory,
|
Memory<BiquadFilterState> biquadFilterStateMemory,
|
||||||
int inputBufferOffset,
|
int inputBufferOffset,
|
||||||
int outputBufferOffset,
|
int outputBufferOffset,
|
||||||
@@ -43,8 +38,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -12,30 +12,25 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CaptureBuffer;
|
public CommandType CommandType => CommandType.CaptureBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint InputBufferIndex { get; private set; }
|
public uint InputBufferIndex { get; }
|
||||||
|
|
||||||
public ulong CpuBufferInfoAddress { get; private set; }
|
public ulong CpuBufferInfoAddress { get; }
|
||||||
public ulong DspBufferInfoAddress { get; private set; }
|
public ulong DspBufferInfoAddress { get; }
|
||||||
|
|
||||||
public CpuAddress OutputBuffer { get; private set; }
|
public CpuAddress OutputBuffer { get; }
|
||||||
public uint CountMax { get; private set; }
|
public uint CountMax { get; }
|
||||||
public uint UpdateCount { get; private set; }
|
public uint UpdateCount { get; }
|
||||||
public uint WriteOffset { get; private set; }
|
public uint WriteOffset { get; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
public CaptureBufferCommand()
|
public CaptureBufferCommand(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled,
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public CaptureBufferCommand Initialize(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled,
|
|
||||||
uint countMax, CpuAddress outputBuffer, uint updateCount, uint writeOffset, int nodeId)
|
uint countMax, CpuAddress outputBuffer, uint updateCount, uint writeOffset, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
@@ -48,8 +43,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
UpdateCount = updateCount;
|
UpdateCount = updateCount;
|
||||||
WriteOffset = writeOffset;
|
WriteOffset = writeOffset;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Audio.Renderer.Parameter.Sink;
|
using Ryujinx.Audio.Renderer.Parameter.Sink;
|
||||||
using Ryujinx.Audio.Renderer.Server.MemoryPool;
|
using Ryujinx.Audio.Renderer.Server.MemoryPool;
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
@@ -9,36 +8,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CircularBufferSink;
|
public CommandType CommandType => CommandType.CircularBufferSink;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort[] Input { get; }
|
public ushort[] Input { get; }
|
||||||
public uint InputCount { get; private set; }
|
public uint InputCount { get; }
|
||||||
|
|
||||||
public ulong CircularBuffer { get; private set; }
|
public ulong CircularBuffer { get; }
|
||||||
public ulong CircularBufferSize { get; private set; }
|
public ulong CircularBufferSize { get; }
|
||||||
public ulong CurrentOffset { get; private set; }
|
public ulong CurrentOffset { get; }
|
||||||
|
|
||||||
public CircularBufferSinkCommand()
|
public CircularBufferSinkCommand(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId)
|
||||||
{
|
|
||||||
Input = new ushort[Constants.ChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public CircularBufferSinkCommand Initialize(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
|
Input = new ushort[Constants.ChannelCountMax];
|
||||||
InputCount = parameter.InputCount;
|
InputCount = parameter.InputCount;
|
||||||
|
|
||||||
Span<byte> inputSpan = parameter.Input.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < InputCount; i++)
|
for (int i = 0; i < InputCount; i++)
|
||||||
{
|
{
|
||||||
Input[i] = (ushort)(bufferOffset + inputSpan[i]);
|
Input[i] = (ushort)(bufferOffset + parameter.Input[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
CircularBuffer = circularBufferAddressInfo.GetReference(true);
|
CircularBuffer = circularBufferAddressInfo.GetReference(true);
|
||||||
@@ -46,8 +39,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
CurrentOffset = currentOffset;
|
CurrentOffset = currentOffset;
|
||||||
|
|
||||||
Debug.Assert(CircularBuffer != 0);
|
Debug.Assert(CircularBuffer != 0);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -4,23 +4,16 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.ClearMixBuffer;
|
public CommandType CommandType => CommandType.ClearMixBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ClearMixBufferCommand()
|
public ClearMixBufferCommand(int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClearMixBufferCommand Initialize(int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
public Memory<float> Buffers { get; }
|
public Memory<float> Buffers { get; }
|
||||||
public uint BufferCount { get; }
|
public uint BufferCount { get; }
|
||||||
|
|
||||||
private readonly static ObjectPool<List<ICommand>> CommandsListPool = new(() => new List<ICommand>(256));
|
|
||||||
public List<ICommand> Commands { get; }
|
public List<ICommand> Commands { get; }
|
||||||
|
|
||||||
public IVirtualMemoryManager MemoryManager { get; }
|
public IVirtualMemoryManager MemoryManager { get; }
|
||||||
@@ -47,7 +46,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
SampleRate = sampleRate;
|
SampleRate = sampleRate;
|
||||||
BufferCount = mixBufferCount + voiceChannelCountMax;
|
BufferCount = mixBufferCount + voiceChannelCountMax;
|
||||||
Buffers = mixBuffer;
|
Buffers = mixBuffer;
|
||||||
Commands = CommandsListPool.Allocate();
|
Commands = [];
|
||||||
MemoryManager = memoryManager;
|
MemoryManager = memoryManager;
|
||||||
|
|
||||||
_buffersEntryCount = Buffers.Length;
|
_buffersEntryCount = Buffers.Length;
|
||||||
@@ -130,7 +129,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
startTime = PerformanceCounter.ElapsedNanoseconds;
|
startTime = PerformanceCounter.ElapsedNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
command.Process(this);
|
command.Process(this);
|
||||||
|
|
||||||
if (shouldMeter)
|
if (shouldMeter)
|
||||||
@@ -143,8 +142,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuffer.ReleaseCommand(command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EndTime = (ulong)PerformanceCounter.ElapsedNanoseconds;
|
EndTime = (ulong)PerformanceCounter.ElapsedNanoseconds;
|
||||||
@@ -152,8 +149,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Commands.Clear();
|
|
||||||
CommandsListPool.Release(Commands);
|
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
_buffersMemoryHandle.Dispose();
|
_buffersMemoryHandle.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
Volume,
|
Volume,
|
||||||
VolumeRamp,
|
VolumeRamp,
|
||||||
BiquadFilter,
|
BiquadFilter,
|
||||||
BiquadFilterFloatCoeff, // new
|
|
||||||
Mix,
|
Mix,
|
||||||
MixRamp,
|
MixRamp,
|
||||||
MixRampGrouped,
|
MixRampGrouped,
|
||||||
@@ -32,17 +31,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
LimiterVersion1,
|
LimiterVersion1,
|
||||||
LimiterVersion2,
|
LimiterVersion2,
|
||||||
MultiTapBiquadFilter,
|
MultiTapBiquadFilter,
|
||||||
MultiTapBiquadFilterFloatCoeff, // new
|
|
||||||
CaptureBuffer,
|
CaptureBuffer,
|
||||||
Compressor,
|
Compressor,
|
||||||
BiquadFilterAndMix,
|
BiquadFilterAndMix,
|
||||||
BiquadFilterAndMixFloatCoeff, // new
|
|
||||||
MultiTapBiquadFilterAndMix,
|
MultiTapBiquadFilterAndMix,
|
||||||
MultiTapBiquadFilterAndMixFloatCoef, // new
|
|
||||||
AuxiliaryBufferGrouped, // new
|
|
||||||
FillMixBuffer, // new
|
|
||||||
BiquadFilterCrossFade, // new
|
|
||||||
MultiTapBiquadFilterCrossFade, // new
|
|
||||||
FillBuffer, // new
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,28 +15,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Compressor;
|
public CommandType CommandType => CommandType.Compressor;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public CompressorParameter Parameter => _parameter;
|
public CompressorParameter Parameter => _parameter;
|
||||||
public Memory<CompressorState> State { get; private set; }
|
public Memory<CompressorState> State { get; }
|
||||||
public Memory<EffectResultState> ResultState { get; private set; }
|
public Memory<EffectResultState> ResultState { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private CompressorParameter _parameter;
|
private CompressorParameter _parameter;
|
||||||
|
|
||||||
public CompressorCommand()
|
public CompressorCommand(uint bufferOffset, CompressorParameter parameter, Memory<CompressorState> state, Memory<EffectResultState> resultState, bool isEnabled, int nodeId)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompressorCommand Initialize(uint bufferOffset, CompressorParameter parameter, Memory<CompressorState> state, Memory<EffectResultState> resultState, bool isEnabled, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -45,17 +39,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
ResultState = resultState;
|
ResultState = resultState;
|
||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
Span<byte> inputSpan = _parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = _parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < _parameter.ChannelCount; i++)
|
for (int i = 0; i < _parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
@@ -179,12 +171,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain);
|
statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain);
|
||||||
statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean);
|
statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean);
|
||||||
|
|
||||||
Span<float> lastSamplesSpan = statistics.LastSamples.AsSpan();
|
|
||||||
|
|
||||||
for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++)
|
for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++)
|
||||||
{
|
{
|
||||||
lastSamplesSpan[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
|
statistics.LastSamples[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,29 +4,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CopyMixBuffer;
|
public CommandType CommandType => CommandType.CopyMixBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public CopyMixBufferCommand()
|
public CopyMixBufferCommand(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyMixBufferCommand Initialize(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
InputBufferIndex = (ushort)inputBufferIndex;
|
InputBufferIndex = (ushort)inputBufferIndex;
|
||||||
OutputBufferIndex = (ushort)outputBufferIndex;
|
OutputBufferIndex = (ushort)outputBufferIndex;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
using Ryujinx.Audio.Renderer.Common;
|
||||||
using Ryujinx.Audio.Renderer.Server.Voice;
|
using Ryujinx.Audio.Renderer.Server.Voice;
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
@@ -11,72 +11,65 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType { get; private set; }
|
public CommandType CommandType { get; }
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
public uint SampleRate { get; private set; }
|
public uint SampleRate { get; }
|
||||||
|
|
||||||
public float Pitch { get; private set; }
|
public float Pitch { get; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public ulong ExtraParameter { get; private set; }
|
public ulong ExtraParameter { get; }
|
||||||
public ulong ExtraParameterSize { get; private set; }
|
public ulong ExtraParameterSize { get; }
|
||||||
|
|
||||||
public uint ChannelIndex { get; private set; }
|
public uint ChannelIndex { get; }
|
||||||
|
|
||||||
public uint ChannelCount { get; private set; }
|
public uint ChannelCount { get; }
|
||||||
|
|
||||||
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
public DecodingBehaviour DecodingBehaviour { get; }
|
||||||
|
|
||||||
public SampleFormat SampleFormat { get; private set; }
|
public SampleFormat SampleFormat { get; }
|
||||||
|
|
||||||
public SampleRateConversionQuality SrcQuality { get; private set; }
|
public SampleRateConversionQuality SrcQuality { get; }
|
||||||
|
|
||||||
public DataSourceVersion2Command()
|
public DataSourceVersion2Command(ref VoiceState serverState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataSourceVersion2Command Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
ChannelIndex = channelIndex;
|
ChannelIndex = channelIndex;
|
||||||
ChannelCount = serverInfo.ChannelsCount;
|
ChannelCount = serverState.ChannelsCount;
|
||||||
SampleFormat = serverInfo.SampleFormat;
|
SampleFormat = serverState.SampleFormat;
|
||||||
SrcQuality = serverInfo.SrcQuality;
|
SrcQuality = serverState.SrcQuality;
|
||||||
CommandType = GetCommandTypeBySampleFormat(SampleFormat);
|
CommandType = GetCommandTypeBySampleFormat(SampleFormat);
|
||||||
|
|
||||||
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
||||||
SampleRate = serverInfo.SampleRate;
|
SampleRate = serverState.SampleRate;
|
||||||
Pitch = serverInfo.Pitch;
|
Pitch = serverState.Pitch;
|
||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
|
||||||
|
|
||||||
WaveBuffers[i] = voiceWaveBuffer.ToCommon(2);
|
WaveBuffers[i] = voiceWaveBuffer.ToCommon(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SampleFormat == SampleFormat.Adpcm)
|
if (SampleFormat == SampleFormat.Adpcm)
|
||||||
{
|
{
|
||||||
ExtraParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
|
ExtraParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
|
||||||
ExtraParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
|
ExtraParameterSize = serverState.DataSourceStateAddressInfo.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverState.DecodingBehaviour;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
|
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
|
||||||
|
|||||||
@@ -13,30 +13,24 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Delay;
|
public CommandType CommandType => CommandType.Delay;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public DelayParameter Parameter => _parameter;
|
public DelayParameter Parameter => _parameter;
|
||||||
public Memory<DelayState> State { get; private set; }
|
public Memory<DelayState> State { get; }
|
||||||
public ulong WorkBuffer { get; private set; }
|
public ulong WorkBuffer { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private DelayParameter _parameter;
|
private DelayParameter _parameter;
|
||||||
|
|
||||||
private const int FixedPointPrecision = 14;
|
private const int FixedPointPrecision = 14;
|
||||||
|
|
||||||
public DelayCommand()
|
public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DelayCommand Initialize(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -45,20 +39,18 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
WorkBuffer = workBuffer;
|
WorkBuffer = workBuffer;
|
||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
Span<byte> inputSpan = Parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = Parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < Parameter.ChannelCount; i++)
|
for (int i = 0; i < Parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
||||||
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
|||||||
@@ -7,26 +7,21 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.DepopForMixBuffers;
|
public CommandType CommandType => CommandType.DepopForMixBuffers;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint MixBufferOffset { get; private set; }
|
public uint MixBufferOffset { get; }
|
||||||
|
|
||||||
public uint MixBufferCount { get; private set; }
|
public uint MixBufferCount { get; }
|
||||||
|
|
||||||
public float Decay { get; private set; }
|
public float Decay { get; }
|
||||||
|
|
||||||
public Memory<float> DepopBuffer { get; private set; }
|
public Memory<float> DepopBuffer { get; }
|
||||||
|
|
||||||
public DepopForMixBuffersCommand()
|
public DepopForMixBuffersCommand(Memory<float> depopBuffer, uint bufferOffset, uint mixBufferCount, int nodeId, uint sampleRate)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepopForMixBuffersCommand Initialize(Memory<float> depopBuffer, uint bufferOffset, uint mixBufferCount, int nodeId, uint sampleRate)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -42,8 +37,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
Decay = 0.943695f;
|
Decay = 0.943695f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -7,30 +7,27 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.DepopPrepare;
|
public CommandType CommandType => CommandType.DepopPrepare;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint MixBufferCount { get; private set; }
|
public uint MixBufferCount { get; }
|
||||||
|
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
public Memory<float> DepopBuffer { get; private set; }
|
public Memory<float> DepopBuffer { get; }
|
||||||
|
|
||||||
public DepopPrepareCommand()
|
public DepopPrepareCommand(Memory<VoiceUpdateState> state, Memory<float> depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
|
||||||
{
|
|
||||||
OutputBufferIndices = new ushort[Constants.MixBufferCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepopPrepareCommand Initialize(Memory<VoiceState> state, Memory<float> depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
|
|
||||||
{
|
{
|
||||||
Enabled = enabled;
|
Enabled = enabled;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
MixBufferCount = mixBufferCount;
|
MixBufferCount = mixBufferCount;
|
||||||
|
|
||||||
|
OutputBufferIndices = new ushort[Constants.MixBufferCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < Constants.MixBufferCountMax; i++)
|
for (int i = 0; i < Constants.MixBufferCountMax; i++)
|
||||||
{
|
{
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + i);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + i);
|
||||||
@@ -38,24 +35,21 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
DepopBuffer = depopBuffer;
|
DepopBuffer = depopBuffer;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
{
|
{
|
||||||
ref VoiceState state = ref State.Span[0];
|
ref VoiceUpdateState state = ref State.Span[0];
|
||||||
|
|
||||||
Span<float> depopBuffer = DepopBuffer.Span;
|
Span<float> depopBuffer = DepopBuffer.Span;
|
||||||
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < MixBufferCount; i++)
|
for (int i = 0; i < MixBufferCount; i++)
|
||||||
{
|
{
|
||||||
if (lastSamplesSpan[i] != 0)
|
if (state.LastSamples[i] != 0)
|
||||||
{
|
{
|
||||||
depopBuffer[OutputBufferIndices[i]] += lastSamplesSpan[i];
|
depopBuffer[OutputBufferIndices[i]] += state.LastSamples[i];
|
||||||
|
|
||||||
lastSamplesSpan[i] = 0;
|
state.LastSamples[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Audio.Integration;
|
using Ryujinx.Audio.Integration;
|
||||||
using Ryujinx.Audio.Renderer.Server.Sink;
|
using Ryujinx.Audio.Renderer.Server.Sink;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -11,55 +10,44 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.DeviceSink;
|
public CommandType CommandType => CommandType.DeviceSink;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public string DeviceName { get; private set; }
|
public string DeviceName { get; }
|
||||||
|
|
||||||
public int SessionId { get; private set; }
|
public int SessionId { get; }
|
||||||
|
|
||||||
public uint InputCount { get; private set; }
|
public uint InputCount { get; }
|
||||||
public ushort[] InputBufferIndices { get; private set; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
|
|
||||||
public Memory<float> Buffers { get; private set; }
|
public Memory<float> Buffers { get; }
|
||||||
|
|
||||||
public DeviceSinkCommand()
|
public DeviceSinkCommand(uint bufferOffset, DeviceSink sink, int sessionId, Memory<float> buffers, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeviceSinkCommand Initialize(uint bufferOffset, DeviceSink sink, int sessionId, Memory<float> buffers, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
// Unused and wasting time and memory, re-add if needed
|
DeviceName = Encoding.ASCII.GetString(sink.Parameter.DeviceName).TrimEnd('\0');
|
||||||
// DeviceName = Encoding.ASCII.GetString(sink.Parameter.DeviceName).TrimEnd('\0');
|
|
||||||
|
|
||||||
SessionId = sessionId;
|
SessionId = sessionId;
|
||||||
InputCount = sink.Parameter.InputCount;
|
InputCount = sink.Parameter.InputCount;
|
||||||
InputBufferIndices = new ushort[InputCount];
|
InputBufferIndices = new ushort[InputCount];
|
||||||
|
|
||||||
Span<byte> inputSpan = sink.Parameter.Input.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < Math.Min(InputCount, Constants.ChannelCountMax); i++)
|
for (int i = 0; i < Math.Min(InputCount, Constants.ChannelCountMax); i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + sink.Parameter.Input[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink.UpsamplerInfo != null)
|
if (sink.UpsamplerState != null)
|
||||||
{
|
{
|
||||||
Buffers = sink.UpsamplerInfo.OutputBuffer;
|
Buffers = sink.UpsamplerState.OutputBuffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Buffers = buffers;
|
Buffers = buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -91,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
inputCount = bufferCount;
|
inputCount = bufferCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] outputBuffer = ArrayPool<short>.Shared.Rent((int)inputCount * SampleCount);
|
short[] outputBuffer = new short[inputCount * SampleCount];
|
||||||
|
|
||||||
for (int i = 0; i < bufferCount; i++)
|
for (int i = 0; i < bufferCount; i++)
|
||||||
{
|
{
|
||||||
@@ -103,9 +91,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device.AppendBuffer(outputBuffer.AsSpan(..((int)inputCount * SampleCount)), inputCount);
|
device.AppendBuffer(outputBuffer, inputCount);
|
||||||
|
|
||||||
ArrayPool<short>.Shared.Return(outputBuffer);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.DownMixSurroundToStereo;
|
public CommandType CommandType => CommandType.DownMixSurroundToStereo;
|
||||||
|
|
||||||
@@ -16,19 +16,16 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
|
|
||||||
public float[] Coefficients { get; private set; }
|
public float[] Coefficients { get; }
|
||||||
|
|
||||||
public DownMixSurroundToStereoCommand()
|
public DownMixSurroundToStereoCommand(uint bufferOffset, Span<byte> inputBufferOffset, Span<byte> outputBufferOffset, float[] downMixParameter, int nodeId)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownMixSurroundToStereoCommand Initialize(uint bufferOffset, Span<byte> inputBufferOffset, Span<byte> outputBufferOffset, float[] downMixParameter, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < Constants.VoiceChannelCountMax; i++)
|
for (int i = 0; i < Constants.VoiceChannelCountMax; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputBufferOffset[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + inputBufferOffset[i]);
|
||||||
@@ -36,8 +33,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
Coefficients = downMixParameter;
|
Coefficients = downMixParameter;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
using Ryujinx.Audio.Renderer.Server.Splitter;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|
||||||
{
|
|
||||||
public class FillBufferCommand : ICommand
|
|
||||||
{
|
|
||||||
public bool Enabled { get; set; }
|
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.FillBuffer;
|
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
|
||||||
|
|
||||||
public SplitterDestinationVersion1 Destination1 { get; private set; }
|
|
||||||
public SplitterDestinationVersion2 Destination2 { get; private set; }
|
|
||||||
public bool IsV2 { get; private set; }
|
|
||||||
public int Length { get; private set; }
|
|
||||||
public float Value { get; private set; }
|
|
||||||
|
|
||||||
public FillBufferCommand()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public FillBufferCommand Initialize(SplitterDestination destination, int length, float value, int nodeId)
|
|
||||||
{
|
|
||||||
Enabled = true;
|
|
||||||
NodeId = nodeId;
|
|
||||||
|
|
||||||
if (Unsafe.IsNullRef(ref destination.GetV2RefOrNull()))
|
|
||||||
{
|
|
||||||
Destination1 = destination.GetV1RefOrNull();
|
|
||||||
IsV2 = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Destination2 = destination.GetV2RefOrNull();
|
|
||||||
IsV2 = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Length = length;
|
|
||||||
Value = value;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ProcessFillBuffer()
|
|
||||||
{
|
|
||||||
if (IsV2)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Length; i++)
|
|
||||||
{
|
|
||||||
Destination2.PreviousMixBufferVolume[i] = Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Length; i++)
|
|
||||||
{
|
|
||||||
Destination1.PreviousMixBufferVolume[i] = Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Process(CommandList context)
|
|
||||||
{
|
|
||||||
ProcessFillBuffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,28 +10,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.LimiterVersion1;
|
public CommandType CommandType => CommandType.LimiterVersion1;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public LimiterParameter Parameter => _parameter;
|
public LimiterParameter Parameter => _parameter;
|
||||||
public Memory<LimiterState> State { get; private set; }
|
public Memory<LimiterState> State { get; }
|
||||||
public ulong WorkBuffer { get; private set; }
|
public ulong WorkBuffer { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private LimiterParameter _parameter;
|
private LimiterParameter _parameter;
|
||||||
|
|
||||||
public LimiterCommandVersion1()
|
public LimiterCommandVersion1(uint bufferOffset, LimiterParameter parameter, Memory<LimiterState> state, bool isEnabled, ulong workBuffer, int nodeId)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public LimiterCommandVersion1 Initialize(uint bufferOffset, LimiterParameter parameter, Memory<LimiterState> state, bool isEnabled, ulong workBuffer, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -41,16 +35,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
Span<byte> inputSpan = _parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = _parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < _parameter.ChannelCount; i++)
|
for (int i = 0; i < _parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -12,29 +12,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.LimiterVersion2;
|
public CommandType CommandType => CommandType.LimiterVersion2;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public LimiterParameter Parameter => _parameter;
|
public LimiterParameter Parameter => _parameter;
|
||||||
public Memory<LimiterState> State { get; private set; }
|
public Memory<LimiterState> State { get; }
|
||||||
public Memory<EffectResultState> ResultState { get; private set; }
|
public Memory<EffectResultState> ResultState { get; }
|
||||||
public ulong WorkBuffer { get; private set; }
|
public ulong WorkBuffer { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private LimiterParameter _parameter;
|
private LimiterParameter _parameter;
|
||||||
|
|
||||||
public LimiterCommandVersion2()
|
public LimiterCommandVersion2(
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public LimiterCommandVersion2 Initialize(
|
|
||||||
uint bufferOffset,
|
uint bufferOffset,
|
||||||
LimiterParameter parameter,
|
LimiterParameter parameter,
|
||||||
Memory<LimiterState> state,
|
Memory<LimiterState> state,
|
||||||
@@ -51,17 +45,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
WorkBuffer = workBuffer;
|
WorkBuffer = workBuffer;
|
||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
Span<byte> inputSpan = _parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = _parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < _parameter.ChannelCount; i++)
|
for (int i = 0; i < _parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
@@ -158,11 +150,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
ref LimiterStatistics statistics = ref MemoryMarshal.Cast<byte, LimiterStatistics>(ResultState.Span[0].SpecificData)[0];
|
ref LimiterStatistics statistics = ref MemoryMarshal.Cast<byte, LimiterStatistics>(ResultState.Span[0].SpecificData)[0];
|
||||||
|
|
||||||
Span<float> inputMaxSpan = statistics.InputMax.AsSpan();
|
statistics.InputMax[channelIndex] = Math.Max(statistics.InputMax[channelIndex], sampleInputMax);
|
||||||
Span<float> compressionGainMinSpan = statistics.CompressionGainMin.AsSpan();
|
statistics.CompressionGainMin[channelIndex] = Math.Min(statistics.CompressionGainMin[channelIndex], compressionGain);
|
||||||
|
|
||||||
inputMaxSpan[channelIndex] = Math.Max(inputMaxSpan[channelIndex], sampleInputMax);
|
|
||||||
compressionGainMinSpan[channelIndex] = Math.Min(compressionGainMinSpan[channelIndex], compressionGain);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,23 +11,18 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Mix;
|
public CommandType CommandType => CommandType.Mix;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public float Volume { get; private set; }
|
public float Volume { get; }
|
||||||
|
|
||||||
public MixCommand()
|
public MixCommand(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public MixCommand Initialize(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -36,8 +31,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
OutputBufferIndex = (ushort)outputBufferIndex;
|
OutputBufferIndex = (ushort)outputBufferIndex;
|
||||||
|
|
||||||
Volume = volume;
|
Volume = volume;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -8,28 +8,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.MixRamp;
|
public CommandType CommandType => CommandType.MixRamp;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public float Volume0 { get; private set; }
|
public float Volume0 { get; }
|
||||||
public float Volume1 { get; private set; }
|
public float Volume1 { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public int LastSampleIndex { get; private set; }
|
public int LastSampleIndex { get; }
|
||||||
|
|
||||||
public MixRampCommand()
|
public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory<VoiceUpdateState> state, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public MixRampCommand Initialize(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory<VoiceState> state, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -42,8 +37,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
LastSampleIndex = lastSampleIndex;
|
LastSampleIndex = lastSampleIndex;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -8,34 +8,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.MixRampGrouped;
|
public CommandType CommandType => CommandType.MixRampGrouped;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint MixBufferCount { get; private set; }
|
public uint MixBufferCount { get; }
|
||||||
|
|
||||||
public ushort[] InputBufferIndices { get; private set; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public ushort[] OutputBufferIndices { get; private set; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
|
|
||||||
public float[] Volume0 { get; private set; }
|
public float[] Volume0 { get; }
|
||||||
public float[] Volume1 { get; private set; }
|
public float[] Volume1 { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public MixRampGroupedCommand()
|
public MixRampGroupedCommand(
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public MixRampGroupedCommand Initialize(
|
|
||||||
uint mixBufferCount,
|
uint mixBufferCount,
|
||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
uint outputBufferIndex,
|
uint outputBufferIndex,
|
||||||
ReadOnlySpan<float> volume0,
|
ReadOnlySpan<float> volume0,
|
||||||
ReadOnlySpan<float> volume1,
|
ReadOnlySpan<float> volume1,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
int nodeId)
|
int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
@@ -57,8 +52,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -86,10 +79,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
{
|
{
|
||||||
ref VoiceState state = ref State.Span[0];
|
|
||||||
|
|
||||||
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < MixBufferCount; i++)
|
for (int i = 0; i < MixBufferCount; i++)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<float> inputBuffer = context.GetBuffer(InputBufferIndices[i]);
|
ReadOnlySpan<float> inputBuffer = context.GetBuffer(InputBufferIndices[i]);
|
||||||
@@ -98,13 +87,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
float volume0 = Volume0[i];
|
float volume0 = Volume0[i];
|
||||||
float volume1 = Volume1[i];
|
float volume1 = Volume1[i];
|
||||||
|
|
||||||
|
ref VoiceUpdateState state = ref State.Span[0];
|
||||||
|
|
||||||
if (volume0 != 0 || volume1 != 0)
|
if (volume0 != 0 || volume1 != 0)
|
||||||
{
|
{
|
||||||
lastSamplesSpan[i] = ProcessMixRampGrouped(outputBuffer, inputBuffer, volume0, volume1, (int)context.SampleCount);
|
state.LastSamples[i] = ProcessMixRampGrouped(outputBuffer, inputBuffer, volume0, volume1, (int)context.SampleCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lastSamplesSpan[i] = 0;
|
state.LastSamples[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,49 +9,44 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.MultiTapBiquadFilterAndMix;
|
public CommandType CommandType => CommandType.MultiTapBiquadFilterAndMix;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
private BiquadFilterParameter2 _parameter0;
|
private BiquadFilterParameter _parameter0;
|
||||||
private BiquadFilterParameter2 _parameter1;
|
private BiquadFilterParameter _parameter1;
|
||||||
|
|
||||||
public Memory<BiquadFilterState> BiquadFilterState0 { get; private set; }
|
public Memory<BiquadFilterState> BiquadFilterState0 { get; }
|
||||||
public Memory<BiquadFilterState> BiquadFilterState1 { get; private set; }
|
public Memory<BiquadFilterState> BiquadFilterState1 { get; }
|
||||||
public Memory<BiquadFilterState> PreviousBiquadFilterState0 { get; private set; }
|
public Memory<BiquadFilterState> PreviousBiquadFilterState0 { get; }
|
||||||
public Memory<BiquadFilterState> PreviousBiquadFilterState1 { get; private set; }
|
public Memory<BiquadFilterState> PreviousBiquadFilterState1 { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
|
|
||||||
public int LastSampleIndex { get; private set; }
|
public int LastSampleIndex { get; }
|
||||||
|
|
||||||
public float Volume0 { get; private set; }
|
public float Volume0 { get; }
|
||||||
public float Volume1 { get; private set; }
|
public float Volume1 { get; }
|
||||||
|
|
||||||
public bool NeedInitialization0 { get; private set; }
|
public bool NeedInitialization0 { get; }
|
||||||
public bool NeedInitialization1 { get; private set; }
|
public bool NeedInitialization1 { get; }
|
||||||
public bool HasVolumeRamp { get; private set; }
|
public bool HasVolumeRamp { get; }
|
||||||
public bool IsFirstMixBuffer { get; private set; }
|
public bool IsFirstMixBuffer { get; }
|
||||||
|
|
||||||
public MultiTapBiquadFilterAndMixCommand()
|
public MultiTapBiquadFilterAndMixCommand(
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultiTapBiquadFilterAndMixCommand Initialize(
|
|
||||||
float volume0,
|
float volume0,
|
||||||
float volume1,
|
float volume1,
|
||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
uint outputBufferIndex,
|
uint outputBufferIndex,
|
||||||
int lastSampleIndex,
|
int lastSampleIndex,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
ref BiquadFilterParameter2 filter0,
|
ref BiquadFilterParameter filter0,
|
||||||
ref BiquadFilterParameter2 filter1,
|
ref BiquadFilterParameter filter1,
|
||||||
Memory<BiquadFilterState> biquadFilterState0,
|
Memory<BiquadFilterState> biquadFilterState0,
|
||||||
Memory<BiquadFilterState> biquadFilterState1,
|
Memory<BiquadFilterState> biquadFilterState1,
|
||||||
Memory<BiquadFilterState> previousBiquadFilterState0,
|
Memory<BiquadFilterState> previousBiquadFilterState0,
|
||||||
@@ -85,8 +80,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
NeedInitialization1 = needInitialization1;
|
NeedInitialization1 = needInitialization1;
|
||||||
HasVolumeRamp = hasVolumeRamp;
|
HasVolumeRamp = hasVolumeRamp;
|
||||||
IsFirstMixBuffer = isFirstMixBuffer;
|
IsFirstMixBuffer = isFirstMixBuffer;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateState(Memory<BiquadFilterState> state, Memory<BiquadFilterState> previousState, bool needInitialization)
|
private void UpdateState(Memory<BiquadFilterState> state, Memory<BiquadFilterState> previousState, bool needInitialization)
|
||||||
|
|||||||
@@ -8,47 +8,40 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.MultiTapBiquadFilter;
|
public CommandType CommandType => CommandType.MultiTapBiquadFilter;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public BiquadFilterParameter2[] Parameters { get; private set; }
|
private readonly BiquadFilterParameter[] _parameters;
|
||||||
public Memory<BiquadFilterState> BiquadFilterStates { get; private set; }
|
private readonly Memory<BiquadFilterState> _biquadFilterStates;
|
||||||
public int InputBufferIndex { get; private set; }
|
private readonly int _inputBufferIndex;
|
||||||
public int OutputBufferIndex { get; private set; }
|
private readonly int _outputBufferIndex;
|
||||||
public bool[] IsInitialized { get; private set; }
|
private readonly bool[] _isInitialized;
|
||||||
|
|
||||||
public MultiTapBiquadFilterCommand()
|
public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan<BiquadFilterParameter> filters, Memory<BiquadFilterState> biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan<bool> isInitialized, int nodeId)
|
||||||
{
|
{
|
||||||
|
_parameters = filters.ToArray();
|
||||||
}
|
_biquadFilterStates = biquadFilterStateMemory;
|
||||||
|
_inputBufferIndex = baseIndex + inputBufferOffset;
|
||||||
public MultiTapBiquadFilterCommand Initialize(int baseIndex, ReadOnlySpan<BiquadFilterParameter2> filters, Memory<BiquadFilterState> biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan<bool> isInitialized, int nodeId)
|
_outputBufferIndex = baseIndex + outputBufferOffset;
|
||||||
{
|
_isInitialized = isInitialized.ToArray();
|
||||||
Parameters = filters.ToArray();
|
|
||||||
BiquadFilterStates = biquadFilterStateMemory;
|
|
||||||
InputBufferIndex = baseIndex + inputBufferOffset;
|
|
||||||
OutputBufferIndex = baseIndex + outputBufferOffset;
|
|
||||||
IsInitialized = isInitialized.ToArray();
|
|
||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
{
|
{
|
||||||
Span<BiquadFilterState> states = BiquadFilterStates.Span;
|
Span<BiquadFilterState> states = _biquadFilterStates.Span;
|
||||||
|
|
||||||
ReadOnlySpan<float> inputBuffer = context.GetBuffer(InputBufferIndex);
|
ReadOnlySpan<float> inputBuffer = context.GetBuffer(_inputBufferIndex);
|
||||||
Span<float> outputBuffer = context.GetBuffer(OutputBufferIndex);
|
Span<float> outputBuffer = context.GetBuffer(_outputBufferIndex);
|
||||||
|
|
||||||
for (int i = 0; i < Parameters.Length; i++)
|
for (int i = 0; i < _parameters.Length; i++)
|
||||||
{
|
{
|
||||||
if (!IsInitialized[i])
|
if (!_isInitialized[i])
|
||||||
{
|
{
|
||||||
states[i] = new BiquadFilterState();
|
states[i] = new BiquadFilterState();
|
||||||
}
|
}
|
||||||
@@ -56,13 +49,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
// NOTE: Nintendo only implement single and double biquad filters but no generic path when the command definition suggests it could be done.
|
// NOTE: Nintendo only implement single and double biquad filters but no generic path when the command definition suggests it could be done.
|
||||||
// As such we currently only implement a generic path for simplicity for double biquad.
|
// As such we currently only implement a generic path for simplicity for double biquad.
|
||||||
if (Parameters.Length == 1)
|
if (_parameters.Length == 1)
|
||||||
{
|
{
|
||||||
BiquadFilterHelper.ProcessBiquadFilter(ref Parameters[0], ref states[0], outputBuffer, inputBuffer, context.SampleCount);
|
BiquadFilterHelper.ProcessBiquadFilter(ref _parameters[0], ref states[0], outputBuffer, inputBuffer, context.SampleCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BiquadFilterHelper.ProcessBiquadFilter(Parameters, states, outputBuffer, inputBuffer, context.SampleCount);
|
BiquadFilterHelper.ProcessBiquadFilter(_parameters, states, outputBuffer, inputBuffer, context.SampleCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
using Ryujinx.Audio.Renderer.Common;
|
||||||
using Ryujinx.Audio.Renderer.Server.Voice;
|
using Ryujinx.Audio.Renderer.Server.Voice;
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
@@ -11,54 +11,47 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.PcmFloatDataSourceVersion1;
|
public CommandType CommandType => CommandType.PcmFloatDataSourceVersion1;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
public uint SampleRate { get; private set; }
|
public uint SampleRate { get; }
|
||||||
public uint ChannelIndex { get; private set; }
|
public uint ChannelIndex { get; }
|
||||||
|
|
||||||
public uint ChannelCount { get; private set; }
|
public uint ChannelCount { get; }
|
||||||
|
|
||||||
public float Pitch { get; private set; }
|
public float Pitch { get; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
public DecodingBehaviour DecodingBehaviour { get; }
|
||||||
|
|
||||||
public PcmFloatDataSourceCommandVersion1()
|
public PcmFloatDataSourceCommandVersion1(ref VoiceState serverState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PcmFloatDataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
||||||
SampleRate = serverInfo.SampleRate;
|
SampleRate = serverState.SampleRate;
|
||||||
ChannelIndex = channelIndex;
|
ChannelIndex = channelIndex;
|
||||||
ChannelCount = serverInfo.ChannelsCount;
|
ChannelCount = serverState.ChannelsCount;
|
||||||
Pitch = serverInfo.Pitch;
|
Pitch = serverState.Pitch;
|
||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
|
||||||
|
|
||||||
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverState.DecodingBehaviour;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
using Ryujinx.Audio.Renderer.Common;
|
||||||
using Ryujinx.Audio.Renderer.Server.Voice;
|
using Ryujinx.Audio.Renderer.Server.Voice;
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
@@ -11,54 +11,47 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.PcmInt16DataSourceVersion1;
|
public CommandType CommandType => CommandType.PcmInt16DataSourceVersion1;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
public uint SampleRate { get; private set; }
|
public uint SampleRate { get; }
|
||||||
public uint ChannelIndex { get; private set; }
|
public uint ChannelIndex { get; }
|
||||||
|
|
||||||
public uint ChannelCount { get; private set; }
|
public uint ChannelCount { get; }
|
||||||
|
|
||||||
public float Pitch { get; private set; }
|
public float Pitch { get; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; private set; }
|
public Memory<VoiceUpdateState> State { get; }
|
||||||
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
public DecodingBehaviour DecodingBehaviour { get; }
|
||||||
|
|
||||||
public PcmInt16DataSourceCommandVersion1()
|
public PcmInt16DataSourceCommandVersion1(ref VoiceState serverState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PcmInt16DataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
|
||||||
SampleRate = serverInfo.SampleRate;
|
SampleRate = serverState.SampleRate;
|
||||||
ChannelIndex = channelIndex;
|
ChannelIndex = channelIndex;
|
||||||
ChannelCount = serverInfo.ChannelsCount;
|
ChannelCount = serverState.ChannelsCount;
|
||||||
Pitch = serverInfo.Pitch;
|
Pitch = serverState.Pitch;
|
||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
|
||||||
|
|
||||||
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverState.DecodingBehaviour;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -13,34 +13,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Performance;
|
public CommandType CommandType => CommandType.Performance;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public PerformanceEntryAddresses PerformanceEntryAddresses { get; private set; }
|
public PerformanceEntryAddresses PerformanceEntryAddresses { get; }
|
||||||
|
|
||||||
public Type PerformanceType { get; set; }
|
public Type PerformanceType { get; set; }
|
||||||
|
|
||||||
public PerformanceCommand()
|
public PerformanceCommand(ref PerformanceEntryAddresses performanceEntryAddresses, Type performanceType, int nodeId)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public PerformanceCommand Initialize(ref PerformanceEntryAddresses performanceEntryAddresses, Type performanceType, int nodeId)
|
|
||||||
{
|
|
||||||
if (PerformanceEntryAddresses is not null)
|
|
||||||
{
|
|
||||||
PerformanceEntryAddresses.PerformanceEntryAddressesPool.Release(PerformanceEntryAddresses);
|
|
||||||
}
|
|
||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
PerformanceEntryAddresses = performanceEntryAddresses;
|
PerformanceEntryAddresses = performanceEntryAddresses;
|
||||||
PerformanceType = performanceType;
|
PerformanceType = performanceType;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -35,32 +35,26 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Reverb3d;
|
public CommandType CommandType => CommandType.Reverb3d;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public Reverb3dParameter Parameter => _parameter;
|
public Reverb3dParameter Parameter => _parameter;
|
||||||
public Memory<Reverb3dState> State { get; private set; }
|
public Memory<Reverb3dState> State { get; }
|
||||||
public ulong WorkBuffer { get; private set; }
|
public ulong WorkBuffer { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private Reverb3dParameter _parameter;
|
private Reverb3dParameter _parameter;
|
||||||
|
|
||||||
public Reverb3dCommand()
|
public Reverb3dCommand(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Reverb3dCommand Initialize(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
@@ -68,22 +62,20 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
_parameter = parameter;
|
_parameter = parameter;
|
||||||
State = state;
|
State = state;
|
||||||
WorkBuffer = workBuffer;
|
WorkBuffer = workBuffer;
|
||||||
|
|
||||||
Span<byte> inputSpan = Parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = Parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < Parameter.ChannelCount; i++)
|
for (int i = 0; i < Parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We do the opposite as Nintendo here for now to restore previous behaviour
|
// NOTE: We do the opposite as Nintendo here for now to restore previous behaviour
|
||||||
// TODO: Update reverb 3d processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
|
// TODO: Update reverb 3d processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
|
||||||
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
||||||
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -33,32 +33,26 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Reverb;
|
public CommandType CommandType => CommandType.Reverb;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ReverbParameter Parameter => _parameter;
|
public ReverbParameter Parameter => _parameter;
|
||||||
public Memory<ReverbState> State { get; private set; }
|
public Memory<ReverbState> State { get; }
|
||||||
public ulong WorkBuffer { get; private set; }
|
public ulong WorkBuffer { get; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsLongSizePreDelaySupported { get; private set; }
|
public bool IsLongSizePreDelaySupported { get; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; private set; }
|
public bool IsEffectEnabled { get; }
|
||||||
|
|
||||||
private ReverbParameter _parameter;
|
private ReverbParameter _parameter;
|
||||||
|
|
||||||
private const int FixedPointPrecision = 14;
|
private const int FixedPointPrecision = 14;
|
||||||
|
|
||||||
public ReverbCommand()
|
public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported)
|
||||||
{
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReverbCommand Initialize(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
@@ -66,14 +60,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
_parameter = parameter;
|
_parameter = parameter;
|
||||||
State = state;
|
State = state;
|
||||||
WorkBuffer = workBuffer;
|
WorkBuffer = workBuffer;
|
||||||
|
|
||||||
Span<byte> inputSpan = Parameter.Input.AsSpan();
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
Span<byte> outputSpan = Parameter.Output.AsSpan();
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
|
||||||
for (int i = 0; i < Parameter.ChannelCount; i++)
|
for (int i = 0; i < Parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsLongSizePreDelaySupported = isLongSizePreDelaySupported;
|
IsLongSizePreDelaySupported = isLongSizePreDelaySupported;
|
||||||
@@ -82,8 +76,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
// TODO: Update reverb processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
|
// TODO: Update reverb processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
|
||||||
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
||||||
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -7,27 +7,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Upsample;
|
public CommandType CommandType => CommandType.Upsample;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint BufferCount { get; private set; }
|
public uint BufferCount { get; }
|
||||||
public uint InputBufferIndex { get; private set; }
|
public uint InputBufferIndex { get; }
|
||||||
public uint InputSampleCount { get; private set; }
|
public uint InputSampleCount { get; }
|
||||||
public uint InputSampleRate { get; private set; }
|
public uint InputSampleRate { get; }
|
||||||
|
|
||||||
public UpsamplerInfo UpsamplerInfo { get; private set; }
|
public UpsamplerState UpsamplerInfo { get; }
|
||||||
|
|
||||||
public Memory<float> OutBuffer { get; private set; }
|
public Memory<float> OutBuffer { get; }
|
||||||
|
|
||||||
public UpsampleCommand()
|
public UpsampleCommand(uint bufferOffset, UpsamplerState info, uint inputCount, Span<byte> inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpsampleCommand Initialize(uint bufferOffset, UpsamplerInfo info, uint inputCount, Span<byte> inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -52,8 +47,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpsamplerInfo = info;
|
UpsamplerInfo = info;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Span<float> GetBuffer(int index, int sampleCount)
|
private Span<float> GetBuffer(int index, int sampleCount)
|
||||||
|
|||||||
@@ -11,23 +11,18 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Volume;
|
public CommandType CommandType => CommandType.Volume;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public float Volume { get; private set; }
|
public float Volume { get; }
|
||||||
|
|
||||||
public VolumeCommand()
|
public VolumeCommand(float volume, uint bufferIndex, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public VolumeCommand Initialize(float volume, uint bufferIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -36,8 +31,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
OutputBufferIndex = (ushort)bufferIndex;
|
OutputBufferIndex = (ushort)bufferIndex;
|
||||||
|
|
||||||
Volume = volume;
|
Volume = volume;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -7,24 +7,19 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; private set; }
|
public int NodeId { get; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.VolumeRamp;
|
public CommandType CommandType => CommandType.VolumeRamp;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; private set; }
|
public ushort InputBufferIndex { get; }
|
||||||
public ushort OutputBufferIndex { get; private set; }
|
public ushort OutputBufferIndex { get; }
|
||||||
|
|
||||||
public float Volume0 { get; private set; }
|
public float Volume0 { get; }
|
||||||
public float Volume1 { get; private set; }
|
public float Volume1 { get; }
|
||||||
|
|
||||||
public VolumeRampCommand()
|
public VolumeRampCommand(float volume0, float volume1, uint bufferIndex, int nodeId)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public VolumeRampCommand Initialize(float volume0, float volume1, uint bufferIndex, int nodeId)
|
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -34,8 +29,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Volume0 = volume0;
|
Volume0 = volume0;
|
||||||
Volume1 = volume1;
|
Volume1 = volume1;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
using System.Runtime.Intrinsics.Arm;
|
using System.Runtime.Intrinsics.Arm;
|
||||||
using System.Runtime.Intrinsics.X86;
|
using System.Runtime.Intrinsics.X86;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp
|
namespace Ryujinx.Audio.Renderer.Dsp
|
||||||
{
|
{
|
||||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span<float> outputBuffer, ref WaveBufferInformation info, Span<WaveBuffer> wavebuffers, ref VoiceState voiceState, uint targetSampleRate, int sampleCount)
|
public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span<float> outputBuffer, ref WaveBufferInformation info, Span<WaveBuffer> wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount)
|
||||||
{
|
{
|
||||||
const int TempBufferSize = 0x3F00;
|
const int TempBufferSize = 0x3F00;
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
{
|
{
|
||||||
int tempBufferIndex = 0;
|
int tempBufferIndex = 0;
|
||||||
|
|
||||||
if ((info.DecodingBehaviour & DecodingBehaviour.SkipPitchAndSampleRateConversion) != DecodingBehaviour.SkipPitchAndSampleRateConversion)
|
if (!info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion))
|
||||||
{
|
{
|
||||||
voiceState.Pitch.AsSpan()[..pitchMaxLength].CopyTo(tempBuffer);
|
voiceState.Pitch.AsSpan()[..pitchMaxLength].CopyTo(tempBuffer);
|
||||||
tempBufferIndex += pitchMaxLength;
|
tempBufferIndex += pitchMaxLength;
|
||||||
@@ -208,7 +208,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.DecodingBehaviour & DecodingBehaviour.PlayedSampleCountResetWhenLooping) == DecodingBehaviour.PlayedSampleCountResetWhenLooping)
|
if (info.DecodingBehaviour.HasFlag(DecodingBehaviour.PlayedSampleCountResetWhenLooping))
|
||||||
{
|
{
|
||||||
playedSampleCount = 0;
|
playedSampleCount = 0;
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
|
|
||||||
Span<int> outputSpanInt = MemoryMarshal.Cast<float, int>(outputBuffer[i..]);
|
Span<int> outputSpanInt = MemoryMarshal.Cast<float, int>(outputBuffer[i..]);
|
||||||
|
|
||||||
if ((info.DecodingBehaviour & DecodingBehaviour.SkipPitchAndSampleRateConversion) == DecodingBehaviour.SkipPitchAndSampleRateConversion)
|
if (info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion))
|
||||||
{
|
{
|
||||||
for (int j = 0; j < y; j++)
|
for (int j = 0; j < y; j++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Linq;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
using System.Runtime.Intrinsics.X86;
|
using System.Runtime.Intrinsics.X86;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp
|
namespace Ryujinx.Audio.Renderer.Dsp
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,12 +41,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
}
|
}
|
||||||
|
|
||||||
Array20<float> result = new();
|
Array20<float> result = new();
|
||||||
Span<float> resultSpan = result.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < FilterBankLength; i++)
|
for (int i = 0; i < FilterBankLength; i++)
|
||||||
{
|
{
|
||||||
float x = (Bank0CenterIndex - i) + offset;
|
float x = (Bank0CenterIndex - i) + offset;
|
||||||
resultSpan[i] = Sinc(x) * BlackmanWindow(x / FilterBankLength + 0.5f);
|
result[i] = Sinc(x) * BlackmanWindow(x / FilterBankLength + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -79,9 +78,6 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
|
|
||||||
Debug.Assert(state.History.Length == HistoryLength);
|
Debug.Assert(state.History.Length == HistoryLength);
|
||||||
Debug.Assert(bank.Length == FilterBankLength);
|
Debug.Assert(bank.Length == FilterBankLength);
|
||||||
|
|
||||||
Span<float> bankSpan = bank.AsSpan();
|
|
||||||
Span<float> historySpan = state.History.AsSpan();
|
|
||||||
|
|
||||||
int curIdx = 0;
|
int curIdx = 0;
|
||||||
if (Vector.IsHardwareAccelerated)
|
if (Vector.IsHardwareAccelerated)
|
||||||
@@ -92,15 +88,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
while (curIdx < stopIdx)
|
while (curIdx < stopIdx)
|
||||||
{
|
{
|
||||||
result += Vector.Dot(
|
result += Vector.Dot(
|
||||||
new Vector<float>(bankSpan[curIdx..(curIdx + Vector<float>.Count)]),
|
new Vector<float>(bank.AsSpan().Slice(curIdx, Vector<float>.Count)),
|
||||||
new Vector<float>(historySpan[curIdx..(curIdx + Vector<float>.Count)]));
|
new Vector<float>(state.History.AsSpan().Slice(curIdx, Vector<float>.Count)));
|
||||||
curIdx += Vector<float>.Count;
|
curIdx += Vector<float>.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (curIdx < FilterBankLength)
|
while (curIdx < FilterBankLength)
|
||||||
{
|
{
|
||||||
result += bankSpan[curIdx] * historySpan[curIdx];
|
result += bank[curIdx] * state.History[curIdx];
|
||||||
curIdx++;
|
curIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Audio.Renderer.Server;
|
|
||||||
using Ryujinx.Audio.Renderer.Server.Types;
|
using Ryujinx.Audio.Renderer.Server.Types;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@@ -94,7 +93,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user audio revision
|
/// The user audio revision
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="BehaviourInfo"/>
|
/// <seealso cref="Server.BehaviourContext"/>
|
||||||
public int Revision;
|
public int Revision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// Biquad filter parameters.
|
/// Biquad filter parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)]
|
||||||
public struct BiquadFilterParameter1
|
public struct BiquadFilterParameter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true if the biquad filter is active.
|
/// Set to true if the biquad filter is active.
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using Ryujinx.Common.Memory;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Parameter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter parameters.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 1)]
|
|
||||||
public struct BiquadFilterParameter2
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true if the biquad filter is active.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool Enable;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/padding.
|
|
||||||
/// </summary>
|
|
||||||
private readonly byte _reserved1;
|
|
||||||
private readonly byte _reserved2;
|
|
||||||
private readonly byte _reserved3;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter numerator (b0, b1, b2).
|
|
||||||
/// </summary>
|
|
||||||
public Array3<float> Numerator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter denominator (a1, a2).
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>a0 = 1</remarks>
|
|
||||||
public Array2<float> Denominator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
|||||||
/// <see cref="IEffectInParameter.SpecificData"/> for <see cref="Common.EffectType.BiquadFilter"/>.
|
/// <see cref="IEffectInParameter.SpecificData"/> for <see cref="Common.EffectType.BiquadFilter"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct BiquadFilterEffectParameter1
|
public struct BiquadFilterEffectParameter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using Ryujinx.Audio.Renderer.Server.Effect;
|
|
||||||
using Ryujinx.Common.Memory;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="IEffectInParameter.SpecificData"/> for <see cref="Common.EffectType.BiquadFilter"/>.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
public struct BiquadFilterEffectParameter2
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
|
||||||
/// </summary>
|
|
||||||
public Array6<byte> Input;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
|
||||||
/// </summary>
|
|
||||||
public Array6<byte> Output;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter numerator (b0, b1, b2).
|
|
||||||
/// </summary>
|
|
||||||
public Array3<float> Numerator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter denominator (a1, a2).
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>a0 = 1</remarks>
|
|
||||||
public Array2<float> Denominator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The total channel count used.
|
|
||||||
/// </summary>
|
|
||||||
public byte ChannelCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current usage status of the effect on the client side.
|
|
||||||
/// </summary>
|
|
||||||
public UsageState Status;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/unused.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ushort _reserved;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,11 +17,11 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// The mix to output the result of the splitter.
|
/// The mix to output the result of the splitter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int DestinationId { get; }
|
int DestinationId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Biquad filter parameters.
|
/// Biquad filter parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Array2<BiquadFilterParameter2> BiquadFilters2 { get; }
|
Array2<BiquadFilterParameter> BiquadFilters { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true if in use.
|
/// Set to true if in use.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reserved/padding.
|
/// Reserved/padding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ushort _magic; // 0xCAFE
|
private readonly ushort _reserved1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The node id of the sink.
|
/// The node id of the sink.
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
readonly int ISplitterDestinationInParameter.Id => Id;
|
readonly int ISplitterDestinationInParameter.Id => Id;
|
||||||
|
|
||||||
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
|
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
|
||||||
|
|
||||||
readonly Array2<BiquadFilterParameter2> ISplitterDestinationInParameter.BiquadFilters2 => default;
|
readonly Array2<BiquadFilterParameter> ISplitterDestinationInParameter.BiquadFilters => default;
|
||||||
|
|
||||||
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
|
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
|
||||||
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
|
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// Input header for a splitter destination version 2 update.
|
/// Input header for a splitter destination version 2 update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct SplitterDestinationInParameterVersion2b : ISplitterDestinationInParameter
|
public struct SplitterDestinationInParameterVersion2 : ISplitterDestinationInParameter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Magic of the input header.
|
/// Magic of the input header.
|
||||||
@@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Biquad filter parameters.
|
/// Biquad filter parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Array2<BiquadFilterParameter2> BiquadFilters;
|
public Array2<BiquadFilterParameter> BiquadFilters;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true if in use.
|
/// Set to true if in use.
|
||||||
@@ -66,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
|
|
||||||
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
|
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
|
||||||
|
|
||||||
readonly Array2<BiquadFilterParameter2> ISplitterDestinationInParameter.BiquadFilters2 => BiquadFilters;
|
readonly Array2<BiquadFilterParameter> ISplitterDestinationInParameter.BiquadFilters => BiquadFilters;
|
||||||
|
|
||||||
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
|
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
|
||||||
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
|
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp;
|
|
||||||
using Ryujinx.Common.Memory;
|
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Parameter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Input header for a splitter destination version 2 update.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
public struct SplitterDestinationInParameterVersion2a : ISplitterDestinationInParameter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Magic of the input header.
|
|
||||||
/// </summary>
|
|
||||||
public uint Magic;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Target splitter destination data id.
|
|
||||||
/// </summary>
|
|
||||||
public int Id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mix buffer volumes storage.
|
|
||||||
/// </summary>
|
|
||||||
private MixArray _mixBufferVolume;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The mix to output the result of the splitter.
|
|
||||||
/// </summary>
|
|
||||||
public int DestinationId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filter parameters.
|
|
||||||
/// </summary>
|
|
||||||
public Array2<BiquadFilterParameter1> BiquadFilters;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true if in use.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool IsUsed;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true to force resetting the previous mix volumes.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool ResetPrevVolume;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/padding.
|
|
||||||
/// </summary>
|
|
||||||
private unsafe fixed byte _reserved[10];
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Size = sizeof(float) * Constants.MixBufferCountMax, Pack = 1)]
|
|
||||||
private struct MixArray { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mix buffer volumes.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Used when a splitter id is specified in the mix.</remarks>
|
|
||||||
public Span<float> MixBufferVolume => SpanHelpers.AsSpan<MixArray, float>(ref _mixBufferVolume);
|
|
||||||
|
|
||||||
readonly int ISplitterDestinationInParameter.Id => Id;
|
|
||||||
|
|
||||||
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
|
|
||||||
|
|
||||||
readonly Array2<BiquadFilterParameter2> ISplitterDestinationInParameter.BiquadFilters2
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
Array2<BiquadFilterParameter2> newFilters = new();
|
|
||||||
Span<BiquadFilterParameter2> newFiltersSpan = newFilters.AsSpan();
|
|
||||||
newFiltersSpan[0] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[0]);
|
|
||||||
newFiltersSpan[1] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[1]);
|
|
||||||
|
|
||||||
return newFilters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
|
|
||||||
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The expected constant of any input header.
|
|
||||||
/// </summary>
|
|
||||||
private const uint ValidMagic = 0x44444E53;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the magic is valid.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Returns true if the magic is valid.</returns>
|
|
||||||
public readonly bool IsMagicValid()
|
|
||||||
{
|
|
||||||
return Magic == ValidMagic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// Input information for a voice.
|
/// Input information for a voice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x170, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Size = 0x170, Pack = 1)]
|
||||||
public struct VoiceInParameter1
|
public struct VoiceInParameter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id of the voice.
|
/// Id of the voice.
|
||||||
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Biquad filters to apply to the output of the voice.
|
/// Biquad filters to apply to the output of the voice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Array2<BiquadFilterParameter1> BiquadFilters;
|
public Array2<BiquadFilterParameter> BiquadFilters;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total count of <see cref="WaveBufferInternal"/> of the voice.
|
/// Total count of <see cref="WaveBufferInternal"/> of the voice.
|
||||||
@@ -171,9 +171,8 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// Reserved/unused.
|
/// Reserved/unused.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private unsafe fixed uint _reserved3[2];
|
private unsafe fixed uint _reserved3[2];
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
|
||||||
/// Input information for a voice wavebuffer.
|
/// Input information for a voice wavebuffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x38, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Size = 0x38, Pack = 1)]
|
||||||
@@ -329,4 +328,5 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Low,
|
Low,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
using Ryujinx.Audio.Common;
|
|
||||||
using Ryujinx.Audio.Renderer.Common;
|
|
||||||
using Ryujinx.Common.Memory;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Parameter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Input information for a voice.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x188, Pack = 1)]
|
|
||||||
public struct VoiceInParameter2
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Id of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public int Id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Node id of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public int NodeId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true if the voice is new.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool IsNew;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true if the voice is used.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool InUse;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The voice <see cref="PlayState"/> wanted by the user.
|
|
||||||
/// </summary>
|
|
||||||
public PlayState PlayState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="SampleFormat"/> of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public SampleFormat SampleFormat;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The sample rate of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public uint SampleRate;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The priority of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public uint Priority;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Target sorting position of the voice. (Used to sort voices with the same <see cref="Priority"/>)
|
|
||||||
/// </summary>
|
|
||||||
public uint SortingOrder;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The total channel count used.
|
|
||||||
/// </summary>
|
|
||||||
public uint ChannelCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The pitch used on the voice.
|
|
||||||
/// </summary>
|
|
||||||
public float Pitch;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The output volume of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public float Volume;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Biquad filters to apply to the output of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public Array2<BiquadFilterParameter2> BiquadFilters;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Total count of <see cref="WaveBufferInternal"/> of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public uint WaveBuffersCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Current playing <see cref="WaveBufferInternal"/> of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public uint WaveBuffersIndex;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/unused.
|
|
||||||
/// </summary>
|
|
||||||
private readonly uint
|
|
||||||
_reserved1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// User state address required by the data source.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Only used for <see cref="SampleFormat.Adpcm"/> as the address of the GC-ADPCM coefficients.</remarks>
|
|
||||||
public ulong DataSourceStateAddress;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// User state size required by the data source.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Only used for <see cref="SampleFormat.Adpcm"/> as the size of the GC-ADPCM coefficients.</remarks>
|
|
||||||
public ulong DataSourceStateSize;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The target mix id of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public int MixId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The target splitter id of the voice.
|
|
||||||
/// </summary>
|
|
||||||
public uint SplitterId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The wavebuffer parameters of this voice.
|
|
||||||
/// </summary>
|
|
||||||
public Array4<WaveBufferInternal> WaveBuffers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The channel resource ids associated to the voice.
|
|
||||||
/// </summary>
|
|
||||||
public Array6<int> ChannelResourceIds;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reset the voice drop flag during voice server update.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
|
||||||
public bool ResetVoiceDropFlag;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Flush the amount of wavebuffer specified. This will result in the wavebuffer being skipped and marked played.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This was added on REV5.</remarks>
|
|
||||||
public byte FlushWaveBufferCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/unused.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ushort _reserved2;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Change the behaviour of the voice.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This was added on REV5.</remarks>
|
|
||||||
public DecodingBehaviour DecodingBehaviourFlags;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Change the Sample Rate Conversion (SRC) quality of the voice.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This was added on REV8.</remarks>
|
|
||||||
public SampleRateConversionQuality SrcQuality;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
|
|
||||||
/// </summary>
|
|
||||||
public uint ExternalContext;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
|
|
||||||
/// </summary>
|
|
||||||
public uint ExternalContextSize;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved/unused.
|
|
||||||
/// </summary>
|
|
||||||
private unsafe fixed uint _reserved3[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
|
||||||
using Ryujinx.Audio.Renderer.Server;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Parameter
|
namespace Ryujinx.Audio.Renderer.Parameter
|
||||||
@@ -7,7 +5,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output information about a voice.
|
/// Output information about a voice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>See <seealso cref="StateUpdater.UpdateVoices1"/></remarks>
|
/// <remarks>See <seealso cref="Server.StateUpdater.UpdateVoices(Server.Voice.VoiceContext, System.Memory{Server.MemoryPool.MemoryPoolState})"/></remarks>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct VoiceOutStatus
|
public struct VoiceOutStatus
|
||||||
{
|
{
|
||||||
@@ -15,7 +13,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
|
|||||||
/// The total amount of samples that was played.
|
/// The total amount of samples that was played.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This is reset to 0 when a <see cref="Common.WaveBuffer"/> finishes playing and <see cref="Common.WaveBuffer.IsEndOfStream"/> is set.</remarks>
|
/// <remarks>This is reset to 0 when a <see cref="Common.WaveBuffer"/> finishes playing and <see cref="Common.WaveBuffer.IsEndOfStream"/> is set.</remarks>
|
||||||
/// <remarks>This is reset to 0 when looping while <see cref="DecodingBehaviour.PlayedSampleCountResetWhenLooping"/> is set.</remarks>
|
/// <remarks>This is reset to 0 when looping while <see cref="Parameter.VoiceInParameter.DecodingBehaviour.PlayedSampleCountResetWhenLooping"/> is set.</remarks>
|
||||||
public ulong PlayedSampleCount;
|
public ulong PlayedSampleCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
private AudioRendererRenderingDevice _renderingDevice;
|
private AudioRendererRenderingDevice _renderingDevice;
|
||||||
private AudioRendererExecutionMode _executionMode;
|
private AudioRendererExecutionMode _executionMode;
|
||||||
private readonly IWritableEvent _systemEvent;
|
private readonly IWritableEvent _systemEvent;
|
||||||
private MemoryPoolInfo _dspMemoryPoolInfo;
|
private MemoryPoolState _dspMemoryPoolState;
|
||||||
private readonly VoiceContext _voiceContext;
|
private readonly VoiceContext _voiceContext;
|
||||||
private readonly MixContext _mixContext;
|
private readonly MixContext _mixContext;
|
||||||
private readonly SinkContext _sinkContext;
|
private readonly SinkContext _sinkContext;
|
||||||
@@ -40,13 +40,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
private PerformanceManager _performanceManager;
|
private PerformanceManager _performanceManager;
|
||||||
private UpsamplerManager _upsamplerManager;
|
private UpsamplerManager _upsamplerManager;
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private BehaviourInfo _behaviourInfo;
|
private BehaviourContext _behaviourContext;
|
||||||
#pragma warning disable IDE0052 // Remove unread private member
|
#pragma warning disable IDE0052 // Remove unread private member
|
||||||
private ulong _totalElapsedTicksUpdating;
|
private ulong _totalElapsedTicksUpdating;
|
||||||
private ulong _totalElapsedTicks;
|
private ulong _totalElapsedTicks;
|
||||||
#pragma warning restore IDE0052
|
#pragma warning restore IDE0052
|
||||||
private int _sessionId;
|
private int _sessionId;
|
||||||
private Memory<MemoryPoolInfo> _memoryPools;
|
private Memory<MemoryPoolState> _memoryPools;
|
||||||
|
|
||||||
private uint _sampleRate;
|
private uint _sampleRate;
|
||||||
private uint _sampleCount;
|
private uint _sampleCount;
|
||||||
@@ -84,7 +84,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent)
|
public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
_dspMemoryPoolInfo = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
|
_dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
|
||||||
_voiceContext = new VoiceContext();
|
_voiceContext = new VoiceContext();
|
||||||
_mixContext = new MixContext();
|
_mixContext = new MixContext();
|
||||||
_sinkContext = new SinkContext();
|
_sinkContext = new SinkContext();
|
||||||
@@ -93,7 +93,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
_commandProcessingTimeEstimator = null;
|
_commandProcessingTimeEstimator = null;
|
||||||
_systemEvent = systemEvent;
|
_systemEvent = systemEvent;
|
||||||
_behaviourInfo = new BehaviourInfo();
|
_behaviourContext = new BehaviourContext();
|
||||||
|
|
||||||
_totalElapsedTicksUpdating = 0;
|
_totalElapsedTicksUpdating = 0;
|
||||||
_sessionId = 0;
|
_sessionId = 0;
|
||||||
@@ -110,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
ulong appletResourceId,
|
ulong appletResourceId,
|
||||||
IVirtualMemoryManager memoryManager)
|
IVirtualMemoryManager memoryManager)
|
||||||
{
|
{
|
||||||
if (!BehaviourInfo.CheckValidRevision(parameter.Revision))
|
if (!BehaviourContext.CheckValidRevision(parameter.Revision))
|
||||||
{
|
{
|
||||||
return ResultCode.OperationFailed;
|
return ResultCode.OperationFailed;
|
||||||
}
|
}
|
||||||
@@ -122,9 +122,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
Debug.Assert(parameter.RenderingDevice == AudioRendererRenderingDevice.Dsp && parameter.ExecutionMode == AudioRendererExecutionMode.Auto);
|
Debug.Assert(parameter.RenderingDevice == AudioRendererRenderingDevice.Dsp && parameter.ExecutionMode == AudioRendererExecutionMode.Auto);
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourInfo.GetRevisionNumber(parameter.Revision)}");
|
Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourContext.GetRevisionNumber(parameter.Revision)}");
|
||||||
|
|
||||||
_behaviourInfo.SetUserRevision(parameter.Revision);
|
_behaviourContext.SetUserRevision(parameter.Revision);
|
||||||
|
|
||||||
_sampleRate = parameter.SampleRate;
|
_sampleRate = parameter.SampleRate;
|
||||||
_sampleCount = parameter.SampleCount;
|
_sampleCount = parameter.SampleCount;
|
||||||
@@ -151,7 +151,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
|
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
|
||||||
|
|
||||||
PoolMapper poolMapper = new(processHandle, false);
|
PoolMapper poolMapper = new(processHandle, false);
|
||||||
poolMapper.InitializeSystemPool(ref _dspMemoryPoolInfo, workBuffer, workBufferSize);
|
poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
|
||||||
|
|
||||||
_mixBuffer = workBufferAllocator.Allocate<float>(_sampleCount * (_voiceChannelCountMax + _mixBufferCount), 0x10);
|
_mixBuffer = workBufferAllocator.Allocate<float>(_sampleCount * (_voiceChannelCountMax + _mixBufferCount), 0x10);
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
Memory<BiquadFilterState> splitterBqfStates = Memory<BiquadFilterState>.Empty;
|
Memory<BiquadFilterState> splitterBqfStates = Memory<BiquadFilterState>.Empty;
|
||||||
|
|
||||||
if (_behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
|
if (_behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
|
||||||
parameter.SplitterCount > 0 &&
|
parameter.SplitterCount > 0 &&
|
||||||
parameter.SplitterDestinationCount > 0)
|
parameter.SplitterDestinationCount > 0)
|
||||||
{
|
{
|
||||||
@@ -191,23 +191,23 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invalidate DSP cache on what was currently allocated with workBuffer.
|
// Invalidate DSP cache on what was currently allocated with workBuffer.
|
||||||
AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolInfo.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
|
AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolState.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
|
||||||
|
|
||||||
Debug.Assert((workBufferAllocator.Offset % Constants.BufferAlignment) == 0);
|
Debug.Assert((workBufferAllocator.Offset % Constants.BufferAlignment) == 0);
|
||||||
|
|
||||||
Memory<VoiceInfo> voices = workBufferAllocator.Allocate<VoiceInfo>(parameter.VoiceCount, VoiceInfo.Alignment);
|
Memory<VoiceState> voices = workBufferAllocator.Allocate<VoiceState>(parameter.VoiceCount, VoiceState.Alignment);
|
||||||
|
|
||||||
if (voices.IsEmpty)
|
if (voices.IsEmpty)
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ref VoiceInfo voice in voices.Span)
|
foreach (ref VoiceState voice in voices.Span)
|
||||||
{
|
{
|
||||||
voice.Initialize();
|
voice.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// A pain to handle as we can't have VoiceInfo*, use indices to be a bit more safe
|
// A pain to handle as we can't have VoiceState*, use indices to be a bit more safe
|
||||||
Memory<int> sortedVoices = workBufferAllocator.Allocate<int>(parameter.VoiceCount, 0x10);
|
Memory<int> sortedVoices = workBufferAllocator.Allocate<int>(parameter.VoiceCount, 0x10);
|
||||||
|
|
||||||
if (sortedVoices.IsEmpty)
|
if (sortedVoices.IsEmpty)
|
||||||
@@ -233,16 +233,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
voiceChannelResource.IsUsed = false;
|
voiceChannelResource.IsUsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory<VoiceState> voiceStates = workBufferAllocator.Allocate<VoiceState>(parameter.VoiceCount, VoiceState.Align);
|
Memory<VoiceUpdateState> voiceUpdateStates = workBufferAllocator.Allocate<VoiceUpdateState>(parameter.VoiceCount, VoiceUpdateState.Align);
|
||||||
|
|
||||||
if (voiceStates.IsEmpty)
|
if (voiceUpdateStates.IsEmpty)
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint mixesCount = parameter.SubMixBufferCount + 1;
|
uint mixesCount = parameter.SubMixBufferCount + 1;
|
||||||
|
|
||||||
Memory<MixInfo> mixes = workBufferAllocator.Allocate<MixInfo>(mixesCount, MixInfo.Alignment);
|
Memory<MixState> mixes = workBufferAllocator.Allocate<MixState>(mixesCount, MixState.Alignment);
|
||||||
|
|
||||||
if (mixes.IsEmpty)
|
if (mixes.IsEmpty)
|
||||||
{
|
{
|
||||||
@@ -251,18 +251,18 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (parameter.EffectCount == 0)
|
if (parameter.EffectCount == 0)
|
||||||
{
|
{
|
||||||
foreach (ref MixInfo mix in mixes.Span)
|
foreach (ref MixState mix in mixes.Span)
|
||||||
{
|
{
|
||||||
mix = new MixInfo(Memory<int>.Empty, ref _behaviourInfo);
|
mix = new MixState(Memory<int>.Empty, ref _behaviourContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory<int> effectProcessingOrderArray = workBufferAllocator.Allocate<int>(parameter.EffectCount * mixesCount, 0x10);
|
Memory<int> effectProcessingOrderArray = workBufferAllocator.Allocate<int>(parameter.EffectCount * mixesCount, 0x10);
|
||||||
|
|
||||||
foreach (ref MixInfo mix in mixes.Span)
|
foreach (ref MixState mix in mixes.Span)
|
||||||
{
|
{
|
||||||
mix = new MixInfo(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourInfo);
|
mix = new MixState(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourContext);
|
||||||
|
|
||||||
effectProcessingOrderArray = effectProcessingOrderArray[(int)parameter.EffectCount..];
|
effectProcessingOrderArray = effectProcessingOrderArray[(int)parameter.EffectCount..];
|
||||||
}
|
}
|
||||||
@@ -271,20 +271,20 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
// Initialize the final mix id
|
// Initialize the final mix id
|
||||||
mixes.Span[0].MixId = Constants.FinalMixId;
|
mixes.Span[0].MixId = Constants.FinalMixId;
|
||||||
|
|
||||||
Memory<int> sortedMixesInfo = workBufferAllocator.Allocate<int>(mixesCount, 0x10);
|
Memory<int> sortedMixesState = workBufferAllocator.Allocate<int>(mixesCount, 0x10);
|
||||||
|
|
||||||
if (sortedMixesInfo.IsEmpty)
|
if (sortedMixesState.IsEmpty)
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear memory (use -1 as it's an invalid index)
|
// Clear memory (use -1 as it's an invalid index)
|
||||||
sortedMixesInfo.Span.Fill(-1);
|
sortedMixesState.Span.Fill(-1);
|
||||||
|
|
||||||
Memory<byte> nodeStatesWorkBuffer = Memory<byte>.Empty;
|
Memory<byte> nodeStatesWorkBuffer = Memory<byte>.Empty;
|
||||||
Memory<byte> edgeMatrixWorkBuffer = Memory<byte>.Empty;
|
Memory<byte> edgeMatrixWorkBuffer = Memory<byte>.Empty;
|
||||||
|
|
||||||
if (_behaviourInfo.IsSplitterSupported())
|
if (_behaviourContext.IsSplitterSupported())
|
||||||
{
|
{
|
||||||
nodeStatesWorkBuffer = workBufferAllocator.Allocate((uint)NodeStates.GetWorkBufferSize((int)mixesCount), 1);
|
nodeStatesWorkBuffer = workBufferAllocator.Allocate((uint)NodeStates.GetWorkBufferSize((int)mixesCount), 1);
|
||||||
edgeMatrixWorkBuffer = workBufferAllocator.Allocate((uint)EdgeMatrix.GetWorkBufferSize((int)mixesCount), 1);
|
edgeMatrixWorkBuffer = workBufferAllocator.Allocate((uint)EdgeMatrix.GetWorkBufferSize((int)mixesCount), 1);
|
||||||
@@ -295,21 +295,21 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_mixContext.Initialize(sortedMixesInfo, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
|
_mixContext.Initialize(sortedMixesState, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
|
||||||
|
|
||||||
_memoryPools = workBufferAllocator.Allocate<MemoryPoolInfo>(_memoryPoolCount, MemoryPoolInfo.Alignment);
|
_memoryPools = workBufferAllocator.Allocate<MemoryPoolState>(_memoryPoolCount, MemoryPoolState.Alignment);
|
||||||
|
|
||||||
if (_memoryPools.IsEmpty)
|
if (_memoryPools.IsEmpty)
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ref MemoryPoolInfo info in _memoryPools.Span)
|
foreach (ref MemoryPoolState state in _memoryPools.Span)
|
||||||
{
|
{
|
||||||
info = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
|
state = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_splitterContext.Initialize(ref _behaviourInfo, ref parameter, workBufferAllocator, splitterBqfStates))
|
if (!_splitterContext.Initialize(ref _behaviourContext, ref parameter, workBufferAllocator, splitterBqfStates))
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
@@ -318,21 +318,21 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
_upsamplerManager = new UpsamplerManager(upSamplerWorkBuffer, _upsamplerCount);
|
_upsamplerManager = new UpsamplerManager(upSamplerWorkBuffer, _upsamplerCount);
|
||||||
|
|
||||||
_effectContext.Initialize(parameter.EffectCount, _behaviourInfo.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
|
_effectContext.Initialize(parameter.EffectCount, _behaviourContext.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
|
||||||
_sinkContext.Initialize(parameter.SinkCount);
|
_sinkContext.Initialize(parameter.SinkCount);
|
||||||
|
|
||||||
Memory<VoiceState> voiceStatesDsp = workBufferAllocator.Allocate<VoiceState>(parameter.VoiceCount, VoiceState.Align);
|
Memory<VoiceUpdateState> voiceUpdateStatesDsp = workBufferAllocator.Allocate<VoiceUpdateState>(parameter.VoiceCount, VoiceUpdateState.Align);
|
||||||
|
|
||||||
if (voiceStatesDsp.IsEmpty)
|
if (voiceUpdateStatesDsp.IsEmpty)
|
||||||
{
|
{
|
||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
_voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceStates, voiceStatesDsp, parameter.VoiceCount);
|
_voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceUpdateStates, voiceUpdateStatesDsp, parameter.VoiceCount);
|
||||||
|
|
||||||
if (parameter.PerformanceMetricFramesCount > 0)
|
if (parameter.PerformanceMetricFramesCount > 0)
|
||||||
{
|
{
|
||||||
ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
||||||
|
|
||||||
_performanceBuffer = workBufferAllocator.Allocate(performanceBufferSize, Constants.BufferAlignment);
|
_performanceBuffer = workBufferAllocator.Allocate(performanceBufferSize, Constants.BufferAlignment);
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
_performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourInfo);
|
_performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourContext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -359,14 +359,14 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
_elapsedFrameCount = 0;
|
_elapsedFrameCount = 0;
|
||||||
_voiceDropParameter = 1.0f;
|
_voiceDropParameter = 1.0f;
|
||||||
|
|
||||||
_commandProcessingTimeEstimator = _behaviourInfo.GetCommandProcessingTimeEstimatorVersion() switch
|
_commandProcessingTimeEstimator = _behaviourContext.GetCommandProcessingTimeEstimatorVersion() switch
|
||||||
{
|
{
|
||||||
1 => new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount),
|
1 => new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount),
|
||||||
2 => new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount),
|
2 => new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount),
|
||||||
3 => new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount),
|
3 => new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount),
|
||||||
4 => new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount),
|
4 => new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount),
|
||||||
5 => new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount),
|
5 => new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount),
|
||||||
_ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourInfo.GetCommandProcessingTimeEstimatorVersion()}."),
|
_ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}."),
|
||||||
};
|
};
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
@@ -411,11 +411,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
output.Span.Clear();
|
output.Span.Clear();
|
||||||
|
|
||||||
StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourInfo);
|
StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourContext);
|
||||||
|
|
||||||
ResultCode result;
|
ResultCode result;
|
||||||
|
|
||||||
result = stateUpdater.UpdateBehaviourInfo();
|
result = stateUpdater.UpdateBehaviourContext();
|
||||||
|
|
||||||
if (result != ResultCode.Success)
|
if (result != ResultCode.Success)
|
||||||
{
|
{
|
||||||
@@ -436,16 +436,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourInfo.IsMemoryPoolForceMappingEnabled());
|
PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
|
||||||
|
|
||||||
if (_behaviourInfo.IsBiquadFilterParameterFloatSupported())
|
result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);
|
||||||
{
|
|
||||||
result = stateUpdater.UpdateVoices2(_voiceContext, poolMapper);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = stateUpdater.UpdateVoices1(_voiceContext, poolMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != ResultCode.Success)
|
if (result != ResultCode.Success)
|
||||||
{
|
{
|
||||||
@@ -459,7 +452,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_behaviourInfo.IsSplitterSupported())
|
if (_behaviourContext.IsSplitterSupported())
|
||||||
{
|
{
|
||||||
result = stateUpdater.UpdateSplitter(_splitterContext);
|
result = stateUpdater.UpdateSplitter(_splitterContext);
|
||||||
|
|
||||||
@@ -497,7 +490,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_behaviourInfo.IsElapsedFrameCountSupported())
|
if (_behaviourContext.IsElapsedFrameCountSupported())
|
||||||
{
|
{
|
||||||
result = stateUpdater.UpdateRendererInfo(_elapsedFrameCount);
|
result = stateUpdater.UpdateRendererInfo(_elapsedFrameCount);
|
||||||
|
|
||||||
@@ -564,7 +557,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref VoiceInfo voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
|
ref VoiceState voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
|
||||||
|
|
||||||
if (voice.Priority == Constants.VoiceHighestPriority)
|
if (voice.Priority == Constants.VoiceHighestPriority)
|
||||||
{
|
{
|
||||||
@@ -653,7 +646,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
_voiceContext.UpdateForCommandGeneration();
|
_voiceContext.UpdateForCommandGeneration();
|
||||||
|
|
||||||
if (_behaviourInfo.IsEffectInfoVersion2Supported())
|
if (_behaviourContext.IsEffectInfoVersion2Supported())
|
||||||
{
|
{
|
||||||
_effectContext.UpdateResultStateForCommandGeneration();
|
_effectContext.UpdateResultStateForCommandGeneration();
|
||||||
}
|
}
|
||||||
@@ -668,7 +661,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
private int GetMaxAllocatedTimeForDsp()
|
private int GetMaxAllocatedTimeForDsp()
|
||||||
{
|
{
|
||||||
return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourInfo.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
|
return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourContext.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCommands()
|
public void SendCommands()
|
||||||
@@ -743,7 +736,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return new RendererSystemContext
|
return new RendererSystemContext
|
||||||
{
|
{
|
||||||
ChannelCount = _manager.Processor.OutputDevices[_sessionId].GetChannelCount(),
|
ChannelCount = _manager.Processor.OutputDevices[_sessionId].GetChannelCount(),
|
||||||
BehaviourInfo = _behaviourInfo,
|
BehaviourContext = _behaviourContext,
|
||||||
DepopBuffer = _depopBuffer,
|
DepopBuffer = _depopBuffer,
|
||||||
MixBufferCount = GetMixBufferCount(),
|
MixBufferCount = GetMixBufferCount(),
|
||||||
SessionId = _sessionId,
|
SessionId = _sessionId,
|
||||||
@@ -758,9 +751,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
public static ulong GetWorkBufferSize(ref AudioRendererConfiguration parameter)
|
public static ulong GetWorkBufferSize(ref AudioRendererConfiguration parameter)
|
||||||
{
|
{
|
||||||
BehaviourInfo behaviourInfo = new();
|
BehaviourContext behaviourContext = new();
|
||||||
|
|
||||||
behaviourInfo.SetUserRevision(parameter.Revision);
|
behaviourContext.SetUserRevision(parameter.Revision);
|
||||||
|
|
||||||
uint mixesCount = parameter.SubMixBufferCount + 1;
|
uint mixesCount = parameter.SubMixBufferCount + 1;
|
||||||
|
|
||||||
@@ -778,28 +771,28 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
size = WorkBufferAllocator.GetTargetSize<float>(size, BitUtils.AlignUp<ulong>(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
size = WorkBufferAllocator.GetTargetSize<float>(size, BitUtils.AlignUp<ulong>(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
||||||
|
|
||||||
// Voice
|
// Voice
|
||||||
size = WorkBufferAllocator.GetTargetSize<VoiceInfo>(size, parameter.VoiceCount, VoiceInfo.Alignment);
|
size = WorkBufferAllocator.GetTargetSize<VoiceState>(size, parameter.VoiceCount, VoiceState.Alignment);
|
||||||
size = WorkBufferAllocator.GetTargetSize<int>(size, parameter.VoiceCount, 0x10);
|
size = WorkBufferAllocator.GetTargetSize<int>(size, parameter.VoiceCount, 0x10);
|
||||||
size = WorkBufferAllocator.GetTargetSize<VoiceChannelResource>(size, parameter.VoiceCount, VoiceChannelResource.Alignment);
|
size = WorkBufferAllocator.GetTargetSize<VoiceChannelResource>(size, parameter.VoiceCount, VoiceChannelResource.Alignment);
|
||||||
size = WorkBufferAllocator.GetTargetSize<VoiceState>(size, parameter.VoiceCount, VoiceState.Align);
|
size = WorkBufferAllocator.GetTargetSize<VoiceUpdateState>(size, parameter.VoiceCount, VoiceUpdateState.Align);
|
||||||
|
|
||||||
// Mix
|
// Mix
|
||||||
size = WorkBufferAllocator.GetTargetSize<MixInfo>(size, mixesCount, MixInfo.Alignment);
|
size = WorkBufferAllocator.GetTargetSize<MixState>(size, mixesCount, MixState.Alignment);
|
||||||
size = WorkBufferAllocator.GetTargetSize<int>(size, parameter.EffectCount * mixesCount, 0x10);
|
size = WorkBufferAllocator.GetTargetSize<int>(size, parameter.EffectCount * mixesCount, 0x10);
|
||||||
size = WorkBufferAllocator.GetTargetSize<int>(size, mixesCount, 0x10);
|
size = WorkBufferAllocator.GetTargetSize<int>(size, mixesCount, 0x10);
|
||||||
|
|
||||||
if (behaviourInfo.IsSplitterSupported())
|
if (behaviourContext.IsSplitterSupported())
|
||||||
{
|
{
|
||||||
size += (ulong)BitUtils.AlignUp(NodeStates.GetWorkBufferSize((int)mixesCount) + EdgeMatrix.GetWorkBufferSize((int)mixesCount), 0x10);
|
size += (ulong)BitUtils.AlignUp(NodeStates.GetWorkBufferSize((int)mixesCount) + EdgeMatrix.GetWorkBufferSize((int)mixesCount), 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory Pool
|
// Memory Pool
|
||||||
size = WorkBufferAllocator.GetTargetSize<MemoryPoolInfo>(size, memoryPoolCount, MemoryPoolInfo.Alignment);
|
size = WorkBufferAllocator.GetTargetSize<MemoryPoolState>(size, memoryPoolCount, MemoryPoolState.Alignment);
|
||||||
|
|
||||||
// Splitter
|
// Splitter
|
||||||
size = SplitterContext.GetWorkBufferSize(size, ref behaviourInfo, ref parameter);
|
size = SplitterContext.GetWorkBufferSize(size, ref behaviourContext, ref parameter);
|
||||||
|
|
||||||
if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
|
if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
|
||||||
parameter.SplitterCount > 0 &&
|
parameter.SplitterCount > 0 &&
|
||||||
parameter.SplitterDestinationCount > 0)
|
parameter.SplitterDestinationCount > 0)
|
||||||
{
|
{
|
||||||
@@ -807,12 +800,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DSP Voice
|
// DSP Voice
|
||||||
size = WorkBufferAllocator.GetTargetSize<VoiceState>(size, parameter.VoiceCount, VoiceState.Align);
|
size = WorkBufferAllocator.GetTargetSize<VoiceUpdateState>(size, parameter.VoiceCount, VoiceUpdateState.Align);
|
||||||
|
|
||||||
// Performance
|
// Performance
|
||||||
if (parameter.PerformanceMetricFramesCount > 0)
|
if (parameter.PerformanceMetricFramesCount > 0)
|
||||||
{
|
{
|
||||||
ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
||||||
|
|
||||||
size += BitUtils.AlignUp<ulong>(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
|
size += BitUtils.AlignUp<ulong>(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
|
||||||
}
|
}
|
||||||
@@ -854,13 +847,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
PoolMapper mapper = new(_processHandle, false);
|
PoolMapper mapper = new(_processHandle, false);
|
||||||
mapper.Unmap(ref _dspMemoryPoolInfo);
|
mapper.Unmap(ref _dspMemoryPoolState);
|
||||||
|
|
||||||
PoolMapper.ClearUsageState(_memoryPools);
|
PoolMapper.ClearUsageState(_memoryPools);
|
||||||
|
|
||||||
for (int i = 0; i < _memoryPoolCount; i++)
|
for (int i = 0; i < _memoryPoolCount; i++)
|
||||||
{
|
{
|
||||||
ref MemoryPoolInfo memoryPool = ref _memoryPools.Span[i];
|
ref MemoryPoolState memoryPool = ref _memoryPools.Span[i];
|
||||||
|
|
||||||
if (memoryPool.IsMapped())
|
if (memoryPool.IsMapped())
|
||||||
{
|
{
|
||||||
@@ -882,7 +875,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
public void SetVoiceDropParameter(float voiceDropParameter)
|
public void SetVoiceDropParameter(float voiceDropParameter)
|
||||||
{
|
{
|
||||||
_voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 4.0f);
|
_voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetVoiceDropParameter()
|
public float GetVoiceDropParameter()
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using Ryujinx.Audio.Renderer.Parameter;
|
|
||||||
using Ryujinx.Common.Memory;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -11,7 +9,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// Behaviour context.
|
/// Behaviour context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This handles features based on the audio renderer revision provided by the user.</remarks>
|
/// <remarks>This handles features based on the audio renderer revision provided by the user.</remarks>
|
||||||
public class BehaviourInfo
|
public class BehaviourContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The base magic of the Audio Renderer revision.
|
/// The base magic of the Audio Renderer revision.
|
||||||
@@ -42,7 +40,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
public const int Revision4 = 4 << 24;
|
public const int Revision4 = 4 << 24;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// REV5: <see cref="VoiceInParameter1.DecodingBehaviour"/>, <see cref="VoiceInParameter1.FlushWaveBufferCount"/> were added to voice.
|
/// REV5: <see cref="Parameter.VoiceInParameter.DecodingBehaviour"/>, <see cref="Parameter.VoiceInParameter.FlushWaveBufferCount"/> were added to voice.
|
||||||
/// A new performance frame format (version 2) was added with support for more information about DSP timing.
|
/// A new performance frame format (version 2) was added with support for more information about DSP timing.
|
||||||
/// <see cref="Parameter.RendererInfoOutStatus"/> was added to supply the count of update done sent to the DSP.
|
/// <see cref="Parameter.RendererInfoOutStatus"/> was added to supply the count of update done sent to the DSP.
|
||||||
/// A new version of the command estimator was added to address timing changes caused by the voice changes.
|
/// A new version of the command estimator was added to address timing changes caused by the voice changes.
|
||||||
@@ -66,7 +64,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// REV8:
|
/// REV8:
|
||||||
/// Wavebuffer was changed to support more control over loop (you can now specify where to start and end a loop, and how many times to loop).
|
/// Wavebuffer was changed to support more control over loop (you can now specify where to start and end a loop, and how many times to loop).
|
||||||
/// <see cref="VoiceInParameter1.SrcQuality"/> was added (see <see cref="VoiceInParameter1.SampleRateConversionQuality"/> for more info).
|
/// <see cref="Parameter.VoiceInParameter.SrcQuality"/> was added (see <see cref="Parameter.VoiceInParameter.SampleRateConversionQuality"/> for more info).
|
||||||
/// Final leftovers of the codec system were removed.
|
/// Final leftovers of the codec system were removed.
|
||||||
/// <see cref="Common.SampleFormat.PcmFloat"/> support was added.
|
/// <see cref="Common.SampleFormat.PcmFloat"/> support was added.
|
||||||
/// A new version of the command estimator was added to address timing changes caused by the voice and command changes.
|
/// A new version of the command estimator was added to address timing changes caused by the voice and command changes.
|
||||||
@@ -117,27 +115,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This was added in system update 18.0.0</remarks>
|
/// <remarks>This was added in system update 18.0.0</remarks>
|
||||||
public const int Revision13 = 13 << 24;
|
public const int Revision13 = 13 << 24;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// REV14:
|
|
||||||
/// Fixes the Depop Bug.
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This was added in system update 19.0.0 </remarks>
|
|
||||||
public const int Revision14 = 14 << 24;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// REV15:
|
|
||||||
/// Support for float coefficients in biquad filters
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This was added in system update 19.0.0 </remarks>
|
|
||||||
public const int Revision15 = 15 << 24;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Last revision supported by the implementation.
|
/// Last revision supported by the implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int LastRevision = Revision15;
|
public const int LastRevision = Revision13;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target revision magic supported by the implementation.
|
||||||
|
/// </summary>
|
||||||
|
public const int ProcessRevision = BaseRevisionMagic + LastRevision;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the revision number from the revision magic.
|
/// Get the revision number from the revision magic.
|
||||||
@@ -146,25 +133,15 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <returns>The revision number.</returns>
|
/// <returns>The revision number.</returns>
|
||||||
public static int GetRevisionNumber(int revision) => (revision - BaseRevisionMagic) >> 24;
|
public static int GetRevisionNumber(int revision) => (revision - BaseRevisionMagic) >> 24;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Target revision magic supported by the implementation.
|
|
||||||
/// </summary>
|
|
||||||
public const int ProcessRevision = BaseRevisionMagic + LastRevision;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current active revision.
|
/// Current active revision.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int UserRevision { get; private set; }
|
public int UserRevision { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Current flags of the <see cref="BehaviourInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
private ulong _flags;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error storage.
|
/// Error storage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Array10<ErrorInfo> _errorInfos;
|
private readonly ErrorInfo[] _errorInfos;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current position in the <see cref="_errorInfos"/> array.
|
/// Current position in the <see cref="_errorInfos"/> array.
|
||||||
@@ -172,12 +149,17 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
private uint _errorIndex;
|
private uint _errorIndex;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new instance of <see cref="BehaviourInfo"/>.
|
/// Current flags of the <see cref="BehaviourContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BehaviourInfo()
|
private ulong _flags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new instance of <see cref="BehaviourContext"/>.
|
||||||
|
/// </summary>
|
||||||
|
public BehaviourContext()
|
||||||
{
|
{
|
||||||
UserRevision = 0;
|
UserRevision = 0;
|
||||||
_errorInfos = new Array10<ErrorInfo>();
|
_errorInfos = new ErrorInfo[Constants.MaxErrorInfos];
|
||||||
_errorIndex = 0;
|
_errorIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +173,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update flags of the <see cref="BehaviourInfo"/>.
|
/// Update flags of the <see cref="BehaviourContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="flags">The new flags.</param>
|
/// <param name="flags">The new flags.</param>
|
||||||
public void UpdateFlags(ulong flags)
|
public void UpdateFlags(ulong flags)
|
||||||
@@ -339,9 +321,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the audio renderer should support <see cref="VoiceInParameter1.DecodingBehaviour"/>.
|
/// Check if the audio renderer should support <see cref="Parameter.VoiceInParameter.DecodingBehaviour"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if the audio renderer should support <see cref="VoiceInParameter1.DecodingBehaviour"/>.</returns>
|
/// <returns>True if the audio renderer should support <see cref="Parameter.VoiceInParameter.DecodingBehaviour"/>.</returns>
|
||||||
public bool IsDecodingBehaviourFlagSupported()
|
public bool IsDecodingBehaviourFlagSupported()
|
||||||
{
|
{
|
||||||
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision5);
|
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision5);
|
||||||
@@ -418,24 +400,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision13);
|
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision13);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the audio renderer should support the depop bug fix.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the audio renderer supports the depop bug fix</returns>
|
|
||||||
public bool IsSplitterDepopBugFixEnabled()
|
|
||||||
{
|
|
||||||
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision14);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the audio renderer should support biquad filter with float coefficients.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the audio renderer support biquad filter with float coefficients</returns>
|
|
||||||
public bool IsBiquadFilterParameterFloatSupported()
|
|
||||||
{
|
|
||||||
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision15);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the version of the <see cref="ICommandProcessingTimeEstimator"/>.
|
/// Get the version of the <see cref="ICommandProcessingTimeEstimator"/>.
|
||||||
@@ -476,7 +440,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (_errorIndex <= Constants.MaxErrorInfos - 1)
|
if (_errorIndex <= Constants.MaxErrorInfos - 1)
|
||||||
{
|
{
|
||||||
_errorInfos[(int)_errorIndex++] = errorInfo;
|
_errorInfos[_errorIndex++] = errorInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,8 +457,22 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorCount = Math.Min(_errorIndex, Constants.MaxErrorInfos);
|
errorCount = Math.Min(_errorIndex, Constants.MaxErrorInfos);
|
||||||
|
|
||||||
_errorInfos.AsSpan().CopyTo(errorInfos);
|
for (int i = 0; i < Constants.MaxErrorInfos; i++)
|
||||||
|
{
|
||||||
|
if (i < errorCount)
|
||||||
|
{
|
||||||
|
errorInfos[i] = _errorInfos[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorInfos[i] = new ErrorInfo
|
||||||
|
{
|
||||||
|
ErrorCode = 0,
|
||||||
|
ExtraErrorInfo = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -5,10 +5,8 @@ using Ryujinx.Audio.Renderer.Parameter;
|
|||||||
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
||||||
using Ryujinx.Audio.Renderer.Server.Performance;
|
using Ryujinx.Audio.Renderer.Server.Performance;
|
||||||
using Ryujinx.Audio.Renderer.Server.Sink;
|
using Ryujinx.Audio.Renderer.Server.Sink;
|
||||||
using Ryujinx.Audio.Renderer.Server.Splitter;
|
|
||||||
using Ryujinx.Audio.Renderer.Server.Upsampler;
|
using Ryujinx.Audio.Renderer.Server.Upsampler;
|
||||||
using Ryujinx.Audio.Renderer.Server.Voice;
|
using Ryujinx.Audio.Renderer.Server.Voice;
|
||||||
using Ryujinx.Common;
|
|
||||||
using System;
|
using System;
|
||||||
using CpuAddress = System.UInt64;
|
using CpuAddress = System.UInt64;
|
||||||
|
|
||||||
@@ -34,162 +32,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public CommandList CommandList { get; }
|
public CommandList CommandList { get; }
|
||||||
|
|
||||||
private readonly static ObjectPool<PcmInt16DataSourceCommandVersion1> _pcmInt16DataSourceCommandVersion1Pool = new(() => new PcmInt16DataSourceCommandVersion1());
|
|
||||||
private readonly static ObjectPool<PcmFloatDataSourceCommandVersion1> _pcmFloatDataSourceCommandVersion1Pool = new(() => new PcmFloatDataSourceCommandVersion1());
|
|
||||||
private readonly static ObjectPool<AdpcmDataSourceCommandVersion1> _adpcmDataSourceCommandVersion1Pool = new(() => new AdpcmDataSourceCommandVersion1());
|
|
||||||
private readonly static ObjectPool<DataSourceVersion2Command> _dataSourceVersion2CommandPool = new(() => new DataSourceVersion2Command());
|
|
||||||
private readonly static ObjectPool<VolumeCommand> _volumeCommandPool = new(() => new VolumeCommand());
|
|
||||||
private readonly static ObjectPool<VolumeRampCommand> _volumeRampCommandPool = new(() => new VolumeRampCommand());
|
|
||||||
private readonly static ObjectPool<BiquadFilterCommand> _biquadFilterCommandPool = new(() => new BiquadFilterCommand());
|
|
||||||
private readonly static ObjectPool<MixCommand> _mixCommandPool = new(() => new MixCommand());
|
|
||||||
private readonly static ObjectPool<MixRampCommand> _mixRampCommandPool = new(() => new MixRampCommand());
|
|
||||||
private readonly static ObjectPool<MixRampGroupedCommand> _mixRampGroupedCommandPool = new(() => new MixRampGroupedCommand());
|
|
||||||
private readonly static ObjectPool<DepopPrepareCommand> _depopPrepareCommandPool = new(() => new DepopPrepareCommand());
|
|
||||||
private readonly static ObjectPool<DepopForMixBuffersCommand> _depopForMixBuffersCommandPool = new(() => new DepopForMixBuffersCommand());
|
|
||||||
private readonly static ObjectPool<DelayCommand> _delayCommandPool = new(() => new DelayCommand());
|
|
||||||
private readonly static ObjectPool<UpsampleCommand> _upsampleCommandPool = new(() => new UpsampleCommand());
|
|
||||||
private readonly static ObjectPool<DownMixSurroundToStereoCommand> _downMixSurroundToStereoCommandPool = new(() => new DownMixSurroundToStereoCommand());
|
|
||||||
private readonly static ObjectPool<AuxiliaryBufferCommand> _auxiliaryBufferCommandPool = new(() => new AuxiliaryBufferCommand());
|
|
||||||
private readonly static ObjectPool<DeviceSinkCommand> _deviceSinkCommandPool = new(() => new DeviceSinkCommand());
|
|
||||||
private readonly static ObjectPool<CircularBufferSinkCommand> _circularBufferSinkCommandPool = new(() => new CircularBufferSinkCommand());
|
|
||||||
private readonly static ObjectPool<ReverbCommand> _reverbCommandPool = new(() => new ReverbCommand());
|
|
||||||
private readonly static ObjectPool<Reverb3dCommand> _reverb3dCommandPool = new(() => new Reverb3dCommand());
|
|
||||||
private readonly static ObjectPool<PerformanceCommand> _performanceCommandPool = new(() => new PerformanceCommand());
|
|
||||||
private readonly static ObjectPool<ClearMixBufferCommand> _clearMixBufferCommandPool = new(() => new ClearMixBufferCommand());
|
|
||||||
private readonly static ObjectPool<CopyMixBufferCommand> _copyMixBufferCommandPool = new(() => new CopyMixBufferCommand());
|
|
||||||
private readonly static ObjectPool<LimiterCommandVersion1> _limiterCommandVersion1Pool = new(() => new LimiterCommandVersion1());
|
|
||||||
private readonly static ObjectPool<LimiterCommandVersion2> _limiterCommandVersion2Pool = new(() => new LimiterCommandVersion2());
|
|
||||||
private readonly static ObjectPool<MultiTapBiquadFilterCommand> _multiTapBiquadFilterCommandPool = new(() => new MultiTapBiquadFilterCommand());
|
|
||||||
private readonly static ObjectPool<CaptureBufferCommand> _captureBufferCommandPool = new(() => new CaptureBufferCommand());
|
|
||||||
private readonly static ObjectPool<CompressorCommand> _compressorCommandPool = new(() => new CompressorCommand());
|
|
||||||
private readonly static ObjectPool<BiquadFilterAndMixCommand> _biquadFilterAndMixCommandPool = new(() => new BiquadFilterAndMixCommand());
|
|
||||||
private readonly static ObjectPool<MultiTapBiquadFilterAndMixCommand> _multiTapBiquadFilterAndMixCommandPool = new(() => new MultiTapBiquadFilterAndMixCommand());
|
|
||||||
private readonly static ObjectPool<FillBufferCommand> _fillBufferCommandPool = new(() => new FillBufferCommand());
|
|
||||||
|
|
||||||
public static void ReleaseCommand(ICommand command)
|
|
||||||
{
|
|
||||||
switch (command.CommandType)
|
|
||||||
{
|
|
||||||
case CommandType.PcmInt16DataSourceVersion1:
|
|
||||||
_pcmInt16DataSourceCommandVersion1Pool.Release((PcmInt16DataSourceCommandVersion1)command);
|
|
||||||
break;
|
|
||||||
case CommandType.PcmInt16DataSourceVersion2:
|
|
||||||
_dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command);
|
|
||||||
break;
|
|
||||||
case CommandType.PcmFloatDataSourceVersion1:
|
|
||||||
_pcmFloatDataSourceCommandVersion1Pool.Release((PcmFloatDataSourceCommandVersion1)command);
|
|
||||||
break;
|
|
||||||
case CommandType.PcmFloatDataSourceVersion2:
|
|
||||||
_dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command);
|
|
||||||
break;
|
|
||||||
case CommandType.AdpcmDataSourceVersion1:
|
|
||||||
_adpcmDataSourceCommandVersion1Pool.Release((AdpcmDataSourceCommandVersion1)command);
|
|
||||||
break;
|
|
||||||
case CommandType.AdpcmDataSourceVersion2:
|
|
||||||
_dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Volume:
|
|
||||||
_volumeCommandPool.Release((VolumeCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.VolumeRamp:
|
|
||||||
_volumeRampCommandPool.Release((VolumeRampCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.BiquadFilter:
|
|
||||||
_biquadFilterCommandPool.Release((BiquadFilterCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.BiquadFilterFloatCoeff:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.Mix:
|
|
||||||
_mixCommandPool.Release((MixCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.MixRamp:
|
|
||||||
_mixRampCommandPool.Release((MixRampCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.MixRampGrouped:
|
|
||||||
_mixRampGroupedCommandPool.Release((MixRampGroupedCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.DepopPrepare:
|
|
||||||
_depopPrepareCommandPool.Release((DepopPrepareCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.DepopForMixBuffers:
|
|
||||||
_depopForMixBuffersCommandPool.Release((DepopForMixBuffersCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Delay:
|
|
||||||
_delayCommandPool.Release((DelayCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Upsample:
|
|
||||||
_upsampleCommandPool.Release((UpsampleCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.DownMixSurroundToStereo:
|
|
||||||
_downMixSurroundToStereoCommandPool.Release((DownMixSurroundToStereoCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.AuxiliaryBuffer:
|
|
||||||
_auxiliaryBufferCommandPool.Release((AuxiliaryBufferCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.DeviceSink:
|
|
||||||
_deviceSinkCommandPool.Release((DeviceSinkCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.CircularBufferSink:
|
|
||||||
_circularBufferSinkCommandPool.Release((CircularBufferSinkCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Reverb:
|
|
||||||
_reverbCommandPool.Release((ReverbCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Reverb3d:
|
|
||||||
_reverb3dCommandPool.Release((Reverb3dCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Performance:
|
|
||||||
_performanceCommandPool.Release((PerformanceCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.ClearMixBuffer:
|
|
||||||
_clearMixBufferCommandPool.Release((ClearMixBufferCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.CopyMixBuffer:
|
|
||||||
_copyMixBufferCommandPool.Release((CopyMixBufferCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.LimiterVersion1:
|
|
||||||
_limiterCommandVersion1Pool.Release((LimiterCommandVersion1)command);
|
|
||||||
break;
|
|
||||||
case CommandType.LimiterVersion2:
|
|
||||||
_limiterCommandVersion2Pool.Release((LimiterCommandVersion2)command);
|
|
||||||
break;
|
|
||||||
case CommandType.MultiTapBiquadFilter:
|
|
||||||
_multiTapBiquadFilterCommandPool.Release((MultiTapBiquadFilterCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.MultiTapBiquadFilterFloatCoeff:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.CaptureBuffer:
|
|
||||||
_captureBufferCommandPool.Release((CaptureBufferCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.Compressor:
|
|
||||||
_compressorCommandPool.Release((CompressorCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.BiquadFilterAndMix:
|
|
||||||
_biquadFilterAndMixCommandPool.Release((BiquadFilterAndMixCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.BiquadFilterAndMixFloatCoeff:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.MultiTapBiquadFilterAndMix:
|
|
||||||
_multiTapBiquadFilterAndMixCommandPool.Release((MultiTapBiquadFilterAndMixCommand)command);
|
|
||||||
break;
|
|
||||||
case CommandType.MultiTapBiquadFilterAndMixFloatCoef:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.AuxiliaryBufferGrouped:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.FillMixBuffer:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.BiquadFilterCrossFade:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.MultiTapBiquadFilterCrossFade:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
case CommandType.FillBuffer:
|
|
||||||
_fillBufferCommandPool.Release((FillBufferCommand)command);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="CommandBuffer"/>.
|
/// Create a new <see cref="CommandBuffer"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -219,7 +61,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateClearMixBuffer(int nodeId)
|
public void GenerateClearMixBuffer(int nodeId)
|
||||||
{
|
{
|
||||||
ClearMixBufferCommand command = _clearMixBufferCommandPool.Allocate().Initialize(nodeId);
|
ClearMixBufferCommand command = new(nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -235,9 +77,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="bufferOffset">The target buffer offset.</param>
|
/// <param name="bufferOffset">The target buffer offset.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
/// <param name="wasPlaying">Set to true if the voice was playing previously.</param>
|
/// <param name="wasPlaying">Set to true if the voice was playing previously.</param>
|
||||||
public void GenerateDepopPrepare(Memory<VoiceState> state, Memory<float> depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
|
public void GenerateDepopPrepare(Memory<VoiceUpdateState> state, Memory<float> depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
|
||||||
{
|
{
|
||||||
DepopPrepareCommand command = _depopPrepareCommandPool.Allocate().Initialize(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying);
|
DepopPrepareCommand command = new(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -252,7 +94,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GeneratePerformance(ref PerformanceEntryAddresses performanceEntryAddresses, PerformanceCommand.Type type, int nodeId)
|
public void GeneratePerformance(ref PerformanceEntryAddresses performanceEntryAddresses, PerformanceCommand.Type type, int nodeId)
|
||||||
{
|
{
|
||||||
PerformanceCommand command = _performanceCommandPool.Allocate().Initialize(ref performanceEntryAddresses, type, nodeId);
|
PerformanceCommand command = new(ref performanceEntryAddresses, type, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -268,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateVolumeRamp(float previousVolume, float volume, uint bufferIndex, int nodeId)
|
public void GenerateVolumeRamp(float previousVolume, float volume, uint bufferIndex, int nodeId)
|
||||||
{
|
{
|
||||||
VolumeRampCommand command = _volumeRampCommandPool.Allocate().Initialize(previousVolume, volume, bufferIndex, nodeId);
|
VolumeRampCommand command = new(previousVolume, volume, bufferIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -278,14 +120,14 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="DataSourceVersion2Command"/>.
|
/// Create a new <see cref="DataSourceVersion2Command"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="voiceInfo">The <see cref="VoiceInfo"/> to generate the command from.</param>
|
/// <param name="voiceState">The <see cref="VoiceState"/> to generate the command from.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
||||||
/// <param name="channelIndex">The target channel index.</param>
|
/// <param name="channelIndex">The target channel index.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateDataSourceVersion2(ref VoiceInfo voiceInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
public void GenerateDataSourceVersion2(ref VoiceState voiceState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
{
|
||||||
DataSourceVersion2Command command = _dataSourceVersion2CommandPool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
|
DataSourceVersion2Command command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -295,14 +137,14 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="PcmInt16DataSourceCommandVersion1"/>.
|
/// Create a new <see cref="PcmInt16DataSourceCommandVersion1"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="voiceInfo">The <see cref="VoiceInfo"/> to generate the command from.</param>
|
/// <param name="voiceState">The <see cref="VoiceState"/> to generate the command from.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
||||||
/// <param name="channelIndex">The target channel index.</param>
|
/// <param name="channelIndex">The target channel index.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GeneratePcmInt16DataSourceVersion1(ref VoiceInfo voiceInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
public void GeneratePcmInt16DataSourceVersion1(ref VoiceState voiceState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
{
|
||||||
PcmInt16DataSourceCommandVersion1 command = _pcmInt16DataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
|
PcmInt16DataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -312,14 +154,14 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="PcmFloatDataSourceCommandVersion1"/>.
|
/// Create a new <see cref="PcmFloatDataSourceCommandVersion1"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="voiceInfo">The <see cref="VoiceInfo"/> to generate the command from.</param>
|
/// <param name="voiceState">The <see cref="VoiceState"/> to generate the command from.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
||||||
/// <param name="channelIndex">The target channel index.</param>
|
/// <param name="channelIndex">The target channel index.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GeneratePcmFloatDataSourceVersion1(ref VoiceInfo voiceInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
public void GeneratePcmFloatDataSourceVersion1(ref VoiceState voiceState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
{
|
||||||
PcmFloatDataSourceCommandVersion1 command = _pcmFloatDataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
|
PcmFloatDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -329,13 +171,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="AdpcmDataSourceCommandVersion1"/>.
|
/// Create a new <see cref="AdpcmDataSourceCommandVersion1"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="voiceInfo">The <see cref="VoiceInfo"/> to generate the command from.</param>
|
/// <param name="voiceState">The <see cref="VoiceState"/> to generate the command from.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
/// <param name="outputBufferIndex">The output buffer index to use.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateAdpcmDataSourceVersion1(ref VoiceInfo voiceInfo, Memory<VoiceState> state, ushort outputBufferIndex, int nodeId)
|
public void GenerateAdpcmDataSourceVersion1(ref VoiceState voiceState, Memory<VoiceUpdateState> state, ushort outputBufferIndex, int nodeId)
|
||||||
{
|
{
|
||||||
AdpcmDataSourceCommandVersion1 command = _adpcmDataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, nodeId);
|
AdpcmDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -352,9 +194,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="outputBufferOffset">The output buffer offset.</param>
|
/// <param name="outputBufferOffset">The output buffer offset.</param>
|
||||||
/// <param name="needInitialization">Set to true if the biquad filter state needs to be initialized.</param>
|
/// <param name="needInitialization">Set to true if the biquad filter state needs to be initialized.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter2 filter, Memory<BiquadFilterState> biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId)
|
public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter filter, Memory<BiquadFilterState> biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId)
|
||||||
{
|
{
|
||||||
BiquadFilterCommand command = _biquadFilterCommandPool.Allocate().Initialize(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId);
|
BiquadFilterCommand command = new(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -371,9 +213,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="outputBufferOffset">The output buffer offset.</param>
|
/// <param name="outputBufferOffset">The output buffer offset.</param>
|
||||||
/// <param name="isInitialized">Set to true if the biquad filter state is initialized.</param>
|
/// <param name="isInitialized">Set to true if the biquad filter state is initialized.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan<BiquadFilterParameter2> filters, Memory<BiquadFilterState> biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan<bool> isInitialized, int nodeId)
|
public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan<BiquadFilterParameter> filters, Memory<BiquadFilterState> biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan<bool> isInitialized, int nodeId)
|
||||||
{
|
{
|
||||||
MultiTapBiquadFilterCommand command = _multiTapBiquadFilterCommandPool.Allocate().Initialize(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId);
|
MultiTapBiquadFilterCommand command = new(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -388,11 +230,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="outputBufferIndex">The base output index.</param>
|
/// <param name="outputBufferIndex">The base output index.</param>
|
||||||
/// <param name="previousVolume">The previous volume.</param>
|
/// <param name="previousVolume">The previous volume.</param>
|
||||||
/// <param name="volume">The new volume.</param>
|
/// <param name="volume">The new volume.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan<float> previousVolume, ReadOnlySpan<float> volume, Memory<VoiceState> state, int nodeId)
|
public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan<float> previousVolume, ReadOnlySpan<float> volume, Memory<VoiceUpdateState> state, int nodeId)
|
||||||
{
|
{
|
||||||
MixRampGroupedCommand command = _mixRampGroupedCommandPool.Allocate().Initialize(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId);
|
MixRampGroupedCommand command = new(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -406,12 +248,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="volume">The new volume.</param>
|
/// <param name="volume">The new volume.</param>
|
||||||
/// <param name="inputBufferIndex">The input buffer index.</param>
|
/// <param name="inputBufferIndex">The input buffer index.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index.</param>
|
/// <param name="outputBufferIndex">The output buffer index.</param>
|
||||||
/// <param name="lastSampleIndex">The index in the <see cref="VoiceState.LastSamples"/> array to store the ramped sample.</param>
|
/// <param name="lastSampleIndex">The index in the <see cref="VoiceUpdateState.LastSamples"/> array to store the ramped sample.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory<VoiceState> state, int nodeId)
|
public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory<VoiceUpdateState> state, int nodeId)
|
||||||
{
|
{
|
||||||
MixRampCommand command = _mixRampCommandPool.Allocate().Initialize(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId);
|
MixRampCommand command = new(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -425,8 +267,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="volume">The new volume.</param>
|
/// <param name="volume">The new volume.</param>
|
||||||
/// <param name="inputBufferIndex">The input buffer index.</param>
|
/// <param name="inputBufferIndex">The input buffer index.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index.</param>
|
/// <param name="outputBufferIndex">The output buffer index.</param>
|
||||||
/// <param name="lastSampleIndex">The index in the <see cref="VoiceState.LastSamples"/> array to store the ramped sample.</param>
|
/// <param name="lastSampleIndex">The index in the <see cref="VoiceUpdateState.LastSamples"/> array to store the ramped sample.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="filter">The biquad filter parameter.</param>
|
/// <param name="filter">The biquad filter parameter.</param>
|
||||||
/// <param name="biquadFilterState">The biquad state.</param>
|
/// <param name="biquadFilterState">The biquad state.</param>
|
||||||
/// <param name="previousBiquadFilterState">The previous biquad state.</param>
|
/// <param name="previousBiquadFilterState">The previous biquad state.</param>
|
||||||
@@ -440,8 +282,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
uint outputBufferIndex,
|
uint outputBufferIndex,
|
||||||
int lastSampleIndex,
|
int lastSampleIndex,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
ref BiquadFilterParameter2 filter,
|
ref BiquadFilterParameter filter,
|
||||||
Memory<BiquadFilterState> biquadFilterState,
|
Memory<BiquadFilterState> biquadFilterState,
|
||||||
Memory<BiquadFilterState> previousBiquadFilterState,
|
Memory<BiquadFilterState> previousBiquadFilterState,
|
||||||
bool needInitialization,
|
bool needInitialization,
|
||||||
@@ -449,7 +291,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
bool isFirstMixBuffer,
|
bool isFirstMixBuffer,
|
||||||
int nodeId)
|
int nodeId)
|
||||||
{
|
{
|
||||||
BiquadFilterAndMixCommand command = _biquadFilterAndMixCommandPool.Allocate().Initialize(
|
BiquadFilterAndMixCommand command = new(
|
||||||
previousVolume,
|
previousVolume,
|
||||||
volume,
|
volume,
|
||||||
inputBufferIndex,
|
inputBufferIndex,
|
||||||
@@ -476,8 +318,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="volume">The new volume.</param>
|
/// <param name="volume">The new volume.</param>
|
||||||
/// <param name="inputBufferIndex">The input buffer index.</param>
|
/// <param name="inputBufferIndex">The input buffer index.</param>
|
||||||
/// <param name="outputBufferIndex">The output buffer index.</param>
|
/// <param name="outputBufferIndex">The output buffer index.</param>
|
||||||
/// <param name="lastSampleIndex">The index in the <see cref="VoiceState.LastSamples"/> array to store the ramped sample.</param>
|
/// <param name="lastSampleIndex">The index in the <see cref="VoiceUpdateState.LastSamples"/> array to store the ramped sample.</param>
|
||||||
/// <param name="state">The <see cref="VoiceState"/> to generate the command from.</param>
|
/// <param name="state">The <see cref="VoiceUpdateState"/> to generate the command from.</param>
|
||||||
/// <param name="filter0">First biquad filter parameter.</param>
|
/// <param name="filter0">First biquad filter parameter.</param>
|
||||||
/// <param name="filter1">Second biquad filter parameter.</param>
|
/// <param name="filter1">Second biquad filter parameter.</param>
|
||||||
/// <param name="biquadFilterState0">First biquad state.</param>
|
/// <param name="biquadFilterState0">First biquad state.</param>
|
||||||
@@ -495,9 +337,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
uint outputBufferIndex,
|
uint outputBufferIndex,
|
||||||
int lastSampleIndex,
|
int lastSampleIndex,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
ref BiquadFilterParameter2 filter0,
|
ref BiquadFilterParameter filter0,
|
||||||
ref BiquadFilterParameter2 filter1,
|
ref BiquadFilterParameter filter1,
|
||||||
Memory<BiquadFilterState> biquadFilterState0,
|
Memory<BiquadFilterState> biquadFilterState0,
|
||||||
Memory<BiquadFilterState> biquadFilterState1,
|
Memory<BiquadFilterState> biquadFilterState1,
|
||||||
Memory<BiquadFilterState> previousBiquadFilterState0,
|
Memory<BiquadFilterState> previousBiquadFilterState0,
|
||||||
@@ -508,7 +350,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
bool isFirstMixBuffer,
|
bool isFirstMixBuffer,
|
||||||
int nodeId)
|
int nodeId)
|
||||||
{
|
{
|
||||||
MultiTapBiquadFilterAndMixCommand command = _multiTapBiquadFilterAndMixCommandPool.Allocate().Initialize(
|
MultiTapBiquadFilterAndMixCommand command = new(
|
||||||
previousVolume,
|
previousVolume,
|
||||||
volume,
|
volume,
|
||||||
inputBufferIndex,
|
inputBufferIndex,
|
||||||
@@ -542,7 +384,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="sampleRate">The target sample rate in use.</param>
|
/// <param name="sampleRate">The target sample rate in use.</param>
|
||||||
public void GenerateDepopForMixBuffers(Memory<float> depopBuffer, uint bufferOffset, uint bufferCount, int nodeId, uint sampleRate)
|
public void GenerateDepopForMixBuffers(Memory<float> depopBuffer, uint bufferOffset, uint bufferCount, int nodeId, uint sampleRate)
|
||||||
{
|
{
|
||||||
DepopForMixBuffersCommand command = _depopForMixBuffersCommandPool.Allocate().Initialize(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate);
|
DepopForMixBuffersCommand command = new(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -557,7 +399,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateCopyMixBuffer(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
public void GenerateCopyMixBuffer(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
||||||
{
|
{
|
||||||
CopyMixBufferCommand command = _copyMixBufferCommandPool.Allocate().Initialize(inputBufferIndex, outputBufferIndex, nodeId);
|
CopyMixBufferCommand command = new(inputBufferIndex, outputBufferIndex, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -573,7 +415,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="volume">The mix volume.</param>
|
/// <param name="volume">The mix volume.</param>
|
||||||
public void GenerateMix(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume)
|
public void GenerateMix(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume)
|
||||||
{
|
{
|
||||||
MixCommand command = _mixCommandPool.Allocate().Initialize(inputBufferIndex, outputBufferIndex, nodeId, volume);
|
MixCommand command = new(inputBufferIndex, outputBufferIndex, nodeId, volume);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -595,7 +437,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
ReverbCommand command = _reverbCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported);
|
ReverbCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -617,7 +459,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
Reverb3dCommand command = _reverb3dCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
|
Reverb3dCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -639,7 +481,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
DelayCommand command = _delayCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
|
DelayCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -660,7 +502,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
LimiterCommandVersion1 command = _limiterCommandVersion1Pool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId);
|
LimiterCommandVersion1 command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -682,7 +524,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
LimiterCommandVersion2 command = _limiterCommandVersion2Pool.Allocate().Initialize(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId);
|
LimiterCommandVersion2 command = new(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -708,7 +550,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (state.SendBufferInfoBase != 0 && state.ReturnBufferInfoBase != 0)
|
if (state.SendBufferInfoBase != 0 && state.ReturnBufferInfoBase != 0)
|
||||||
{
|
{
|
||||||
AuxiliaryBufferCommand command = _auxiliaryBufferCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId);
|
AuxiliaryBufferCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -732,7 +574,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (sendBufferInfo != 0)
|
if (sendBufferInfo != 0)
|
||||||
{
|
{
|
||||||
CaptureBufferCommand command = _captureBufferCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId);
|
CaptureBufferCommand command = new(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -753,7 +595,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
if (parameter.IsChannelCountValid())
|
if (parameter.IsChannelCountValid())
|
||||||
{
|
{
|
||||||
CompressorCommand command = _compressorCommandPool.Allocate().Initialize(bufferOffset, parameter, state, effectResultState, isEnabled, nodeId);
|
CompressorCommand command = new(bufferOffset, parameter, state, effectResultState, isEnabled, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -769,7 +611,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateVolume(float volume, uint bufferOffset, int nodeId)
|
public void GenerateVolume(float volume, uint bufferOffset, int nodeId)
|
||||||
{
|
{
|
||||||
VolumeCommand command = _volumeCommandPool.Allocate().Initialize(volume, bufferOffset, nodeId);
|
VolumeCommand command = new(volume, bufferOffset, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -784,7 +626,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateCircularBuffer(uint bufferOffset, CircularBufferSink sink, int nodeId)
|
public void GenerateCircularBuffer(uint bufferOffset, CircularBufferSink sink, int nodeId)
|
||||||
{
|
{
|
||||||
CircularBufferSinkCommand command = _circularBufferSinkCommandPool.Allocate().Initialize(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId);
|
CircularBufferSinkCommand command = new(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -801,7 +643,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateDownMixSurroundToStereo(uint bufferOffset, Span<byte> inputBufferOffset, Span<byte> outputBufferOffset, float[] downMixParameter, int nodeId)
|
public void GenerateDownMixSurroundToStereo(uint bufferOffset, Span<byte> inputBufferOffset, Span<byte> outputBufferOffset, float[] downMixParameter, int nodeId)
|
||||||
{
|
{
|
||||||
DownMixSurroundToStereoCommand command = _downMixSurroundToStereoCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId);
|
DownMixSurroundToStereoCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -812,16 +654,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// Create a new <see cref="UpsampleCommand"/>.
|
/// Create a new <see cref="UpsampleCommand"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bufferOffset">The offset of the mix buffer.</param>
|
/// <param name="bufferOffset">The offset of the mix buffer.</param>
|
||||||
/// <param name="upsampler">The <see cref="UpsamplerInfo"/> associated.</param>
|
/// <param name="upsampler">The <see cref="UpsamplerState"/> associated.</param>
|
||||||
/// <param name="inputCount">The total input count.</param>
|
/// <param name="inputCount">The total input count.</param>
|
||||||
/// <param name="inputBufferOffset">The input buffer mix offset.</param>
|
/// <param name="inputBufferOffset">The input buffer mix offset.</param>
|
||||||
/// <param name="bufferCountPerSample">The buffer count per sample.</param>
|
/// <param name="bufferCountPerSample">The buffer count per sample.</param>
|
||||||
/// <param name="sampleCount">The source sample count.</param>
|
/// <param name="sampleCount">The source sample count.</param>
|
||||||
/// <param name="sampleRate">The source sample rate.</param>
|
/// <param name="sampleRate">The source sample rate.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateUpsample(uint bufferOffset, UpsamplerInfo upsampler, uint inputCount, Span<byte> inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId)
|
public void GenerateUpsample(uint bufferOffset, UpsamplerState upsampler, uint inputCount, Span<byte> inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId)
|
||||||
{
|
{
|
||||||
UpsampleCommand command = _upsampleCommandPool.Allocate().Initialize(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId);
|
UpsampleCommand command = new(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
@@ -838,20 +680,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <param name="nodeId">The node id associated to this command.</param>
|
/// <param name="nodeId">The node id associated to this command.</param>
|
||||||
public void GenerateDeviceSink(uint bufferOffset, DeviceSink sink, int sessionId, Memory<float> buffer, int nodeId)
|
public void GenerateDeviceSink(uint bufferOffset, DeviceSink sink, int sessionId, Memory<float> buffer, int nodeId)
|
||||||
{
|
{
|
||||||
DeviceSinkCommand command = _deviceSinkCommandPool.Allocate().Initialize(bufferOffset, sink, sessionId, buffer, nodeId);
|
DeviceSinkCommand command = new(bufferOffset, sink, sessionId, buffer, nodeId);
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
AddCommand(command);
|
AddCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateFillBuffer(SplitterDestination destination, float value, int length, int nodeId)
|
|
||||||
{
|
|
||||||
FillBufferCommand command = _fillBufferCommandPool.Allocate().Initialize(destination, length, value, nodeId);
|
|
||||||
|
|
||||||
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
|
||||||
|
|
||||||
AddCommand(command);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,27 +41,27 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
_commandBuffer.GenerateClearMixBuffer(Constants.InvalidNodeId);
|
_commandBuffer.GenerateClearMixBuffer(Constants.InvalidNodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateDataSource(ref VoiceInfo voiceInfo, Memory<VoiceState> dspState, int channelIndex)
|
private void GenerateDataSource(ref VoiceState voiceState, Memory<VoiceUpdateState> dspState, int channelIndex)
|
||||||
{
|
{
|
||||||
if (voiceInfo.MixId != Constants.UnusedMixId)
|
if (voiceState.MixId != Constants.UnusedMixId)
|
||||||
{
|
{
|
||||||
ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
|
ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
|
||||||
|
|
||||||
_commandBuffer.GenerateDepopPrepare(
|
_commandBuffer.GenerateDepopPrepare(
|
||||||
dspState,
|
dspState,
|
||||||
_rendererContext.DepopBuffer,
|
_rendererContext.DepopBuffer,
|
||||||
mix.BufferCount,
|
mix.BufferCount,
|
||||||
mix.BufferOffset,
|
mix.BufferOffset,
|
||||||
voiceInfo.NodeId,
|
voiceState.NodeId,
|
||||||
voiceInfo.WasPlaying);
|
voiceState.WasPlaying);
|
||||||
}
|
}
|
||||||
else if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
|
else if (voiceState.SplitterId != Constants.UnusedSplitterId)
|
||||||
{
|
{
|
||||||
int destinationId = 0;
|
int destinationId = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId++);
|
SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId++);
|
||||||
|
|
||||||
if (destination.IsNull)
|
if (destination.IsNull)
|
||||||
{
|
{
|
||||||
@@ -74,17 +74,15 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||||
{
|
{
|
||||||
ref MixInfo mix = ref _mixContext.GetState(mixId);
|
ref MixState mix = ref _mixContext.GetState(mixId);
|
||||||
|
|
||||||
// _commandBuffer.GenerateFillBuffer();
|
|
||||||
|
|
||||||
_commandBuffer.GenerateDepopPrepare(
|
_commandBuffer.GenerateDepopPrepare(
|
||||||
dspState,
|
dspState,
|
||||||
_rendererContext.DepopBuffer,
|
_rendererContext.DepopBuffer,
|
||||||
mix.BufferCount,
|
mix.BufferCount,
|
||||||
mix.BufferOffset,
|
mix.BufferOffset,
|
||||||
voiceInfo.NodeId,
|
voiceState.NodeId,
|
||||||
voiceInfo.WasPlaying);
|
voiceState.WasPlaying);
|
||||||
|
|
||||||
destination.MarkAsNeedToUpdateInternalState();
|
destination.MarkAsNeedToUpdateInternalState();
|
||||||
}
|
}
|
||||||
@@ -92,71 +90,69 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!voiceInfo.WasPlaying)
|
if (!voiceState.WasPlaying)
|
||||||
{
|
{
|
||||||
Debug.Assert(voiceInfo.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
|
Debug.Assert(voiceState.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
|
||||||
|
|
||||||
if (_rendererContext.BehaviourInfo.IsWaveBufferVersion2Supported())
|
if (_rendererContext.BehaviourContext.IsWaveBufferVersion2Supported())
|
||||||
{
|
{
|
||||||
_commandBuffer.GenerateDataSourceVersion2(
|
_commandBuffer.GenerateDataSourceVersion2(
|
||||||
ref voiceInfo,
|
ref voiceState,
|
||||||
dspState,
|
dspState,
|
||||||
(ushort)_rendererContext.MixBufferCount,
|
(ushort)_rendererContext.MixBufferCount,
|
||||||
(ushort)channelIndex,
|
(ushort)channelIndex,
|
||||||
voiceInfo.NodeId);
|
voiceState.NodeId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (voiceInfo.SampleFormat)
|
switch (voiceState.SampleFormat)
|
||||||
{
|
{
|
||||||
case SampleFormat.PcmInt16:
|
case SampleFormat.PcmInt16:
|
||||||
_commandBuffer.GeneratePcmInt16DataSourceVersion1(
|
_commandBuffer.GeneratePcmInt16DataSourceVersion1(
|
||||||
ref voiceInfo,
|
ref voiceState,
|
||||||
dspState,
|
dspState,
|
||||||
(ushort)_rendererContext.MixBufferCount,
|
(ushort)_rendererContext.MixBufferCount,
|
||||||
(ushort)channelIndex,
|
(ushort)channelIndex,
|
||||||
voiceInfo.NodeId);
|
voiceState.NodeId);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.PcmFloat:
|
case SampleFormat.PcmFloat:
|
||||||
_commandBuffer.GeneratePcmFloatDataSourceVersion1(
|
_commandBuffer.GeneratePcmFloatDataSourceVersion1(
|
||||||
ref voiceInfo,
|
ref voiceState,
|
||||||
dspState,
|
dspState,
|
||||||
(ushort)_rendererContext.MixBufferCount,
|
(ushort)_rendererContext.MixBufferCount,
|
||||||
(ushort)channelIndex,
|
(ushort)channelIndex,
|
||||||
voiceInfo.NodeId);
|
voiceState.NodeId);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.Adpcm:
|
case SampleFormat.Adpcm:
|
||||||
_commandBuffer.GenerateAdpcmDataSourceVersion1(
|
_commandBuffer.GenerateAdpcmDataSourceVersion1(
|
||||||
ref voiceInfo,
|
ref voiceState,
|
||||||
dspState,
|
dspState,
|
||||||
(ushort)_rendererContext.MixBufferCount,
|
(ushort)_rendererContext.MixBufferCount,
|
||||||
voiceInfo.NodeId);
|
voiceState.NodeId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Unsupported data source {voiceInfo.SampleFormat}");
|
throw new NotImplementedException($"Unsupported data source {voiceState.SampleFormat}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateBiquadFilterForVoice(ref VoiceInfo voiceInfo, Memory<VoiceState> state, int baseIndex, int bufferOffset, int nodeId)
|
private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory<VoiceUpdateState> state, int baseIndex, int bufferOffset, int nodeId)
|
||||||
{
|
{
|
||||||
bool supportsOptimizedPath = _rendererContext.BehaviourInfo.UseMultiTapBiquadFilterProcessing();
|
bool supportsOptimizedPath = _rendererContext.BehaviourContext.UseMultiTapBiquadFilterProcessing();
|
||||||
|
|
||||||
Span<BiquadFilterParameter2> biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
|
if (supportsOptimizedPath && voiceState.BiquadFilters[0].Enable && voiceState.BiquadFilters[1].Enable)
|
||||||
|
|
||||||
if (supportsOptimizedPath && biquadFiltersSpan[0].Enable && biquadFiltersSpan[1].Enable)
|
|
||||||
{
|
{
|
||||||
Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state)[..(Unsafe.SizeOf<BiquadFilterState>() * Constants.VoiceBiquadFilterCount)];
|
Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state)[..(Unsafe.SizeOf<BiquadFilterState>() * Constants.VoiceBiquadFilterCount)];
|
||||||
Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory);
|
Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory);
|
||||||
|
|
||||||
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceInfo.BiquadFilterNeedInitialization, nodeId);
|
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, voiceState.BiquadFilters.AsSpan(), stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < biquadFiltersSpan.Length; i++)
|
for (int i = 0; i < voiceState.BiquadFilters.Length; i++)
|
||||||
{
|
{
|
||||||
ref BiquadFilterParameter2 filter = ref biquadFiltersSpan[i];
|
ref BiquadFilterParameter filter = ref voiceState.BiquadFilters[i];
|
||||||
|
|
||||||
if (filter.Enable)
|
if (filter.Enable)
|
||||||
{
|
{
|
||||||
@@ -169,7 +165,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
stateMemory.Slice(i, 1),
|
stateMemory.Slice(i, 1),
|
||||||
bufferOffset,
|
bufferOffset,
|
||||||
bufferOffset,
|
bufferOffset,
|
||||||
!voiceInfo.BiquadFilterNeedInitialization[i],
|
!voiceState.BiquadFilterNeedInitialization[i],
|
||||||
nodeId);
|
nodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +174,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
private void GenerateVoiceMixWithSplitter(
|
private void GenerateVoiceMixWithSplitter(
|
||||||
SplitterDestination destination,
|
SplitterDestination destination,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
uint bufferOffset,
|
uint bufferOffset,
|
||||||
uint bufferCount,
|
uint bufferCount,
|
||||||
uint bufferIndex,
|
uint bufferIndex,
|
||||||
@@ -187,8 +183,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
ReadOnlySpan<float> mixVolumes = destination.MixBufferVolume;
|
ReadOnlySpan<float> mixVolumes = destination.MixBufferVolume;
|
||||||
ReadOnlySpan<float> previousMixVolumes = destination.PreviousMixBufferVolume;
|
ReadOnlySpan<float> previousMixVolumes = destination.PreviousMixBufferVolume;
|
||||||
|
|
||||||
ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
|
ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||||
ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
|
ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||||
|
|
||||||
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
||||||
|
|
||||||
@@ -272,7 +268,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
private void GenerateVoiceMix(
|
private void GenerateVoiceMix(
|
||||||
ReadOnlySpan<float> mixVolumes,
|
ReadOnlySpan<float> mixVolumes,
|
||||||
ReadOnlySpan<float> previousMixVolumes,
|
ReadOnlySpan<float> previousMixVolumes,
|
||||||
Memory<VoiceState> state,
|
Memory<VoiceUpdateState> state,
|
||||||
uint bufferOffset,
|
uint bufferOffset,
|
||||||
uint bufferCount,
|
uint bufferCount,
|
||||||
uint bufferIndex,
|
uint bufferIndex,
|
||||||
@@ -311,34 +307,31 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateVoice(ref VoiceInfo voiceInfo)
|
private void GenerateVoice(ref VoiceState voiceState)
|
||||||
{
|
{
|
||||||
int nodeId = voiceInfo.NodeId;
|
int nodeId = voiceState.NodeId;
|
||||||
uint channelsCount = voiceInfo.ChannelsCount;
|
uint channelsCount = voiceState.ChannelsCount;
|
||||||
|
|
||||||
Span<int> channelResourceIdsSpan = voiceInfo.ChannelResourceIds.AsSpan();
|
|
||||||
Span<BiquadFilterParameter2> biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
|
|
||||||
|
|
||||||
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
|
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
|
||||||
{
|
{
|
||||||
Memory<VoiceState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
|
Memory<VoiceUpdateState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(voiceState.ChannelResourceIds[channelIndex]);
|
||||||
|
|
||||||
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(channelResourceIdsSpan[channelIndex]);
|
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(voiceState.ChannelResourceIds[channelIndex]);
|
||||||
|
|
||||||
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
|
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
|
||||||
|
|
||||||
if (voiceInfo.SampleFormat == SampleFormat.PcmInt16)
|
if (voiceState.SampleFormat == SampleFormat.PcmInt16)
|
||||||
{
|
{
|
||||||
dataSourceDetailType = PerformanceDetailType.PcmInt16;
|
dataSourceDetailType = PerformanceDetailType.PcmInt16;
|
||||||
}
|
}
|
||||||
else if (voiceInfo.SampleFormat == SampleFormat.PcmFloat)
|
else if (voiceState.SampleFormat == SampleFormat.PcmFloat)
|
||||||
{
|
{
|
||||||
dataSourceDetailType = PerformanceDetailType.PcmFloat;
|
dataSourceDetailType = PerformanceDetailType.PcmFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
if (_performanceManager != null && _performanceManager.IsTargetNodeId(nodeId) && _performanceManager.GetNextEntry(out performanceEntry, dataSourceDetailType, PerformanceEntryType.Voice, nodeId))
|
if (_performanceManager != null && _performanceManager.IsTargetNodeId(nodeId) && _performanceManager.GetNextEntry(out performanceEntry, dataSourceDetailType, PerformanceEntryType.Voice, nodeId))
|
||||||
{
|
{
|
||||||
@@ -347,18 +340,18 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateDataSource(ref voiceInfo, dspStateMemory, channelIndex);
|
GenerateDataSource(ref voiceState, dspStateMemory, channelIndex);
|
||||||
|
|
||||||
if (performanceInitialized)
|
if (performanceInitialized)
|
||||||
{
|
{
|
||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voiceInfo.WasPlaying)
|
if (voiceState.WasPlaying)
|
||||||
{
|
{
|
||||||
voiceInfo.PreviousVolume = 0.0f;
|
voiceState.PreviousVolume = 0.0f;
|
||||||
}
|
}
|
||||||
else if (voiceInfo.HasAnyDestination())
|
else if (voiceState.HasAnyDestination())
|
||||||
{
|
{
|
||||||
performanceInitialized = false;
|
performanceInitialized = false;
|
||||||
|
|
||||||
@@ -369,7 +362,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateBiquadFilterForVoice(ref voiceInfo, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
|
GenerateBiquadFilterForVoice(ref voiceState, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
|
||||||
|
|
||||||
if (performanceInitialized)
|
if (performanceInitialized)
|
||||||
{
|
{
|
||||||
@@ -386,8 +379,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
_commandBuffer.GenerateVolumeRamp(
|
_commandBuffer.GenerateVolumeRamp(
|
||||||
voiceInfo.PreviousVolume,
|
voiceState.PreviousVolume,
|
||||||
voiceInfo.Volume,
|
voiceState.Volume,
|
||||||
_rendererContext.MixBufferCount + (uint)channelIndex,
|
_rendererContext.MixBufferCount + (uint)channelIndex,
|
||||||
nodeId);
|
nodeId);
|
||||||
|
|
||||||
@@ -396,17 +389,17 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
voiceInfo.PreviousVolume = voiceInfo.Volume;
|
voiceState.PreviousVolume = voiceState.Volume;
|
||||||
|
|
||||||
if (voiceInfo.MixId == Constants.UnusedMixId)
|
if (voiceState.MixId == Constants.UnusedMixId)
|
||||||
{
|
{
|
||||||
if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
|
if (voiceState.SplitterId != Constants.UnusedSplitterId)
|
||||||
{
|
{
|
||||||
int destinationId = channelIndex;
|
int destinationId = channelIndex;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId);
|
SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId);
|
||||||
|
|
||||||
if (destination.IsNull)
|
if (destination.IsNull)
|
||||||
{
|
{
|
||||||
@@ -421,7 +414,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||||
{
|
{
|
||||||
ref MixInfo mix = ref _mixContext.GetState(mixId);
|
ref MixState mix = ref _mixContext.GetState(mixId);
|
||||||
|
|
||||||
if (destination.IsBiquadFilterEnabled())
|
if (destination.IsBiquadFilterEnabled())
|
||||||
{
|
{
|
||||||
@@ -453,7 +446,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
|
ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
|
||||||
|
|
||||||
performanceInitialized = false;
|
performanceInitialized = false;
|
||||||
|
|
||||||
@@ -481,9 +474,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
channelResource.UpdateState();
|
channelResource.UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < voiceInfo.BiquadFilterNeedInitialization.Length; i++)
|
for (int i = 0; i < voiceState.BiquadFilterNeedInitialization.Length; i++)
|
||||||
{
|
{
|
||||||
voiceInfo.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
|
voiceState.BiquadFilterNeedInitialization[i] = voiceState.BiquadFilters[i].Enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,13 +486,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _voiceContext.GetCount(); i++)
|
for (int i = 0; i < _voiceContext.GetCount(); i++)
|
||||||
{
|
{
|
||||||
ref VoiceInfo sortedInfo = ref _voiceContext.GetSortedState(i);
|
ref VoiceState sortedState = ref _voiceContext.GetSortedState(i);
|
||||||
|
|
||||||
if (!sortedInfo.ShouldSkip() && sortedInfo.UpdateForCommandGeneration(_voiceContext))
|
if (!sortedState.ShouldSkip() && sortedState.UpdateForCommandGeneration(_voiceContext))
|
||||||
{
|
{
|
||||||
int nodeId = sortedInfo.NodeId;
|
int nodeId = sortedState.NodeId;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
@@ -510,7 +503,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateVoice(ref sortedInfo);
|
GenerateVoice(ref sortedState);
|
||||||
|
|
||||||
if (performanceInitialized)
|
if (performanceInitialized)
|
||||||
{
|
{
|
||||||
@@ -533,19 +526,15 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (effect.IsEnabled)
|
if (effect.IsEnabled)
|
||||||
{
|
{
|
||||||
Span<float> volumesSpan = effect.Parameter.Volumes.AsSpan();
|
|
||||||
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
|
|
||||||
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
|
|
||||||
|
|
||||||
for (int i = 0; i < effect.Parameter.MixesCount; i++)
|
for (int i = 0; i < effect.Parameter.MixesCount; i++)
|
||||||
{
|
{
|
||||||
if (volumesSpan[i] != 0.0f)
|
if (effect.Parameter.Volumes[i] != 0.0f)
|
||||||
{
|
{
|
||||||
_commandBuffer.GenerateMix(
|
_commandBuffer.GenerateMix(
|
||||||
(uint)bufferOffset + inputSpan[i],
|
(uint)bufferOffset + effect.Parameter.Input[i],
|
||||||
(uint)bufferOffset + outputSpan[i],
|
(uint)bufferOffset + effect.Parameter.Output[i],
|
||||||
nodeId,
|
nodeId,
|
||||||
volumesSpan[i]);
|
effect.Parameter.Volumes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -565,10 +554,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
uint writeOffset = 0;
|
uint writeOffset = 0;
|
||||||
|
|
||||||
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
|
|
||||||
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
|
|
||||||
|
|
||||||
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
|
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
|
||||||
{
|
{
|
||||||
uint newUpdateCount = writeOffset + _commandBuffer.CommandList.SampleCount;
|
uint newUpdateCount = writeOffset + _commandBuffer.CommandList.SampleCount;
|
||||||
@@ -586,8 +571,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
_commandBuffer.GenerateAuxEffect(
|
_commandBuffer.GenerateAuxEffect(
|
||||||
bufferOffset,
|
bufferOffset,
|
||||||
inputSpan[i],
|
effect.Parameter.Input[i],
|
||||||
outputSpan[i],
|
effect.Parameter.Output[i],
|
||||||
ref effect.State,
|
ref effect.State,
|
||||||
effect.IsEnabled,
|
effect.IsEnabled,
|
||||||
effect.Parameter.BufferStorageSize,
|
effect.Parameter.BufferStorageSize,
|
||||||
@@ -634,16 +619,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect effect, int nodeId)
|
private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect effect, int nodeId)
|
||||||
{
|
{
|
||||||
Debug.Assert(effect.Type == EffectType.BiquadFilter);
|
Debug.Assert(effect.Type == EffectType.BiquadFilter);
|
||||||
|
|
||||||
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
|
|
||||||
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
|
|
||||||
|
|
||||||
if (effect.IsEnabled)
|
if (effect.IsEnabled)
|
||||||
{
|
{
|
||||||
bool needInitialization = effect.Parameter.Status == UsageState.Invalid ||
|
bool needInitialization = effect.Parameter.Status == UsageState.Invalid ||
|
||||||
(effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
|
(effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourContext.IsBiquadFilterEffectStateClearBugFixed());
|
||||||
|
|
||||||
BiquadFilterParameter2 parameter = new()
|
BiquadFilterParameter parameter = new()
|
||||||
{
|
{
|
||||||
Enable = true,
|
Enable = true,
|
||||||
};
|
};
|
||||||
@@ -657,8 +639,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
(int)bufferOffset,
|
(int)bufferOffset,
|
||||||
ref parameter,
|
ref parameter,
|
||||||
effect.State.Slice(i, 1),
|
effect.State.Slice(i, 1),
|
||||||
inputSpan[i],
|
effect.Parameter.Input[i],
|
||||||
outputSpan[i],
|
effect.Parameter.Output[i],
|
||||||
needInitialization,
|
needInitialization,
|
||||||
nodeId);
|
nodeId);
|
||||||
}
|
}
|
||||||
@@ -667,8 +649,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < effect.Parameter.ChannelCount; i++)
|
for (int i = 0; i < effect.Parameter.ChannelCount; i++)
|
||||||
{
|
{
|
||||||
uint inputBufferIndex = bufferOffset + inputSpan[i];
|
uint inputBufferIndex = bufferOffset + effect.Parameter.Input[i];
|
||||||
uint outputBufferIndex = bufferOffset + outputSpan[i];
|
uint outputBufferIndex = bufferOffset + effect.Parameter.Output[i];
|
||||||
|
|
||||||
// If the input and output isn't the same, generate a command.
|
// If the input and output isn't the same, generate a command.
|
||||||
if (inputBufferIndex != outputBufferIndex)
|
if (inputBufferIndex != outputBufferIndex)
|
||||||
@@ -685,7 +667,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
ulong workBuffer = effect.GetWorkBuffer(-1);
|
ulong workBuffer = effect.GetWorkBuffer(-1);
|
||||||
|
|
||||||
if (_rendererContext.BehaviourInfo.IsEffectInfoVersion2Supported())
|
if (_rendererContext.BehaviourContext.IsEffectInfoVersion2Supported())
|
||||||
{
|
{
|
||||||
Memory<EffectResultState> dspResultState;
|
Memory<EffectResultState> dspResultState;
|
||||||
|
|
||||||
@@ -719,8 +701,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
uint writeOffset = 0;
|
uint writeOffset = 0;
|
||||||
|
|
||||||
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
|
|
||||||
|
|
||||||
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
|
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
|
||||||
{
|
{
|
||||||
@@ -739,7 +719,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
_commandBuffer.GenerateCaptureEffect(
|
_commandBuffer.GenerateCaptureEffect(
|
||||||
bufferOffset,
|
bufferOffset,
|
||||||
inputSpan[i],
|
effect.Parameter.Input[i],
|
||||||
effect.State.SendBufferInfo,
|
effect.State.SendBufferInfo,
|
||||||
effect.IsEnabled,
|
effect.IsEnabled,
|
||||||
effect.Parameter.BufferStorageSize,
|
effect.Parameter.BufferStorageSize,
|
||||||
@@ -779,13 +759,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
nodeId);
|
nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateEffect(ref MixInfo mix, int effectId, BaseEffect effect)
|
private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect)
|
||||||
{
|
{
|
||||||
int nodeId = mix.NodeId;
|
int nodeId = mix.NodeId;
|
||||||
|
|
||||||
bool isFinalMix = mix.MixId == Constants.FinalMixId;
|
bool isFinalMix = mix.MixId == Constants.FinalMixId;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
@@ -809,13 +789,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
|
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
|
||||||
break;
|
break;
|
||||||
case EffectType.Delay:
|
case EffectType.Delay:
|
||||||
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.Reverb:
|
case EffectType.Reverb:
|
||||||
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.Reverb3d:
|
case EffectType.Reverb3d:
|
||||||
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.BiquadFilter:
|
case EffectType.BiquadFilter:
|
||||||
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
|
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
|
||||||
@@ -841,7 +821,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
effect.UpdateForCommandGeneration();
|
effect.UpdateForCommandGeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateEffects(ref MixInfo mix)
|
private void GenerateEffects(ref MixState mix)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<int> effectProcessingOrderArray = mix.EffectProcessingOrderArray;
|
ReadOnlySpan<int> effectProcessingOrderArray = mix.EffectProcessingOrderArray;
|
||||||
|
|
||||||
@@ -877,8 +857,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
ref bool isFirstMixBuffer,
|
ref bool isFirstMixBuffer,
|
||||||
int nodeId)
|
int nodeId)
|
||||||
{
|
{
|
||||||
ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
|
ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||||
ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
|
ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||||
|
|
||||||
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
||||||
|
|
||||||
@@ -890,7 +870,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
inputBufferIndex,
|
inputBufferIndex,
|
||||||
outputBufferIndex,
|
outputBufferIndex,
|
||||||
0,
|
0,
|
||||||
Memory<VoiceState>.Empty,
|
Memory<VoiceUpdateState>.Empty,
|
||||||
ref bqf0,
|
ref bqf0,
|
||||||
ref bqf1,
|
ref bqf1,
|
||||||
bqfState[..1],
|
bqfState[..1],
|
||||||
@@ -914,7 +894,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
inputBufferIndex,
|
inputBufferIndex,
|
||||||
outputBufferIndex,
|
outputBufferIndex,
|
||||||
0,
|
0,
|
||||||
Memory<VoiceState>.Empty,
|
Memory<VoiceUpdateState>.Empty,
|
||||||
ref bqf0,
|
ref bqf0,
|
||||||
bqfState[..1],
|
bqfState[..1],
|
||||||
bqfState.Slice(1, 1),
|
bqfState.Slice(1, 1),
|
||||||
@@ -933,7 +913,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
inputBufferIndex,
|
inputBufferIndex,
|
||||||
outputBufferIndex,
|
outputBufferIndex,
|
||||||
0,
|
0,
|
||||||
Memory<VoiceState>.Empty,
|
Memory<VoiceUpdateState>.Empty,
|
||||||
ref bqf1,
|
ref bqf1,
|
||||||
bqfState[..1],
|
bqfState[..1],
|
||||||
bqfState.Slice(1, 1),
|
bqfState.Slice(1, 1),
|
||||||
@@ -948,7 +928,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
isFirstMixBuffer = false;
|
isFirstMixBuffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateMix(ref MixInfo mix)
|
private void GenerateMix(ref MixState mix)
|
||||||
{
|
{
|
||||||
if (mix.HasAnyDestination())
|
if (mix.HasAnyDestination())
|
||||||
{
|
{
|
||||||
@@ -977,7 +957,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||||
{
|
{
|
||||||
ref MixInfo destinationMix = ref _mixContext.GetState(mixId);
|
ref MixState destinationMix = ref _mixContext.GetState(mixId);
|
||||||
|
|
||||||
uint inputBufferIndex = mix.BufferOffset + ((uint)destinationIndex % mix.BufferCount);
|
uint inputBufferIndex = mix.BufferOffset + ((uint)destinationIndex % mix.BufferCount);
|
||||||
|
|
||||||
@@ -1016,7 +996,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ref MixInfo destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
|
ref MixState destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
|
||||||
|
|
||||||
for (uint bufferIndex = 0; bufferIndex < mix.BufferCount; bufferIndex++)
|
for (uint bufferIndex = 0; bufferIndex < mix.BufferCount; bufferIndex++)
|
||||||
{
|
{
|
||||||
@@ -1038,7 +1018,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateSubMix(ref MixInfo subMix)
|
private void GenerateSubMix(ref MixState subMix)
|
||||||
{
|
{
|
||||||
_commandBuffer.GenerateDepopForMixBuffers(
|
_commandBuffer.GenerateDepopForMixBuffers(
|
||||||
_rendererContext.DepopBuffer,
|
_rendererContext.DepopBuffer,
|
||||||
@@ -1049,7 +1029,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
GenerateEffects(ref subMix);
|
GenerateEffects(ref subMix);
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
int nodeId = subMix.NodeId;
|
int nodeId = subMix.NodeId;
|
||||||
|
|
||||||
@@ -1074,13 +1054,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
for (int id = 0; id < _mixContext.GetCount(); id++)
|
for (int id = 0; id < _mixContext.GetCount(); id++)
|
||||||
{
|
{
|
||||||
ref MixInfo sortedInfo = ref _mixContext.GetSortedState(id);
|
ref MixState sortedState = ref _mixContext.GetSortedState(id);
|
||||||
|
|
||||||
if (sortedInfo.IsUsed && sortedInfo.MixId != Constants.FinalMixId)
|
if (sortedState.IsUsed && sortedState.MixId != Constants.FinalMixId)
|
||||||
{
|
{
|
||||||
int nodeId = sortedInfo.NodeId;
|
int nodeId = sortedState.NodeId;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
@@ -1091,7 +1071,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateSubMix(ref sortedInfo);
|
GenerateSubMix(ref sortedState);
|
||||||
|
|
||||||
if (performanceInitialized)
|
if (performanceInitialized)
|
||||||
{
|
{
|
||||||
@@ -1103,7 +1083,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
private void GenerateFinalMix()
|
private void GenerateFinalMix()
|
||||||
{
|
{
|
||||||
ref MixInfo finalMix = ref _mixContext.GetFinalState();
|
ref MixState finalMix = ref _mixContext.GetFinalState();
|
||||||
|
|
||||||
_commandBuffer.GenerateDepopForMixBuffers(
|
_commandBuffer.GenerateDepopForMixBuffers(
|
||||||
_rendererContext.DepopBuffer,
|
_rendererContext.DepopBuffer,
|
||||||
@@ -1114,7 +1094,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
GenerateEffects(ref finalMix);
|
GenerateEffects(ref finalMix);
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
int nodeId = finalMix.NodeId;
|
int nodeId = finalMix.NodeId;
|
||||||
|
|
||||||
@@ -1163,7 +1143,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
int nodeId = _mixContext.GetFinalState().NodeId;
|
int nodeId = _mixContext.GetFinalState().NodeId;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
@@ -1182,16 +1162,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateCircularBuffer(CircularBufferSink sink, ref MixInfo finalMix)
|
private void GenerateCircularBuffer(CircularBufferSink sink, ref MixState finalMix)
|
||||||
{
|
{
|
||||||
_commandBuffer.GenerateCircularBuffer(finalMix.BufferOffset, sink, Constants.InvalidNodeId);
|
_commandBuffer.GenerateCircularBuffer(finalMix.BufferOffset, sink, Constants.InvalidNodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateDevice(DeviceSink sink, ref MixInfo finalMix)
|
private void GenerateDevice(DeviceSink sink, ref MixState finalMix)
|
||||||
{
|
{
|
||||||
if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerInfo == null)
|
if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerState == null)
|
||||||
{
|
{
|
||||||
sink.UpsamplerInfo = _rendererContext.UpsamplerManager.Allocate();
|
sink.UpsamplerState = _rendererContext.UpsamplerManager.Allocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useCustomDownMixingCommand = _rendererContext.ChannelCount == 2 && sink.Parameter.DownMixParameterEnabled;
|
bool useCustomDownMixingCommand = _rendererContext.ChannelCount == 2 && sink.Parameter.DownMixParameterEnabled;
|
||||||
@@ -1218,11 +1198,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
CommandList commandList = _commandBuffer.CommandList;
|
CommandList commandList = _commandBuffer.CommandList;
|
||||||
|
|
||||||
if (sink.UpsamplerInfo != null)
|
if (sink.UpsamplerState != null)
|
||||||
{
|
{
|
||||||
_commandBuffer.GenerateUpsample(
|
_commandBuffer.GenerateUpsample(
|
||||||
finalMix.BufferOffset,
|
finalMix.BufferOffset,
|
||||||
sink.UpsamplerInfo,
|
sink.UpsamplerState,
|
||||||
sink.Parameter.InputCount,
|
sink.Parameter.InputCount,
|
||||||
sink.Parameter.Input.AsSpan(),
|
sink.Parameter.Input.AsSpan(),
|
||||||
commandList.BufferCount,
|
commandList.BufferCount,
|
||||||
@@ -1239,11 +1219,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
Constants.InvalidNodeId);
|
Constants.InvalidNodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateSink(BaseSink sink, ref MixInfo finalMix)
|
private void GenerateSink(BaseSink sink, ref MixState finalMix)
|
||||||
{
|
{
|
||||||
bool performanceInitialized = false;
|
bool performanceInitialized = false;
|
||||||
|
|
||||||
PerformanceEntryAddresses performanceEntry = null;
|
PerformanceEntryAddresses performanceEntry = new();
|
||||||
|
|
||||||
if (_performanceManager != null && _performanceManager.GetNextEntry(out performanceEntry, PerformanceEntryType.Sink, sink.NodeId))
|
if (_performanceManager != null && _performanceManager.GetNextEntry(out performanceEntry, PerformanceEntryType.Sink, sink.NodeId))
|
||||||
{
|
{
|
||||||
@@ -1277,7 +1257,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
public void GenerateSinks()
|
public void GenerateSinks()
|
||||||
{
|
{
|
||||||
ref MixInfo finalMix = ref _mixContext.GetFinalState();
|
ref MixState finalMix = ref _mixContext.GetFinalState();
|
||||||
|
|
||||||
for (int i = 0; i < _sinkContext.GetCount(); i++)
|
for (int i = 0; i < _sinkContext.GetCount(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -194,10 +194,5 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Estimate(FillBufferCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,10 +486,5 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Estimate(FillBufferCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Ryujinx.Audio.Renderer.Dsp.Command;
|
|||||||
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Server
|
namespace Ryujinx.Audio.Renderer.Server
|
||||||
{
|
{
|
||||||
@@ -656,10 +656,5 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual uint Estimate(FillBufferCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,10 +286,5 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return 8683;
|
return 8683;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint Estimate(FillBufferCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Audio.Renderer.Common;
|
using Ryujinx.Audio.Renderer.Common;
|
||||||
using Ryujinx.Audio.Renderer.Dsp;
|
|
||||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using Ryujinx.Audio.Renderer.Parameter;
|
||||||
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
||||||
@@ -18,26 +17,20 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The biquad filter parameter.
|
/// The biquad filter parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BiquadFilterEffectParameter2 Parameter;
|
public BiquadFilterEffectParameter Parameter;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The biquad filter state.
|
/// The biquad filter state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Memory<BiquadFilterState> State { get; }
|
public Memory<BiquadFilterState> State { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The biquad filter effect version.
|
|
||||||
/// </summary>
|
|
||||||
public int BiquadFilterEffectVersion;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="BiquadFilterEffect"/>.
|
/// Create a new <see cref="BiquadFilterEffect"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BiquadFilterEffect(int version)
|
public BiquadFilterEffect()
|
||||||
{
|
{
|
||||||
Parameter = new BiquadFilterEffectParameter2();
|
Parameter = new BiquadFilterEffectParameter();
|
||||||
State = new BiquadFilterState[Constants.ChannelCountMax];
|
State = new BiquadFilterState[Constants.ChannelCountMax];
|
||||||
BiquadFilterEffectVersion = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EffectType TargetEffectType => EffectType.BiquadFilter;
|
public override EffectType TargetEffectType => EffectType.BiquadFilter;
|
||||||
@@ -58,17 +51,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
|
|||||||
|
|
||||||
UpdateParameterBase(in parameter);
|
UpdateParameterBase(in parameter);
|
||||||
|
|
||||||
if (BiquadFilterEffectVersion == 2)
|
Parameter = MemoryMarshal.Cast<byte, BiquadFilterEffectParameter>(parameter.SpecificData)[0];
|
||||||
{
|
|
||||||
Parameter = MemoryMarshal.Cast<byte, BiquadFilterEffectParameter2>(parameter.SpecificData)[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BiquadFilterEffectParameter1 oldParameter =
|
|
||||||
MemoryMarshal.Cast<byte, BiquadFilterEffectParameter1>(parameter.SpecificData)[0];
|
|
||||||
Parameter = BiquadFilterHelper.ToBiquadFilterEffectParameter2(oldParameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
IsEnabled = parameter.IsEnabled;
|
IsEnabled = parameter.IsEnabled;
|
||||||
|
|
||||||
updateErrorInfo = new BehaviourParameter.ErrorInfo();
|
updateErrorInfo = new BehaviourParameter.ErrorInfo();
|
||||||
|
|||||||
@@ -38,6 +38,5 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
uint Estimate(CompressorCommand command);
|
uint Estimate(CompressorCommand command);
|
||||||
uint Estimate(BiquadFilterAndMixCommand command);
|
uint Estimate(BiquadFilterAndMixCommand command);
|
||||||
uint Estimate(MultiTapBiquadFilterAndMixCommand command);
|
uint Estimate(MultiTapBiquadFilterAndMixCommand command);
|
||||||
uint Estimate(FillBufferCommand command);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong Size;
|
public ulong Size;
|
||||||
|
|
||||||
private unsafe MemoryPoolInfo* _memoryPools;
|
private unsafe MemoryPoolState* _memoryPools;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The forced DSP address of the region.
|
/// The forced DSP address of the region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DspAddress ForceMappedDspAddress;
|
public DspAddress ForceMappedDspAddress;
|
||||||
|
|
||||||
private readonly unsafe ref MemoryPoolInfo MemoryPoolInfo => ref *_memoryPools;
|
private readonly unsafe ref MemoryPoolState MemoryPoolState => ref *_memoryPools;
|
||||||
|
|
||||||
public readonly unsafe bool HasMemoryPoolState => (nint)_memoryPools != nint.Zero;
|
public readonly unsafe bool HasMemoryPoolState => (nint)_memoryPools != nint.Zero;
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
return new AddressInfo
|
return new AddressInfo
|
||||||
{
|
{
|
||||||
CpuAddress = cpuAddress,
|
CpuAddress = cpuAddress,
|
||||||
_memoryPools = MemoryPoolInfo.Null,
|
_memoryPools = MemoryPoolState.Null,
|
||||||
Size = size,
|
Size = size,
|
||||||
ForceMappedDspAddress = 0,
|
ForceMappedDspAddress = 0,
|
||||||
};
|
};
|
||||||
@@ -73,19 +73,19 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
_memoryPools = MemoryPoolInfo.Null;
|
_memoryPools = MemoryPoolState.Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the <see cref="MemoryPoolInfo"/> associated.
|
/// Set the <see cref="MemoryPoolState"/> associated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPoolState">The <see cref="MemoryPoolInfo"/> associated.</param>
|
/// <param name="memoryPoolState">The <see cref="MemoryPoolState"/> associated.</param>
|
||||||
public void SetupMemoryPool(Span<MemoryPoolInfo> memoryPoolState)
|
public void SetupMemoryPool(Span<MemoryPoolState> memoryPoolState)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (MemoryPoolInfo* ptr = &MemoryMarshal.GetReference(memoryPoolState))
|
fixed (MemoryPoolState* ptr = &MemoryMarshal.GetReference(memoryPoolState))
|
||||||
{
|
{
|
||||||
SetupMemoryPool(ptr);
|
SetupMemoryPool(ptr);
|
||||||
}
|
}
|
||||||
@@ -93,27 +93,27 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the <see cref="MemoryPoolInfo"/> associated.
|
/// Set the <see cref="MemoryPoolState"/> associated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPoolState">The <see cref="MemoryPoolInfo"/> associated.</param>
|
/// <param name="memoryPoolState">The <see cref="MemoryPoolState"/> associated.</param>
|
||||||
public unsafe void SetupMemoryPool(MemoryPoolInfo* memoryPoolState)
|
public unsafe void SetupMemoryPool(MemoryPoolState* memoryPoolState)
|
||||||
{
|
{
|
||||||
_memoryPools = memoryPoolState;
|
_memoryPools = memoryPoolState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the <see cref="MemoryPoolInfo"/> is mapped.
|
/// Check if the <see cref="MemoryPoolState"/> is mapped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns true if the <see cref="MemoryPoolInfo"/> is mapped.</returns>
|
/// <returns>Returns true if the <see cref="MemoryPoolState"/> is mapped.</returns>
|
||||||
public readonly bool HasMappedMemoryPool()
|
public readonly bool HasMappedMemoryPool()
|
||||||
{
|
{
|
||||||
return HasMemoryPoolState && MemoryPoolInfo.IsMapped();
|
return HasMemoryPoolState && MemoryPoolState.IsMapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the DSP address associated to the <see cref="AddressInfo"/>.
|
/// Get the DSP address associated to the <see cref="AddressInfo"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="markUsed">If true, mark the <see cref="MemoryPoolInfo"/> as used.</param>
|
/// <param name="markUsed">If true, mark the <see cref="MemoryPoolState"/> as used.</param>
|
||||||
/// <returns>Returns the DSP address associated to the <see cref="AddressInfo"/>.</returns>
|
/// <returns>Returns the DSP address associated to the <see cref="AddressInfo"/>.</returns>
|
||||||
public readonly DspAddress GetReference(bool markUsed)
|
public readonly DspAddress GetReference(bool markUsed)
|
||||||
{
|
{
|
||||||
@@ -124,10 +124,10 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
|
|
||||||
if (markUsed)
|
if (markUsed)
|
||||||
{
|
{
|
||||||
MemoryPoolInfo.IsUsed = true;
|
MemoryPoolState.IsUsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemoryPoolInfo.Translate(CpuAddress, Size);
|
return MemoryPoolState.Translate(CpuAddress, Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,62 +8,62 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
/// Server state for a memory pool.
|
/// Server state for a memory pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)]
|
[StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)]
|
||||||
public struct MemoryPoolInfo
|
public struct MemoryPoolState
|
||||||
{
|
{
|
||||||
public const int Alignment = 0x10;
|
public const int Alignment = 0x10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location of the <see cref="MemoryPoolInfo"/>.
|
/// The location of the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum LocationType : uint
|
public enum LocationType : uint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="MemoryPoolInfo"/> located on the CPU side for user use.
|
/// <see cref="MemoryPoolState"/> located on the CPU side for user use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Cpu,
|
Cpu,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="MemoryPoolInfo"/> located on the DSP side for system use.
|
/// <see cref="MemoryPoolState"/> located on the DSP side for system use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Dsp,
|
Dsp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The CPU address associated to the <see cref="MemoryPoolInfo"/>.
|
/// The CPU address associated to the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CpuAddress CpuAddress;
|
public CpuAddress CpuAddress;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The DSP address associated to the <see cref="MemoryPoolInfo"/>.
|
/// The DSP address associated to the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DspAddress DspAddress;
|
public DspAddress DspAddress;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The size associated to the <see cref="MemoryPoolInfo"/>.
|
/// The size associated to the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong Size;
|
public ulong Size;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="LocationType"/> associated to the <see cref="MemoryPoolInfo"/>.
|
/// The <see cref="LocationType"/> associated to the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LocationType Location;
|
public LocationType Location;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true if the <see cref="MemoryPoolInfo"/> is used.
|
/// Set to true if the <see cref="MemoryPoolState"/> is used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
public bool IsUsed;
|
public bool IsUsed;
|
||||||
|
|
||||||
public static unsafe MemoryPoolInfo* Null => (MemoryPoolInfo*)nint.Zero.ToPointer();
|
public static unsafe MemoryPoolState* Null => (MemoryPoolState*)nint.Zero.ToPointer();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="MemoryPoolInfo"/> with the given <see cref="LocationType"/>.
|
/// Create a new <see cref="MemoryPoolState"/> with the given <see cref="LocationType"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="location">The location type to use.</param>
|
/// <param name="location">The location type to use.</param>
|
||||||
/// <returns>A new <see cref="MemoryPoolInfo"/> with the given <see cref="LocationType"/>.</returns>
|
/// <returns>A new <see cref="MemoryPoolState"/> with the given <see cref="LocationType"/>.</returns>
|
||||||
public static MemoryPoolInfo Create(LocationType location)
|
public static MemoryPoolState Create(LocationType location)
|
||||||
{
|
{
|
||||||
return new MemoryPoolInfo
|
return new MemoryPoolState
|
||||||
{
|
{
|
||||||
CpuAddress = 0,
|
CpuAddress = 0,
|
||||||
DspAddress = 0,
|
DspAddress = 0,
|
||||||
@@ -73,7 +73,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the <see cref="CpuAddress"/> and size of the <see cref="MemoryPoolInfo"/>.
|
/// Set the <see cref="CpuAddress"/> and size of the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cpuAddress">The <see cref="CpuAddress"/>.</param>
|
/// <param name="cpuAddress">The <see cref="CpuAddress"/>.</param>
|
||||||
/// <param name="size">The size.</param>
|
/// <param name="size">The size.</param>
|
||||||
@@ -84,11 +84,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the given <see cref="CpuAddress"/> and size is contains in the <see cref="MemoryPoolInfo"/>.
|
/// Check if the given <see cref="CpuAddress"/> and size is contains in the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="targetCpuAddress">The <see cref="CpuAddress"/>.</param>
|
/// <param name="targetCpuAddress">The <see cref="CpuAddress"/>.</param>
|
||||||
/// <param name="size">The size.</param>
|
/// <param name="size">The size.</param>
|
||||||
/// <returns>True if the <see cref="CpuAddress"/> is contained inside the <see cref="MemoryPoolInfo"/>.</returns>
|
/// <returns>True if the <see cref="CpuAddress"/> is contained inside the <see cref="MemoryPoolState"/>.</returns>
|
||||||
public readonly bool Contains(CpuAddress targetCpuAddress, ulong size)
|
public readonly bool Contains(CpuAddress targetCpuAddress, ulong size)
|
||||||
{
|
{
|
||||||
if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress)
|
if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress)
|
||||||
@@ -118,9 +118,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is the <see cref="MemoryPoolInfo"/> mapped on the DSP?
|
/// Is the <see cref="MemoryPoolState"/> mapped on the DSP?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns true if the <see cref="MemoryPoolInfo"/> is mapped on the DSP.</returns>
|
/// <returns>Returns true if the <see cref="MemoryPoolState"/> is mapped on the DSP.</returns>
|
||||||
public readonly bool IsMapped()
|
public readonly bool IsMapped()
|
||||||
{
|
{
|
||||||
return DspAddress != 0;
|
return DspAddress != 0;
|
||||||
@@ -18,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
const uint CurrentProcessPseudoHandle = 0xFFFF8001;
|
const uint CurrentProcessPseudoHandle = 0xFFFF8001;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The result of <see cref="Update(ref MemoryPoolInfo, ref MemoryPoolInParameter, ref MemoryPoolOutStatus)"/>.
|
/// The result of <see cref="Update(ref MemoryPoolState, ref MemoryPoolInParameter, ref MemoryPoolOutStatus)"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum UpdateResult : uint
|
public enum UpdateResult : uint
|
||||||
{
|
{
|
||||||
@@ -49,9 +49,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
private readonly uint _processHandle;
|
private readonly uint _processHandle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="Memory{MemoryPoolInfo}"/> that will be manipulated.
|
/// The <see cref="Memory{MemoryPoolState}"/> that will be manipulated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Memory<MemoryPoolInfo> _memoryPools;
|
private readonly Memory<MemoryPoolState> _memoryPools;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
|
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
|
||||||
@@ -67,7 +67,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
{
|
{
|
||||||
_processHandle = processHandle;
|
_processHandle = processHandle;
|
||||||
_isForceMapEnabled = isForceMapEnabled;
|
_isForceMapEnabled = isForceMapEnabled;
|
||||||
_memoryPools = Memory<MemoryPoolInfo>.Empty;
|
_memoryPools = Memory<MemoryPoolState>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -76,7 +76,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
/// <param name="processHandle">The handle of the process owning the CPU memory manipulated.</param>
|
/// <param name="processHandle">The handle of the process owning the CPU memory manipulated.</param>
|
||||||
/// <param name="memoryPool">The user memory pools.</param>
|
/// <param name="memoryPool">The user memory pools.</param>
|
||||||
/// <param name="isForceMapEnabled">If set to true, this will try to force map memory pool even if their state are considered invalid.</param>
|
/// <param name="isForceMapEnabled">If set to true, this will try to force map memory pool even if their state are considered invalid.</param>
|
||||||
public PoolMapper(uint processHandle, Memory<MemoryPoolInfo> memoryPool, bool isForceMapEnabled)
|
public PoolMapper(uint processHandle, Memory<MemoryPoolState> memoryPool, bool isForceMapEnabled)
|
||||||
{
|
{
|
||||||
_processHandle = processHandle;
|
_processHandle = processHandle;
|
||||||
_memoryPools = memoryPool;
|
_memoryPools = memoryPool;
|
||||||
@@ -84,15 +84,15 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the <see cref="MemoryPoolInfo"/> for system use.
|
/// Initialize the <see cref="MemoryPoolState"/> for system use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/> for system use.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/> for system use.</param>
|
||||||
/// <param name="cpuAddress">The <see cref="CpuAddress"/> to assign.</param>
|
/// <param name="cpuAddress">The <see cref="CpuAddress"/> to assign.</param>
|
||||||
/// <param name="size">The size to assign.</param>
|
/// <param name="size">The size to assign.</param>
|
||||||
/// <returns>Returns true if mapping on the <see cref="Dsp.AudioProcessor"/> succeeded.</returns>
|
/// <returns>Returns true if mapping on the <see cref="Dsp.AudioProcessor"/> succeeded.</returns>
|
||||||
public bool InitializeSystemPool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
|
public bool InitializeSystemPool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
|
||||||
{
|
{
|
||||||
if (memoryPool.Location != MemoryPoolInfo.LocationType.Dsp)
|
if (memoryPool.Location != MemoryPoolState.LocationType.Dsp)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -101,13 +101,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the <see cref="MemoryPoolInfo"/>.
|
/// Initialize the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/>.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/>.</param>
|
||||||
/// <param name="cpuAddress">The <see cref="CpuAddress"/> to assign.</param>
|
/// <param name="cpuAddress">The <see cref="CpuAddress"/> to assign.</param>
|
||||||
/// <param name="size">The size to assign.</param>
|
/// <param name="size">The size to assign.</param>
|
||||||
/// <returns>Returns true if mapping on the <see cref="Dsp.AudioProcessor"/> succeeded.</returns>
|
/// <returns>Returns true if mapping on the <see cref="Dsp.AudioProcessor"/> succeeded.</returns>
|
||||||
public bool InitializePool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
|
public bool InitializePool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
|
||||||
{
|
{
|
||||||
memoryPool.SetCpuAddress(cpuAddress, size);
|
memoryPool.SetCpuAddress(cpuAddress, size);
|
||||||
|
|
||||||
@@ -115,18 +115,18 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the process handle associated to the <see cref="MemoryPoolInfo"/>.
|
/// Get the process handle associated to the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/>.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/>.</param>
|
||||||
/// <returns>Returns the process handle associated to the <see cref="MemoryPoolInfo"/>.</returns>
|
/// <returns>Returns the process handle associated to the <see cref="MemoryPoolState"/>.</returns>
|
||||||
public uint GetProcessHandle(ref MemoryPoolInfo memoryPool)
|
public uint GetProcessHandle(ref MemoryPoolState memoryPool)
|
||||||
{
|
{
|
||||||
if (memoryPool.Location == MemoryPoolInfo.LocationType.Cpu)
|
if (memoryPool.Location == MemoryPoolState.LocationType.Cpu)
|
||||||
{
|
{
|
||||||
return CurrentProcessPseudoHandle;
|
return CurrentProcessPseudoHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoryPool.Location == MemoryPoolInfo.LocationType.Dsp)
|
if (memoryPool.Location == MemoryPoolState.LocationType.Dsp)
|
||||||
{
|
{
|
||||||
return _processHandle;
|
return _processHandle;
|
||||||
}
|
}
|
||||||
@@ -135,11 +135,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Map the <see cref="MemoryPoolInfo"/> on the <see cref="Dsp.AudioProcessor"/>.
|
/// Map the <see cref="MemoryPoolState"/> on the <see cref="Dsp.AudioProcessor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/> to map.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/> to map.</param>
|
||||||
/// <returns>Returns the DSP address mapped.</returns>
|
/// <returns>Returns the DSP address mapped.</returns>
|
||||||
public DspAddress Map(ref MemoryPoolInfo memoryPool)
|
public DspAddress Map(ref MemoryPoolState memoryPool)
|
||||||
{
|
{
|
||||||
DspAddress result = AudioProcessorMemoryManager.Map(GetProcessHandle(ref memoryPool), memoryPool.CpuAddress, memoryPool.Size);
|
DspAddress result = AudioProcessorMemoryManager.Map(GetProcessHandle(ref memoryPool), memoryPool.CpuAddress, memoryPool.Size);
|
||||||
|
|
||||||
@@ -152,11 +152,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unmap the <see cref="MemoryPoolInfo"/> from the <see cref="Dsp.AudioProcessor"/>.
|
/// Unmap the <see cref="MemoryPoolState"/> from the <see cref="Dsp.AudioProcessor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/> to unmap.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/> to unmap.</param>
|
||||||
/// <returns>Returns true if unmapped.</returns>
|
/// <returns>Returns true if unmapped.</returns>
|
||||||
public bool Unmap(ref MemoryPoolInfo memoryPool)
|
public bool Unmap(ref MemoryPoolState memoryPool)
|
||||||
{
|
{
|
||||||
if (memoryPool.IsUsed)
|
if (memoryPool.IsUsed)
|
||||||
{
|
{
|
||||||
@@ -172,12 +172,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find a <see cref="MemoryPoolInfo"/> associated to the region given.
|
/// Find a <see cref="MemoryPoolState"/> associated to the region given.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cpuAddress">The region <see cref="CpuAddress"/>.</param>
|
/// <param name="cpuAddress">The region <see cref="CpuAddress"/>.</param>
|
||||||
/// <param name="size">The region size.</param>
|
/// <param name="size">The region size.</param>
|
||||||
/// <returns>Returns the <see cref="MemoryPoolInfo"/> found or <see cref="Memory{MemoryPoolInfo}.Empty"/> if not found.</returns>
|
/// <returns>Returns the <see cref="MemoryPoolState"/> found or <see cref="Memory{MemoryPoolState}.Empty"/> if not found.</returns>
|
||||||
private Span<MemoryPoolInfo> FindMemoryPool(CpuAddress cpuAddress, ulong size)
|
private Span<MemoryPoolState> FindMemoryPool(CpuAddress cpuAddress, ulong size)
|
||||||
{
|
{
|
||||||
if (!_memoryPools.IsEmpty && _memoryPools.Length > 0)
|
if (!_memoryPools.IsEmpty && _memoryPools.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Span<MemoryPoolInfo>.Empty;
|
return Span<MemoryPoolState>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -201,7 +201,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
{
|
{
|
||||||
if (_isForceMapEnabled)
|
if (_isForceMapEnabled)
|
||||||
{
|
{
|
||||||
Span<MemoryPoolInfo> memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
|
Span<MemoryPoolState> memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
|
||||||
|
|
||||||
if (!memoryPool.IsEmpty)
|
if (!memoryPool.IsEmpty)
|
||||||
{
|
{
|
||||||
@@ -243,13 +243,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update a <see cref="MemoryPoolInfo"/> using user parameters.
|
/// Update a <see cref="MemoryPoolState"/> using user parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="MemoryPoolInfo"/> to update.</param>
|
/// <param name="memoryPool">The <see cref="MemoryPoolState"/> to update.</param>
|
||||||
/// <param name="inParameter">Input user parameter.</param>
|
/// <param name="inParameter">Input user parameter.</param>
|
||||||
/// <param name="outStatus">Output user parameter.</param>
|
/// <param name="outStatus">Output user parameter.</param>
|
||||||
/// <returns>Returns the <see cref="UpdateResult"/> of the operations performed.</returns>
|
/// <returns>Returns the <see cref="UpdateResult"/> of the operations performed.</returns>
|
||||||
public UpdateResult Update(ref MemoryPoolInfo memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
|
public UpdateResult Update(ref MemoryPoolState memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
|
||||||
{
|
{
|
||||||
MemoryPoolUserState inputState = inParameter.State;
|
MemoryPoolUserState inputState = inParameter.State;
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
|
|
||||||
if (_memoryPools.Length > 0)
|
if (_memoryPools.Length > 0)
|
||||||
{
|
{
|
||||||
Span<MemoryPoolInfo> memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
|
Span<MemoryPoolState> memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
|
||||||
|
|
||||||
if (!memoryPool.IsEmpty)
|
if (!memoryPool.IsEmpty)
|
||||||
{
|
{
|
||||||
@@ -343,7 +343,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
addressInfo.SetupMemoryPool(MemoryPoolInfo.Null);
|
addressInfo.SetupMemoryPool(MemoryPoolState.Null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,12 +351,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove the usage flag from all the <see cref="MemoryPoolInfo"/>.
|
/// Remove the usage flag from all the <see cref="MemoryPoolState"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="memoryPool">The <see cref="Memory{MemoryPoolInfo}"/> to reset.</param>
|
/// <param name="memoryPool">The <see cref="Memory{MemoryPoolState}"/> to reset.</param>
|
||||||
public static void ClearUsageState(Memory<MemoryPoolInfo> memoryPool)
|
public static void ClearUsageState(Memory<MemoryPoolState> memoryPool)
|
||||||
{
|
{
|
||||||
foreach (ref MemoryPoolInfo info in memoryPool.Span)
|
foreach (ref MemoryPoolState info in memoryPool.Span)
|
||||||
{
|
{
|
||||||
info.IsUsed = false;
|
info.IsUsed = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user